muffin v7.4.12
This commit is contained in:
parent
e3e5a401c3
commit
0f9f445830
38 changed files with 13646 additions and 10442 deletions
401
Questionable/Questionable.Windows/FateSelectionWindow.cs
Normal file
401
Questionable/Questionable.Windows/FateSelectionWindow.cs
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using LLib.ImGui;
|
||||
using Questionable.Controller;
|
||||
using Questionable.Data;
|
||||
using Questionable.Model.Questing;
|
||||
using Questionable.Windows.QuestComponents;
|
||||
|
||||
namespace Questionable.Windows;
|
||||
|
||||
internal sealed class FateSelectionWindow : LWindow
|
||||
{
|
||||
private readonly FateController _fateController;
|
||||
|
||||
private readonly FateDefinitionRegistry _fateDefinitionRegistry;
|
||||
|
||||
private readonly QuestController _questController;
|
||||
|
||||
private readonly MovementController _movementController;
|
||||
|
||||
private readonly TerritoryData _territoryData;
|
||||
|
||||
private int _cycleLimit;
|
||||
|
||||
public FateSelectionWindow(FateController fateController, FateDefinitionRegistry fateDefinitionRegistry, QuestController questController, MovementController movementController, TerritoryData territoryData)
|
||||
: base("FATE Farming###QuestionableFateFarming")
|
||||
{
|
||||
_fateController = fateController;
|
||||
_fateDefinitionRegistry = fateDefinitionRegistry;
|
||||
_questController = questController;
|
||||
_movementController = movementController;
|
||||
_territoryData = territoryData;
|
||||
base.Size = new Vector2(600f, 400f);
|
||||
base.SizeCondition = ImGuiCond.FirstUseEver;
|
||||
base.SizeConstraints = new WindowSizeConstraints
|
||||
{
|
||||
MinimumSize = new Vector2(500f, 300f),
|
||||
MaximumSize = new Vector2(900f, 700f)
|
||||
};
|
||||
}
|
||||
|
||||
public override void DrawContent()
|
||||
{
|
||||
if (_fateController.IsRunning)
|
||||
{
|
||||
DrawRunningHeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawControlsStrip();
|
||||
}
|
||||
if (_fateDefinitionRegistry.Definitions.Count == 0)
|
||||
{
|
||||
DrawEmptyState();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawFateTable();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRunningHeader()
|
||||
{
|
||||
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
||||
float x = ImGui.GetContentRegionAvail().X;
|
||||
float num = ImGui.GetTextLineHeightWithSpacing() * 3f + ImGui.GetStyle().ItemSpacing.Y * 3f;
|
||||
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
||||
windowDrawList.AddRectFilledMultiColor(cursorScreenPos, cursorScreenPos + new Vector2(x, num), ImGui.ColorConvertFloat4ToU32(new Vector4(0.22f, 0.2f, 0.28f, 0.85f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.18f, 0.16f, 0.24f, 0.85f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.18f, 0.16f, 0.24f, 0.85f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.22f, 0.2f, 0.28f, 0.85f)));
|
||||
windowDrawList.AddLine(cursorScreenPos + new Vector2(0f, num), cursorScreenPos + new Vector2(x, num), ImGui.ColorConvertFloat4ToU32(new Vector4(0.7f, 0.6f, 0.9f, 0.5f)), 2f);
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetStyle().ItemSpacing.Y);
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 8f);
|
||||
float num2 = (float)ImGui.GetTime();
|
||||
float num3 = 0.85f + MathF.Sin(num2 * 3f) * 0.15f;
|
||||
Vector4 col = new Vector4(1f * num3, 0.85f * num3, 0f, 1f);
|
||||
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||
{
|
||||
ImGui.TextColored(in col, FontAwesomeIcon.Star.ToIconString());
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.ParsedGold, _fateController.CurrentFate.Name);
|
||||
ImGui.SameLine(x - 35f);
|
||||
using (ImRaii.PushColor(ImGuiCol.Button, Vector4.Zero))
|
||||
{
|
||||
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, new Vector4(0.8f, 0.3f, 0.3f, 0.4f)))
|
||||
{
|
||||
using (ImRaii.PushColor(ImGuiCol.ButtonActive, new Vector4(0.9f, 0.2f, 0.2f, 0.6f)))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
|
||||
{
|
||||
_fateController.Stop("UI stop");
|
||||
_movementController.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 8f);
|
||||
string value = (_fateController.CycleLimit.HasValue ? $"Cycle {_fateController.CompletedCycles + 1} / {_fateController.CycleLimit}" : $"Cycle {_fateController.CompletedCycles + 1}");
|
||||
string value2 = FormatElapsed(_fateController.ElapsedTime);
|
||||
IList<string> remainingTaskNames = _fateController.GetRemainingTaskNames();
|
||||
string text = ((remainingTaskNames.Count > 0) ? remainingTaskNames.First() : "");
|
||||
if (text.Length > 0)
|
||||
{
|
||||
Vector4 col2 = ImGuiColors.DalamudGrey3;
|
||||
ImU8String text2 = new ImU8String(10, 3);
|
||||
text2.AppendFormatted(value);
|
||||
text2.AppendLiteral(" · ");
|
||||
text2.AppendFormatted(value2);
|
||||
text2.AppendLiteral(" · ");
|
||||
text2.AppendFormatted(text);
|
||||
ImGui.TextColored(in col2, text2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector4 col2 = ImGuiColors.DalamudGrey3;
|
||||
ImU8String text3 = new ImU8String(5, 2);
|
||||
text3.AppendFormatted(value);
|
||||
text3.AppendLiteral(" · ");
|
||||
text3.AppendFormatted(value2);
|
||||
ImGui.TextColored(in col2, text3);
|
||||
}
|
||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 8f);
|
||||
using (ImRaii.Disabled(disabled: true))
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Cycles:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(100f);
|
||||
ImGui.InputInt("##CycleLimitRunning", ref _cycleLimit, 1, 5);
|
||||
}
|
||||
ImGui.SetCursorPosY(cursorScreenPos.Y + num - ImGui.GetCursorScreenPos().Y + ImGui.GetCursorPosY() + 4f);
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
private void DrawControlsStrip()
|
||||
{
|
||||
using (ImRaii.Disabled(_fateController.IsRunning))
|
||||
{
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Cycles:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(100f);
|
||||
ImGui.InputInt("##CycleLimit", ref _cycleLimit, 1, 5);
|
||||
if (_cycleLimit < 0)
|
||||
{
|
||||
_cycleLimit = 0;
|
||||
}
|
||||
ImGui.SameLine();
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey, (_cycleLimit == 0) ? "(unlimited)" : "");
|
||||
}
|
||||
ImGui.Spacing();
|
||||
}
|
||||
|
||||
private static void DrawEmptyState()
|
||||
{
|
||||
float y = ImGui.GetContentRegionAvail().Y;
|
||||
float x = ImGui.GetContentRegionAvail().X;
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + y * 0.25f);
|
||||
Vector4 col = new Vector4(0.6f, 0.5f, 0.8f, 0.7f);
|
||||
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
string text = FontAwesomeIcon.Search.ToIconString();
|
||||
Vector2 vector = ImGui.CalcTextSize(text);
|
||||
vector *= 2.5f;
|
||||
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
||||
Vector2 vector2 = new Vector2(x * 0.5f, 0f) + cursorScreenPos + new Vector2(0f, vector.Y * 0.5f);
|
||||
for (int num = 3; num > 0; num--)
|
||||
{
|
||||
Vector4 col2 = new Vector4(col.X, col.Y, col.Z, col.W * 0.1f * (float)num);
|
||||
ImGui.SetCursorScreenPos(vector2 - vector * 0.5f - new Vector2(num * 2, num * 2));
|
||||
ImGui.TextColored(in col2, text);
|
||||
}
|
||||
ImGui.SetCursorScreenPos(vector2 - vector * 0.5f);
|
||||
ImGui.TextColored(in col, text);
|
||||
ImGui.PopFont();
|
||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + vector.Y * 0.5f + 20f);
|
||||
string text2 = "No FATE Definitions";
|
||||
Vector2 vector3 = ImGui.CalcTextSize(text2);
|
||||
Vector2 vector4 = new Vector2((x - vector3.X) * 0.5f, 0f) + ImGui.GetCursorScreenPos();
|
||||
windowDrawList.AddText(vector4 + new Vector2(1f, 1f), ImGui.ColorConvertFloat4ToU32(new Vector4(0f, 0f, 0f, 0.5f)), text2);
|
||||
ImGui.SetCursorPosX((x - vector3.X) * 0.5f);
|
||||
ImGui.TextColored(new Vector4(0.95f, 0.95f, 1f, 1f), text2);
|
||||
ImGui.Spacing();
|
||||
ImGui.Spacing();
|
||||
string text3 = "Add FATE definitions to the FatePaths folder to get started.";
|
||||
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(text3).X) * 0.5f);
|
||||
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), text3);
|
||||
}
|
||||
|
||||
private void DrawFateTable()
|
||||
{
|
||||
List<FateDefinition> list = _fateDefinitionRegistry.Definitions.Values.OrderBy(delegate(FateDefinition f)
|
||||
{
|
||||
DateTime? eventExpiry = f.EventExpiry;
|
||||
if (eventExpiry.HasValue)
|
||||
{
|
||||
DateTime valueOrDefault = eventExpiry.GetValueOrDefault();
|
||||
if (EventInfoComponent.NormalizeExpiry(valueOrDefault) - DateTime.UtcNow > TimeSpan.Zero)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}).ThenBy(delegate(FateDefinition f)
|
||||
{
|
||||
DateTime? eventExpiry = f.EventExpiry;
|
||||
if (eventExpiry.HasValue)
|
||||
{
|
||||
DateTime valueOrDefault = eventExpiry.GetValueOrDefault();
|
||||
TimeSpan timeSpan = EventInfoComponent.NormalizeExpiry(valueOrDefault) - DateTime.UtcNow;
|
||||
if (timeSpan > TimeSpan.Zero)
|
||||
{
|
||||
return timeSpan.TotalSeconds;
|
||||
}
|
||||
}
|
||||
return double.MaxValue;
|
||||
}).ThenBy<FateDefinition, string>((FateDefinition f) => f.Name, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
using ImRaii.IEndObject endObject = ImRaii.Table("FateTable", 4, ImGuiTableFlags.SizingStretchProp | ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInnerH | ImGuiTableFlags.ScrollY);
|
||||
if (!endObject)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ImGui.TableSetupColumn("Name", ImGuiTableColumnFlags.None, 3f);
|
||||
ImGui.TableSetupColumn("Zone", ImGuiTableColumnFlags.None, 2f);
|
||||
ImGui.TableSetupColumn("Expiry", ImGuiTableColumnFlags.WidthFixed, 80f);
|
||||
ImGui.TableSetupColumn("##Actions", ImGuiTableColumnFlags.WidthFixed, 30f);
|
||||
ImGui.TableHeadersRow();
|
||||
foreach (FateDefinition item in list)
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
bool flag = _fateController.IsRunning && _fateController.CurrentFate == item;
|
||||
if (flag)
|
||||
{
|
||||
float num = (float)ImGui.GetTime();
|
||||
float w = 0.1f + MathF.Sin(num * 2.5f) * 0.05f;
|
||||
ImGui.TableSetBgColor(ImGuiTableBgTarget.RowBg1, ImGui.GetColorU32(new Vector4(1f, 0.85f, 0f, w)));
|
||||
}
|
||||
ImGui.TableNextColumn();
|
||||
DrawFateRowName(item, flag);
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TextUnformatted(_territoryData.GetName(item.TerritoryId) ?? item.Description);
|
||||
ImGui.TableNextColumn();
|
||||
DrawFateRowExpiry(item);
|
||||
ImGui.TableNextColumn();
|
||||
bool disabled = _fateController.IsRunning || _questController.AutomationType != QuestController.EAutomationType.Manual;
|
||||
DrawFateRowActions(item, disabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFateRowName(FateDefinition fate, bool isActive)
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
float num = (float)ImGui.GetTime();
|
||||
float num2 = 0.85f + MathF.Sin(num * 3f) * 0.15f;
|
||||
ImGui.TextColored(new Vector4(1f * num2, 0.85f * num2, 0f, 1f), fate.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextUnformatted(fate.Name);
|
||||
}
|
||||
if (!ImGui.IsItemHovered())
|
||||
{
|
||||
return;
|
||||
}
|
||||
using (ImRaii.Tooltip())
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudWhite, fate.Name);
|
||||
ImGui.Separator();
|
||||
ImGui.PushTextWrapPos(300f);
|
||||
ImGui.TextUnformatted(fate.Description);
|
||||
ImGui.PopTextWrapPos();
|
||||
ImGui.Spacing();
|
||||
string nameAndId = _territoryData.GetNameAndId(fate.TerritoryId);
|
||||
Vector4 col = ImGuiColors.DalamudGrey;
|
||||
ImU8String text = new ImU8String(6, 1);
|
||||
text.AppendLiteral("Zone: ");
|
||||
text.AppendFormatted(nameAndId);
|
||||
ImGui.TextColored(in col, text);
|
||||
col = ImGuiColors.DalamudGrey;
|
||||
ImU8String text2 = new ImU8String(9, 1);
|
||||
text2.AppendLiteral("Targets: ");
|
||||
text2.AppendFormatted(fate.Targets.Count);
|
||||
ImGui.TextColored(in col, text2);
|
||||
if (fate.RequiredStatusId.HasValue)
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudYellow, "Requires transformation");
|
||||
}
|
||||
DateTime? eventExpiry = fate.EventExpiry;
|
||||
if (eventExpiry.HasValue)
|
||||
{
|
||||
DateTime valueOrDefault = eventExpiry.GetValueOrDefault();
|
||||
TimeSpan timeSpan = EventInfoComponent.NormalizeExpiry(valueOrDefault) - DateTime.UtcNow;
|
||||
if (timeSpan > TimeSpan.Zero)
|
||||
{
|
||||
string text3 = EventInfoComponent.FormatRemainingFull(timeSpan);
|
||||
ImGui.TextColored(ImGuiColors.DalamudOrange, text3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawFateRowExpiry(FateDefinition fate)
|
||||
{
|
||||
DateTime? eventExpiry = fate.EventExpiry;
|
||||
if (eventExpiry.HasValue)
|
||||
{
|
||||
DateTime valueOrDefault = eventExpiry.GetValueOrDefault();
|
||||
TimeSpan timeSpan = EventInfoComponent.NormalizeExpiry(valueOrDefault) - DateTime.UtcNow;
|
||||
if (timeSpan > TimeSpan.Zero)
|
||||
{
|
||||
string text = EventInfoComponent.FormatRemainingDays(timeSpan);
|
||||
ImGui.TextColored((timeSpan.TotalDays < 3.0) ? ImGuiColors.DalamudOrange : ImGuiColors.DalamudGrey, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, "Expired");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, "--");
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFateRowActions(FateDefinition fate, bool disabled)
|
||||
{
|
||||
using (ImRaii.Disabled(disabled))
|
||||
{
|
||||
ImU8String id = new ImU8String(5, 1);
|
||||
id.AppendLiteral("fate_");
|
||||
id.AppendFormatted(fate.Name);
|
||||
using (ImRaii.PushId(id))
|
||||
{
|
||||
if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
|
||||
{
|
||||
_questController.Stop("FATE farming start");
|
||||
_movementController.Stop();
|
||||
int? cycleLimit = ((_cycleLimit > 0) ? new int?(_cycleLimit) : ((int?)null));
|
||||
_fateController.Start(fate, cycleLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disabled && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
|
||||
{
|
||||
if (_fateController.IsRunning)
|
||||
{
|
||||
ImGui.SetTooltip("Already farming a FATE");
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.SetTooltip("Stop quest automation first");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatElapsed(TimeSpan elapsed)
|
||||
{
|
||||
IFormatProvider invariantCulture;
|
||||
if (elapsed.TotalHours >= 1.0)
|
||||
{
|
||||
invariantCulture = CultureInfo.InvariantCulture;
|
||||
IFormatProvider provider = invariantCulture;
|
||||
DefaultInterpolatedStringHandler handler = new DefaultInterpolatedStringHandler(5, 3, invariantCulture);
|
||||
handler.AppendFormatted((int)elapsed.TotalHours);
|
||||
handler.AppendLiteral("h ");
|
||||
handler.AppendFormatted(elapsed.Minutes, "D2");
|
||||
handler.AppendLiteral("m ");
|
||||
handler.AppendFormatted(elapsed.Seconds, "D2");
|
||||
handler.AppendLiteral("s");
|
||||
return string.Create(provider, ref handler);
|
||||
}
|
||||
if (elapsed.TotalMinutes >= 1.0)
|
||||
{
|
||||
invariantCulture = CultureInfo.InvariantCulture;
|
||||
IFormatProvider provider2 = invariantCulture;
|
||||
DefaultInterpolatedStringHandler handler2 = new DefaultInterpolatedStringHandler(3, 2, invariantCulture);
|
||||
handler2.AppendFormatted((int)elapsed.TotalMinutes);
|
||||
handler2.AppendLiteral("m ");
|
||||
handler2.AppendFormatted(elapsed.Seconds, "D2");
|
||||
handler2.AppendLiteral("s");
|
||||
return string.Create(provider2, ref handler2);
|
||||
}
|
||||
invariantCulture = CultureInfo.InvariantCulture;
|
||||
IFormatProvider provider3 = invariantCulture;
|
||||
DefaultInterpolatedStringHandler handler3 = new DefaultInterpolatedStringHandler(1, 1, invariantCulture);
|
||||
handler3.AppendFormatted(elapsed.Seconds);
|
||||
handler3.AppendLiteral("s");
|
||||
return string.Create(provider3, ref handler3);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,11 +28,14 @@ internal sealed class PriorityWindow : LWindow
|
|||
|
||||
private readonly PresetBuilderComponent _presetBuilderComponent;
|
||||
|
||||
public PriorityWindow(QuestController questController, QuestFunctions questFunctions, QuestSelector questSelector, QuestTooltipComponent questTooltipComponent, PresetBuilderComponent presetBuilderComponent, UiUtils uiUtils, IChatGui chatGui, IDalamudPluginInterface pluginInterface)
|
||||
private readonly SavedPresetsComponent _savedPresetsComponent;
|
||||
|
||||
public PriorityWindow(QuestController questController, QuestFunctions questFunctions, QuestSelector questSelector, QuestTooltipComponent questTooltipComponent, PresetBuilderComponent presetBuilderComponent, SavedPresetsComponent savedPresetsComponent, UiUtils uiUtils, IChatGui chatGui, IDalamudPluginInterface pluginInterface)
|
||||
: base("Quest Priority###QuestionableQuestPriority")
|
||||
{
|
||||
_manualPriorityComponent = new ManualPriorityComponent(questController, questFunctions, questSelector, questTooltipComponent, uiUtils, chatGui, pluginInterface);
|
||||
_presetBuilderComponent = presetBuilderComponent;
|
||||
_savedPresetsComponent = savedPresetsComponent;
|
||||
base.Size = new Vector2(500f, 500f);
|
||||
base.SizeCondition = ImGuiCond.Once;
|
||||
base.SizeConstraints = new WindowSizeConstraints
|
||||
|
|
@ -56,10 +59,17 @@ internal sealed class PriorityWindow : LWindow
|
|||
_manualPriorityComponent.Draw();
|
||||
}
|
||||
}
|
||||
using ImRaii.IEndObject endObject3 = ImRaii.TabItem("Quest Presets");
|
||||
if (endObject3)
|
||||
using (ImRaii.IEndObject endObject3 = ImRaii.TabItem("Quest Presets"))
|
||||
{
|
||||
_presetBuilderComponent.Draw();
|
||||
if (endObject3)
|
||||
{
|
||||
_presetBuilderComponent.Draw();
|
||||
}
|
||||
}
|
||||
using ImRaii.IEndObject endObject4 = ImRaii.TabItem("Saved Presets");
|
||||
if (endObject4)
|
||||
{
|
||||
_savedPresetsComponent.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue