663 lines
20 KiB
C#
663 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Text;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Components;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Services;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using Questionable.Controller;
|
|
using Questionable.Controller.Conditions;
|
|
using Questionable.Data;
|
|
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 const string ClipboardPrefix = "qst:stop:";
|
|
|
|
private static readonly string[] ConditionModeNames = new string[2] { "Pause", "Stop" };
|
|
|
|
private static readonly string[] ConditionTypeNames = new string[7] { "Quest Complete", "Quest Accept", "Level", "Global Sequence", "Inventory Full", "Before Duty", "Gil Threshold" };
|
|
|
|
private readonly IDalamudPluginInterface _pluginInterface;
|
|
|
|
private readonly QuestSelector _questSelector;
|
|
|
|
private readonly QuestRegistry _questRegistry;
|
|
|
|
private readonly QuestData _questData;
|
|
|
|
private readonly QuestFunctions _questFunctions;
|
|
|
|
private readonly QuestTooltipComponent _questTooltipComponent;
|
|
|
|
private readonly UiUtils _uiUtils;
|
|
|
|
private readonly IObjectTable _objectTable;
|
|
|
|
private readonly QuestController _questController;
|
|
|
|
private readonly ILogger<StopConditionComponent> _logger;
|
|
|
|
private int _addConditionType;
|
|
|
|
private int _addLevel = 50;
|
|
|
|
private int _addSequence = 1;
|
|
|
|
private int _addGilThreshold = 1000;
|
|
|
|
private string _questAcceptSearchText = string.Empty;
|
|
|
|
private List<Quest> _acceptedQuests = new List<Quest>();
|
|
|
|
private long _acceptedQuestsRefreshAtMs;
|
|
|
|
private StopCondition? _draggedCondition;
|
|
|
|
public StopConditionComponent(IDalamudPluginInterface pluginInterface, QuestSelector questSelector, QuestFunctions questFunctions, QuestRegistry questRegistry, QuestData questData, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, IObjectTable objectTable, QuestController questController, Configuration configuration, ILogger<StopConditionComponent> logger)
|
|
: base(pluginInterface, configuration)
|
|
{
|
|
StopConditionComponent stopConditionComponent = this;
|
|
_pluginInterface = pluginInterface;
|
|
_questSelector = questSelector;
|
|
_questRegistry = questRegistry;
|
|
_questData = questData;
|
|
_questFunctions = questFunctions;
|
|
_questTooltipComponent = questTooltipComponent;
|
|
_uiUtils = uiUtils;
|
|
_logger = logger;
|
|
_objectTable = objectTable;
|
|
_questController = questController;
|
|
_questSelector.SuggestionPredicate = (Quest quest) => !stopConditionComponent.HasQuestCondition(quest.Id, EStopConditionType.QuestComplete);
|
|
_questSelector.DefaultPredicate = (Quest quest) => quest.Info.IsMainScenarioQuest && questFunctions.IsQuestAccepted(quest.Id);
|
|
_questSelector.QuestSelected = delegate(Quest quest)
|
|
{
|
|
stopConditionComponent.Configuration.Stop.Conditions.Add(new QuestCompleteCondition
|
|
{
|
|
QuestId = quest.Id,
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
stopConditionComponent.Save();
|
|
};
|
|
}
|
|
|
|
public override void DrawTab()
|
|
{
|
|
bool value = base.Configuration.Stop.Enabled;
|
|
UiThemeUtils.SectionHeader("Stop Conditions");
|
|
var (contentStartPos, availableWidth, drawList) = UiThemeUtils.BeginCard();
|
|
if (UiThemeUtils.WrappedCheckbox("Enable stop conditions", ref value, "Pause: Stops automation when condition is met, but allows resuming past it.\nStop: True stop, blocks automation from starting/resuming if condition is already met."))
|
|
{
|
|
base.Configuration.Stop.Enabled = value;
|
|
Save();
|
|
}
|
|
using (ImRaii.Disabled(!value))
|
|
{
|
|
DrawConditionsList();
|
|
}
|
|
UiThemeUtils.EndCard(contentStartPos, availableWidth, drawList);
|
|
UiThemeUtils.SectionSpacing();
|
|
UiThemeUtils.SectionHeader("Add Condition");
|
|
var (contentStartPos2, availableWidth2, drawList2) = UiThemeUtils.BeginCard();
|
|
using (ImRaii.Disabled(!value))
|
|
{
|
|
DrawAddCondition();
|
|
}
|
|
UiThemeUtils.EndCard(contentStartPos2, availableWidth2, drawList2);
|
|
UiThemeUtils.SectionSpacing();
|
|
UiThemeUtils.SectionHeader("After Stopping");
|
|
var (contentStartPos3, availableWidth3, drawList3) = UiThemeUtils.BeginCard();
|
|
using (ImRaii.Disabled(!value))
|
|
{
|
|
string buf = base.Configuration.Stop.CommandAfterStop;
|
|
ImGui.SetNextItemWidth(MathF.Min(260f, ImGui.GetContentRegionAvail().X));
|
|
if (ImGui.InputText("Run command after stop", ref buf, 200))
|
|
{
|
|
base.Configuration.Stop.CommandAfterStop = buf;
|
|
Save();
|
|
}
|
|
ImGui.SameLine();
|
|
UiThemeUtils.InfoIcon("Runs this chat command when a stop condition ends the run - not on a manual stop.");
|
|
}
|
|
UiThemeUtils.EndCard(contentStartPos3, availableWidth3, drawList3);
|
|
DrawSessionConditions();
|
|
}
|
|
|
|
private void DrawConditionsList()
|
|
{
|
|
List<StopCondition> conditions = base.Configuration.Stop.Conditions;
|
|
DrawClipboardButtons(conditions);
|
|
if (conditions.Count == 0)
|
|
{
|
|
ImGui.TextDisabled("No conditions configured.");
|
|
return;
|
|
}
|
|
ImGui.SameLine();
|
|
if (UiThemeUtils.DestructiveButton(FontAwesomeIcon.Trash, "Clear all"))
|
|
{
|
|
conditions.Clear();
|
|
Save();
|
|
}
|
|
int? indexToRemove = null;
|
|
StopCondition stopCondition = null;
|
|
int index = 0;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
List<(Vector2, Vector2)> list = new List<(Vector2, Vector2)>();
|
|
for (int i = 0; i < conditions.Count; i++)
|
|
{
|
|
Vector2 item = ImGui.GetCursorScreenPos() + new Vector2(0f, (0f - ImGui.GetStyle().ItemSpacing.Y) / 2f);
|
|
using (ImRaii.PushId(i))
|
|
{
|
|
StopCondition stopCondition2 = conditions[i];
|
|
if (conditions.Count > 1)
|
|
{
|
|
ImGuiComponents.IconButton("##Move", FontAwesomeIcon.Bars);
|
|
if (_draggedCondition == null && ImGui.IsItemActive() && ImGui.IsMouseDragging(ImGuiMouseButton.Left))
|
|
{
|
|
_draggedCondition = stopCondition2;
|
|
}
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
ImGui.SetTooltip("Drag to reorder");
|
|
}
|
|
ImGui.SameLine();
|
|
}
|
|
DrawConditionRow(stopCondition2, i, ref indexToRemove);
|
|
Vector2 item2 = new Vector2(item.X + x, ImGui.GetCursorScreenPos().Y - ImGui.GetStyle().ItemSpacing.Y + 2f);
|
|
list.Add((item, item2));
|
|
}
|
|
}
|
|
if (!ImGui.IsMouseDragging(ImGuiMouseButton.Left))
|
|
{
|
|
_draggedCondition = null;
|
|
}
|
|
else if (_draggedCondition != null)
|
|
{
|
|
int num = conditions.IndexOf(_draggedCondition);
|
|
if (num >= 0)
|
|
{
|
|
var (pMin, pMax) = list[num];
|
|
ImGui.GetWindowDrawList().AddRect(pMin, pMax, ImGui.ColorConvertFloat4ToU32(UiThemeUtils.CardBorderHighColor), 3f, ImDrawFlags.RoundCornersAll);
|
|
int num2 = list.FindIndex(((Vector2 TopLeft, Vector2 BottomRight) tuple2) => ImGui.IsMouseHoveringRect(tuple2.TopLeft, tuple2.BottomRight, clip: true));
|
|
if (num2 >= 0 && num != num2)
|
|
{
|
|
stopCondition = _draggedCondition;
|
|
index = num2;
|
|
}
|
|
}
|
|
}
|
|
if (indexToRemove.HasValue)
|
|
{
|
|
int valueOrDefault = indexToRemove.GetValueOrDefault();
|
|
conditions.RemoveAt(valueOrDefault);
|
|
_draggedCondition = null;
|
|
Save();
|
|
}
|
|
else if (stopCondition != null)
|
|
{
|
|
conditions.Remove(stopCondition);
|
|
conditions.Insert(index, stopCondition);
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawClipboardButtons(List<StopCondition> conditions)
|
|
{
|
|
using (ImRaii.Disabled(conditions.Count == 0))
|
|
{
|
|
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Copy, "Copy"))
|
|
{
|
|
string s = JsonConvert.SerializeObject(conditions);
|
|
ImGui.SetClipboardText("qst:stop:" + Convert.ToBase64String(Encoding.UTF8.GetBytes(s)));
|
|
}
|
|
}
|
|
ImGui.SameLine();
|
|
string text = ThrottledClipboard.GetText();
|
|
using (ImRaii.Disabled(!text.StartsWith("qst:stop:", StringComparison.InvariantCulture)))
|
|
{
|
|
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Paste, "Paste"))
|
|
{
|
|
ImportConditions(text);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ImportConditions(string clipboardText)
|
|
{
|
|
try
|
|
{
|
|
string s = clipboardText.Substring("qst:stop:".Length);
|
|
List<StopCondition> list = JsonConvert.DeserializeObject<List<StopCondition>>(Encoding.UTF8.GetString(Convert.FromBase64String(s))) ?? new List<StopCondition>();
|
|
list.RemoveAll((StopCondition x) => x?.IsSession ?? true);
|
|
if (list.Count != 0)
|
|
{
|
|
base.Configuration.Stop.Conditions.Clear();
|
|
base.Configuration.Stop.Conditions.AddRange(list);
|
|
Save();
|
|
}
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
_logger.LogDebug(exception, "Failed to import stop conditions from clipboard");
|
|
}
|
|
}
|
|
|
|
private void DrawConditionRow(StopCondition condition, int index, ref int? indexToRemove)
|
|
{
|
|
ImGui.AlignTextToFramePadding();
|
|
if (!(condition is QuestCompleteCondition condition2))
|
|
{
|
|
if (!(condition is QuestAcceptCondition condition3))
|
|
{
|
|
if (!(condition is LevelCondition condition4))
|
|
{
|
|
if (!(condition is GlobalSequenceCondition condition5))
|
|
{
|
|
if (!(condition is InventoryFullCondition))
|
|
{
|
|
if (!(condition is BeforeDutyCondition))
|
|
{
|
|
if (condition is GilThresholdCondition gilThresholdCondition)
|
|
{
|
|
ImU8String text = new ImU8String(10, 1);
|
|
text.AppendLiteral("Gil below ");
|
|
text.AppendFormatted(gilThresholdCondition.MinGil, "N0");
|
|
ImGui.Text(text);
|
|
}
|
|
else
|
|
{
|
|
ImGui.Text(condition.GetDescription());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui.Text("Before Duty");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ImGui.Text("Inventory Full");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawGlobalSequenceRow(condition5);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawLevelRow(condition4);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawQuestAcceptRow(condition3);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DrawQuestCompleteRow(condition2);
|
|
}
|
|
ImGui.SameLine();
|
|
int currentItem = ((condition.Mode != EStopConditionMode.Pause) ? 1 : 0);
|
|
ImGui.SetNextItemWidth(70f);
|
|
if (UiThemeUtils.ThemedCombo("##Mode", ref currentItem, ConditionModeNames, ConditionModeNames.Length))
|
|
{
|
|
condition.Mode = ((currentItem == 0) ? EStopConditionMode.Pause : EStopConditionMode.Stop);
|
|
Save();
|
|
}
|
|
ImGui.SameLine();
|
|
if (UiThemeUtils.IconButton(FontAwesomeIcon.Times, ImGui.GetFrameHeight()))
|
|
{
|
|
indexToRemove = index;
|
|
}
|
|
}
|
|
|
|
private void DrawQuestCompleteRow(QuestCompleteCondition condition)
|
|
{
|
|
string text = ResolveQuestName(condition.QuestId);
|
|
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(condition.QuestId);
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString());
|
|
}
|
|
ImGui.SameLine();
|
|
float x = ImGui.GetStyle().ItemSpacing.X;
|
|
float frameHeight = ImGui.GetFrameHeight();
|
|
float x2;
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
x2 = ImGui.CalcTextSize(FontAwesomeIcon.InfoCircle.ToIconString()).X;
|
|
}
|
|
float reservedRightWidth = x * 6f + frameHeight * 2f + ImGui.CalcTextSize("Seq:").X + x2 + 85f + 70f;
|
|
UiThemeUtils.RowLabel(text, reservedRightWidth);
|
|
if (ImGui.IsItemHovered() && _questRegistry.TryGetQuest(condition.QuestId, out Quest quest))
|
|
{
|
|
_questTooltipComponent.Draw(quest.Info);
|
|
}
|
|
ImGui.SameLine();
|
|
bool value = condition.Sequence.HasValue;
|
|
if (UiThemeUtils.WrappedCheckbox("Seq:", ref value, "Stop at specific sequence (unchecked = stop on completion)"))
|
|
{
|
|
condition.Sequence = (value ? new int?(1) : ((int?)null));
|
|
Save();
|
|
}
|
|
using (ImRaii.Disabled(!value))
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.SetNextItemWidth(85f);
|
|
int data = condition.Sequence ?? 1;
|
|
if (ImGui.InputInt("##Seq", ref data, 1, 1) && value)
|
|
{
|
|
condition.Sequence = Math.Max(0, Math.Min(255, data));
|
|
Save();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawQuestAcceptRow(QuestAcceptCondition condition)
|
|
{
|
|
string text = ResolveQuestName(condition.QuestId);
|
|
(Vector4, FontAwesomeIcon, string) questStyle = _uiUtils.GetQuestStyle(condition.QuestId);
|
|
using (_pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
|
{
|
|
ImGui.TextColored(in questStyle.Item1, questStyle.Item2.ToIconString());
|
|
}
|
|
ImGui.SameLine();
|
|
float num = ImGui.GetStyle().ItemSpacing.X * 2f + 70f + ImGui.GetFrameHeight() + ImGui.CalcTextSize(" (on accept)").X;
|
|
float maxWidth = ImGui.GetContentRegionAvail().X - num;
|
|
ImGui.TextUnformatted(UiThemeUtils.TruncateToWidth(text, maxWidth) + " (on accept)");
|
|
if (ImGui.IsItemHovered() && _questRegistry.TryGetQuest(condition.QuestId, out Quest quest))
|
|
{
|
|
_questTooltipComponent.Draw(quest.Info);
|
|
}
|
|
}
|
|
|
|
private void DrawLevelRow(LevelCondition condition)
|
|
{
|
|
ImGui.Text("Level");
|
|
ImGui.SameLine();
|
|
ImGui.SetNextItemWidth(100f);
|
|
int data = condition.TargetLevel;
|
|
if (ImGui.InputInt("##Level", ref data, 1, 5))
|
|
{
|
|
condition.TargetLevel = Math.Max(1, Math.Min(100, data));
|
|
Save();
|
|
}
|
|
int num = _objectTable.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);
|
|
}
|
|
}
|
|
|
|
private void DrawGlobalSequenceRow(GlobalSequenceCondition condition)
|
|
{
|
|
ImGui.Text("Global Sequence");
|
|
ImGui.SameLine();
|
|
ImGui.SetNextItemWidth(100f);
|
|
int data = condition.TargetSequence;
|
|
if (ImGui.InputInt("##Seq", ref data, 1, 1))
|
|
{
|
|
condition.TargetSequence = Math.Max(0, Math.Min(255, data));
|
|
Save();
|
|
}
|
|
QuestController.QuestProgress currentQuest = _questController.CurrentQuest;
|
|
if (currentQuest != null)
|
|
{
|
|
ImGui.SameLine();
|
|
ImU8String text = new ImU8String(11, 1);
|
|
text.AppendLiteral("(Current: ");
|
|
text.AppendFormatted(currentQuest.Sequence);
|
|
text.AppendLiteral(")");
|
|
ImGui.TextDisabled(text);
|
|
}
|
|
}
|
|
|
|
private void DrawAddCondition()
|
|
{
|
|
ImGui.SetNextItemWidth(MathF.Min(260f, ImGui.GetContentRegionAvail().X));
|
|
UiThemeUtils.ThemedCombo("##AddType", ref _addConditionType, ConditionTypeNames, ConditionTypeNames.Length);
|
|
ImGui.SameLine();
|
|
switch (_addConditionType)
|
|
{
|
|
case 0:
|
|
DrawAddQuestComplete();
|
|
break;
|
|
case 1:
|
|
DrawAddQuestAccept();
|
|
break;
|
|
case 2:
|
|
DrawAddLevel();
|
|
break;
|
|
case 3:
|
|
DrawAddGlobalSequence();
|
|
break;
|
|
case 4:
|
|
DrawAddSimpleCondition<InventoryFullCondition>();
|
|
break;
|
|
case 5:
|
|
DrawAddSimpleCondition<BeforeDutyCondition>();
|
|
break;
|
|
case 6:
|
|
DrawAddGilThreshold();
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void DrawAddQuestComplete()
|
|
{
|
|
ImGui.NewLine();
|
|
_questSelector.DrawSelection(MathF.Min(260f, ImGui.GetContentRegionAvail().X));
|
|
}
|
|
|
|
private void DrawAddQuestAccept()
|
|
{
|
|
ImGui.NewLine();
|
|
long tickCount = Environment.TickCount64;
|
|
if (tickCount >= _acceptedQuestsRefreshAtMs)
|
|
{
|
|
_acceptedQuests = GetCurrentlyAcceptedQuests();
|
|
_acceptedQuestsRefreshAtMs = tickCount + 1000;
|
|
}
|
|
List<Quest> list = _acceptedQuests.Where((Quest x) => !HasQuestCondition(x.Id, EStopConditionType.QuestAccept)).ToList();
|
|
if (list.Count == 0)
|
|
{
|
|
ImGui.TextDisabled((_acceptedQuests.Count == 0) ? "No quests currently accepted" : "All accepted quests already added");
|
|
return;
|
|
}
|
|
string[] items = list.Select((Quest x) => x.Info.Name).ToArray();
|
|
int currentItem = -1;
|
|
if (UiThemeUtils.SearchableCombo("##QuestAcceptSelection", ref currentItem, items, ref _questAcceptSearchText, MathF.Min(260f, ImGui.GetContentRegionAvail().X), "Select quest to add...") && currentItem >= 0)
|
|
{
|
|
base.Configuration.Stop.Conditions.Add(new QuestAcceptCondition
|
|
{
|
|
QuestId = list[currentItem].Id,
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawAddLevel()
|
|
{
|
|
if (base.Configuration.Stop.Conditions.OfType<LevelCondition>().Any())
|
|
{
|
|
ImGui.TextDisabled("Already configured");
|
|
return;
|
|
}
|
|
ImGui.SetNextItemWidth(100f);
|
|
ImGui.InputInt("##AddLevel", ref _addLevel, 1, 5);
|
|
_addLevel = Math.Max(1, Math.Min(100, _addLevel));
|
|
ImGui.SameLine();
|
|
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Plus, "Add"))
|
|
{
|
|
base.Configuration.Stop.Conditions.Add(new LevelCondition
|
|
{
|
|
TargetLevel = _addLevel,
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawAddGlobalSequence()
|
|
{
|
|
if (base.Configuration.Stop.Conditions.OfType<GlobalSequenceCondition>().Any())
|
|
{
|
|
ImGui.TextDisabled("Already configured");
|
|
return;
|
|
}
|
|
ImGui.SetNextItemWidth(100f);
|
|
ImGui.InputInt("##AddSeq", ref _addSequence, 1, 1);
|
|
_addSequence = Math.Max(0, Math.Min(255, _addSequence));
|
|
ImGui.SameLine();
|
|
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Plus, "Add"))
|
|
{
|
|
base.Configuration.Stop.Conditions.Add(new GlobalSequenceCondition
|
|
{
|
|
TargetSequence = _addSequence,
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawAddGilThreshold()
|
|
{
|
|
if (base.Configuration.Stop.Conditions.OfType<GilThresholdCondition>().Any())
|
|
{
|
|
ImGui.TextDisabled("Already configured");
|
|
return;
|
|
}
|
|
ImGui.SetNextItemWidth(100f);
|
|
ImGui.InputInt("##AddGil", ref _addGilThreshold, 100, 1000);
|
|
_addGilThreshold = Math.Max(1, Math.Min(999999999, _addGilThreshold));
|
|
ImGui.SameLine();
|
|
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Plus, "Add"))
|
|
{
|
|
base.Configuration.Stop.Conditions.Add(new GilThresholdCondition
|
|
{
|
|
MinGil = _addGilThreshold,
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawAddSimpleCondition<T>() where T : StopCondition, new()
|
|
{
|
|
if (base.Configuration.Stop.Conditions.OfType<T>().Any())
|
|
{
|
|
ImGui.TextDisabled("Already configured");
|
|
}
|
|
else if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Plus, "Add"))
|
|
{
|
|
base.Configuration.Stop.Conditions.Add(new T
|
|
{
|
|
Mode = EStopConditionMode.Stop
|
|
});
|
|
Save();
|
|
}
|
|
}
|
|
|
|
private void DrawSessionConditions()
|
|
{
|
|
List<StopCondition> sessionConditions = _questController.SessionConditions;
|
|
if (sessionConditions.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
UiThemeUtils.SectionSpacing();
|
|
UiThemeUtils.SectionHeader("This Session");
|
|
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard();
|
|
Vector2 item = tuple.ContentStartPos;
|
|
float item2 = tuple.AvailableWidth;
|
|
ImDrawListPtr item3 = tuple.DrawList;
|
|
for (int i = 0; i < sessionConditions.Count; i++)
|
|
{
|
|
ImU8String id = new ImU8String(7, 1);
|
|
id.AppendLiteral("Session");
|
|
id.AppendFormatted(i);
|
|
using (ImRaii.PushId(id))
|
|
{
|
|
StopCondition stopCondition = sessionConditions[i];
|
|
ImGui.BulletText(stopCondition.GetDescription());
|
|
ImGui.SameLine();
|
|
ImU8String text = new ImU8String(2, 1);
|
|
text.AppendLiteral("[");
|
|
text.AppendFormatted(stopCondition.Mode);
|
|
text.AppendLiteral("]");
|
|
ImGui.TextDisabled(text);
|
|
}
|
|
}
|
|
UiThemeUtils.EndCard(item, item2, item3);
|
|
}
|
|
|
|
private string ResolveQuestName(ElementId questId)
|
|
{
|
|
if (_questData.TryGetQuestInfo(questId, out IQuestInfo questInfo))
|
|
{
|
|
return questInfo.Name;
|
|
}
|
|
return questId.ToString();
|
|
}
|
|
|
|
private bool HasQuestCondition(ElementId questId, EStopConditionType type)
|
|
{
|
|
foreach (StopCondition condition in base.Configuration.Stop.Conditions)
|
|
{
|
|
if (condition.Type == type)
|
|
{
|
|
if (condition is QuestCompleteCondition questCompleteCondition && questCompleteCondition.QuestId.Equals(questId))
|
|
{
|
|
return true;
|
|
}
|
|
if (condition is QuestAcceptCondition questAcceptCondition && questAcceptCondition.QuestId.Equals(questId))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private List<Quest> GetCurrentlyAcceptedQuests()
|
|
{
|
|
List<Quest> list = new List<Quest>();
|
|
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 exception)
|
|
{
|
|
_logger.LogDebug(exception, "Failed to enumerate accepted quests");
|
|
list.Clear();
|
|
}
|
|
return list;
|
|
}
|
|
}
|