forked from aly/qstbak
595 lines
25 KiB
C#
595 lines
25 KiB
C#
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.Services;
|
|
using Lumina.Excel.Sheets;
|
|
using Microsoft.Extensions.Logging;
|
|
using Questionable.Controller;
|
|
using Questionable.Data;
|
|
using Questionable.Functions;
|
|
using Questionable.Model;
|
|
using Questionable.Model.Questing;
|
|
|
|
namespace Questionable.Windows.QuestComponents;
|
|
|
|
internal sealed class QuestSequenceComponent
|
|
{
|
|
private readonly QuestData _questData;
|
|
|
|
private readonly QuestRegistry _questRegistry;
|
|
|
|
private readonly QuestFunctions _questFunctions;
|
|
|
|
private readonly IDataManager _dataManager;
|
|
|
|
private readonly ILogger<QuestSequenceComponent> _logger;
|
|
|
|
private string _questLookupInput = string.Empty;
|
|
|
|
private ElementId? _lookedUpQuestId;
|
|
|
|
private int _hoveredSequenceId = -1;
|
|
|
|
public QuestSequenceComponent(QuestData questData, QuestRegistry questRegistry, QuestFunctions questFunctions, IDataManager dataManager, ILogger<QuestSequenceComponent> logger)
|
|
{
|
|
_questData = questData;
|
|
_questRegistry = questRegistry;
|
|
_questFunctions = questFunctions;
|
|
_dataManager = dataManager;
|
|
_logger = logger;
|
|
}
|
|
|
|
public static void DrawCustomHeader(ref bool isOpen)
|
|
{
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
float num = ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().ItemSpacing.Y * 1.5f;
|
|
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);
|
|
float textLineHeight = ImGui.GetTextLineHeight();
|
|
float num2 = (num - textLineHeight) * 0.5f;
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + num2);
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 10f);
|
|
ImGui.TextColored(new Vector4(0.98f, 0.98f, 1f, 1f), "Quest Sequence Viewer");
|
|
ImGui.SameLine(x - 35f);
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - num2 + ImGui.GetStyle().ItemSpacing.Y);
|
|
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.Times))
|
|
{
|
|
isOpen = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ImGui.SetCursorPosY(cursorScreenPos.Y + num - ImGui.GetCursorScreenPos().Y + ImGui.GetCursorPosY());
|
|
}
|
|
|
|
public static void DrawWindowBorder()
|
|
{
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
Vector2 windowPos = ImGui.GetWindowPos();
|
|
Vector2 windowSize = ImGui.GetWindowSize();
|
|
windowDrawList.AddRect(windowPos - new Vector2(1f, 1f), windowPos + windowSize + new Vector2(1f, 1f), ImGui.ColorConvertFloat4ToU32(new Vector4(0.7f, 0.6f, 0.9f, 0.15f)), 5f, ImDrawFlags.None, 3f);
|
|
windowDrawList.AddRect(windowPos, windowPos + windowSize, ImGui.ColorConvertFloat4ToU32(new Vector4(0.7f, 0.6f, 0.9f, 0.4f)), 4f, ImDrawFlags.None, 1.5f);
|
|
}
|
|
|
|
public void DrawCurrentQuestTab()
|
|
{
|
|
QuestReference currentQuest = _questFunctions.GetCurrentQuest();
|
|
(ElementId, byte) tuple = (currentQuest.CurrentQuest, currentQuest.Sequence);
|
|
if (tuple.Item1 != null)
|
|
{
|
|
DrawQuestSequences(tuple.Item1, tuple.Item2);
|
|
}
|
|
else
|
|
{
|
|
DrawEmptyState(FontAwesomeIcon.QuestionCircle, "No Active Quest", "Accept a quest to view its sequence information.", new Vector4(0.6f, 0.5f, 0.8f, 0.7f));
|
|
}
|
|
}
|
|
|
|
public void DrawQuestLookupTab()
|
|
{
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float y = ImGui.GetFrameHeightWithSpacing() + ImGui.GetStyle().ItemSpacing.Y * 3f;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.AddRectFilledMultiColor(cursorScreenPos, cursorScreenPos + new Vector2(x, y), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.6f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.6f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.6f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.6f)));
|
|
windowDrawList.AddRect(cursorScreenPos, cursorScreenPos + new Vector2(x, y), ImGui.ColorConvertFloat4ToU32(new Vector4(0.6f, 0.5f, 0.8f, 0.2f)), 4f, ImDrawFlags.None, 1f);
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetStyle().ItemSpacing.Y * 1.5f);
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 10f);
|
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
|
{
|
|
ImGui.TextColored(new Vector4(0.7f, 0.6f, 0.9f, 1f), FontAwesomeIcon.Search.ToIconString());
|
|
}
|
|
ImGui.SameLine();
|
|
float x2 = ImGui.GetStyle().ItemSpacing.X;
|
|
float num = 10f;
|
|
float num2 = 10f;
|
|
float num3 = ImGui.CalcTextSize("Search").X + ImGui.CalcTextSize(FontAwesomeIcon.Search.ToIconString()).X + ImGui.GetStyle().FramePadding.X * 4f + x2;
|
|
ImGui.SetNextItemWidth(x - num3 - x2 * 3f - num - num2);
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.08f, 0.06f, 0.12f, 0.8f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBgHovered, new Vector4(0.12f, 0.1f, 0.18f, 0.9f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBgActive, new Vector4(0.15f, 0.13f, 0.22f, 1f)))
|
|
{
|
|
bool flag = ImGui.InputTextWithHint("##QuestLookup", "Enter quest ID...", ref _questLookupInput, 10, ImGuiInputTextFlags.EnterReturnsTrue);
|
|
ImGui.SameLine();
|
|
using (ImRaii.PushColor(ImGuiCol.Button, new Vector4(0.25f, 0.22f, 0.32f, 0.8f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, new Vector4(0.35f, 0.3f, 0.45f, 0.9f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.ButtonActive, new Vector4(0.4f, 0.35f, 0.5f, 1f)))
|
|
{
|
|
bool flag2 = ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Search, "Search");
|
|
if (flag || flag2)
|
|
{
|
|
if (ushort.TryParse(_questLookupInput, out var result))
|
|
{
|
|
_lookedUpQuestId = new QuestId(result);
|
|
}
|
|
else
|
|
{
|
|
_lookedUpQuestId = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + ImGui.GetStyle().ItemSpacing.Y * 1.5f);
|
|
ImGui.Spacing();
|
|
ImGui.Spacing();
|
|
if (_lookedUpQuestId != null)
|
|
{
|
|
DrawQuestSequences(_lookedUpQuestId, null);
|
|
}
|
|
else
|
|
{
|
|
DrawEmptyState(FontAwesomeIcon.Search, "Enter a Quest ID", "Use the search box above to look up any quest by its ID.", new Vector4(0.6f, 0.5f, 0.8f, 0.7f));
|
|
}
|
|
}
|
|
|
|
private static void DrawEmptyState(FontAwesomeIcon icon, string title, string message, Vector4 iconColor)
|
|
{
|
|
float y = ImGui.GetContentRegionAvail().Y;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + y * 0.25f);
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
string text = icon.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 col = new Vector4(iconColor.X, iconColor.Y, iconColor.Z, iconColor.W * 0.1f * (float)num);
|
|
ImGui.SetCursorScreenPos(vector2 - vector * 0.5f - new Vector2(num * 2, num * 2));
|
|
ImGui.TextColored(in col, text);
|
|
}
|
|
ImGui.SetCursorScreenPos(vector2 - vector * 0.5f);
|
|
ImGui.TextColored(in iconColor, text);
|
|
ImGui.PopFont();
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + vector.Y * 0.5f + 20f);
|
|
Vector2 vector3 = ImGui.CalcTextSize(title);
|
|
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)), title);
|
|
ImGui.SetCursorPosX((x - vector3.X) * 0.5f);
|
|
ImGui.TextColored(new Vector4(0.95f, 0.95f, 1f, 1f), title);
|
|
ImGui.Spacing();
|
|
ImGui.Spacing();
|
|
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(message).X) * 0.5f);
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), message);
|
|
}
|
|
|
|
private void DrawQuestSequences(ElementId questElementId, byte? currentSequence)
|
|
{
|
|
if (!(questElementId is QuestId questId))
|
|
{
|
|
DrawErrorState("Invalid Quest ID Type", "This viewer only supports regular quest IDs.");
|
|
return;
|
|
}
|
|
if (!_questData.TryGetQuestInfo(questElementId, out IQuestInfo questInfo))
|
|
{
|
|
DrawErrorState($"Quest {questId.Value} Not Found", "This quest ID does not exist in the game data.");
|
|
return;
|
|
}
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float num = ImGui.GetFrameHeightWithSpacing() * 1.8f;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.AddRectFilledMultiColor(cursorScreenPos, cursorScreenPos + new Vector2(x, num), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.7f)));
|
|
windowDrawList.AddRect(cursorScreenPos, cursorScreenPos + new Vector2(x, num), ImGui.ColorConvertFloat4ToU32(new Vector4(0.6f, 0.5f, 0.8f, 0.25f)), 4f, ImDrawFlags.None, 1f);
|
|
float textLineHeight = ImGui.GetTextLineHeight();
|
|
float num2 = (num - textLineHeight) * 0.5f;
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + num2);
|
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + 10f);
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
ImGui.TextColored(new Vector4(0.7f, 0.6f, 0.9f, 1f), FontAwesomeIcon.Book.ToIconString());
|
|
ImGui.PopFont();
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.98f, 0.98f, 1f, 1f), questInfo.Name);
|
|
ImGui.SameLine();
|
|
Vector4 col = new Vector4(0.7f, 0.7f, 0.8f, 1f);
|
|
ImU8String text = new ImU8String(6, 1);
|
|
text.AppendLiteral("(ID: ");
|
|
text.AppendFormatted(questId.Value);
|
|
text.AppendLiteral(")");
|
|
ImGui.TextColored(in col, text);
|
|
if (currentSequence.HasValue)
|
|
{
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.5f, 0.5f, 0.6f, 1f), "—");
|
|
ImGui.SameLine();
|
|
float num3 = (float)ImGui.GetTime();
|
|
float num4 = 0.85f + MathF.Sin(num3 * 3f) * 0.15f;
|
|
col = new Vector4(0.5f * num4, 1f * num4, 0.6f * num4, 1f);
|
|
text = new ImU8String(17, 1);
|
|
text.AppendLiteral("Active: Sequence ");
|
|
text.AppendFormatted(currentSequence.Value);
|
|
ImGui.TextColored(in col, text);
|
|
}
|
|
ImGui.SetCursorPosY(cursorScreenPos.Y + num - ImGui.GetCursorScreenPos().Y + ImGui.GetCursorPosY());
|
|
ImGui.Spacing();
|
|
try
|
|
{
|
|
Lumina.Excel.Sheets.Quest? quest = _dataManager.GetExcelSheet<Lumina.Excel.Sheets.Quest>()?.GetRowOrDefault((uint)(questId.Value + 65536));
|
|
if (!quest.HasValue)
|
|
{
|
|
DrawErrorState("Quest Not Found in Game Data", "Unable to load quest information from Lumina.");
|
|
return;
|
|
}
|
|
List<int> list = (from result in quest.Value.TodoParams.Where((Lumina.Excel.Sheets.Quest.TodoParamsStruct todoParamsStruct) => todoParamsStruct.ToDoCompleteSeq > 0 && todoParamsStruct.ToDoCompleteSeq < byte.MaxValue).Select((Func<Lumina.Excel.Sheets.Quest.TodoParamsStruct, int>)((Lumina.Excel.Sheets.Quest.TodoParamsStruct todoParamsStruct) => todoParamsStruct.ToDoCompleteSeq)).Distinct()
|
|
orderby result
|
|
select result).ToList();
|
|
if (list.Count == 0)
|
|
{
|
|
DrawErrorState("No Sequence Data Available", "This quest may not have traditional sequences.");
|
|
return;
|
|
}
|
|
int num5 = list.Max();
|
|
int num6 = num5 + 1;
|
|
Questionable.Model.Quest quest2;
|
|
bool flag = _questRegistry.TryGetQuest(questElementId, out quest2);
|
|
HashSet<int> hashSet = new HashSet<int>();
|
|
Dictionary<int, (int, string)> dictionary = new Dictionary<int, (int, string)>();
|
|
bool flag2 = false;
|
|
if (flag && quest2 != null && quest2.Root.QuestSequence.Count > 0)
|
|
{
|
|
foreach (QuestSequence item in quest2.Root.QuestSequence)
|
|
{
|
|
if (item.Sequence == byte.MaxValue)
|
|
{
|
|
flag2 = true;
|
|
dictionary[255] = (item.Steps.Count, item.Comment);
|
|
}
|
|
else
|
|
{
|
|
hashSet.Add(item.Sequence);
|
|
dictionary[item.Sequence] = (item.Steps.Count, item.Comment);
|
|
}
|
|
}
|
|
}
|
|
int num7 = hashSet.Count + (flag2 ? 1 : 0);
|
|
int num8 = num6 + 1;
|
|
float num9 = (flag ? ((float)num7 / (float)num8 * 100f) : 0f);
|
|
Vector4 coverageColor = ((num9 >= 100f) ? new Vector4(0.5f, 1f, 0.6f, 1f) : ((num9 >= 50f) ? new Vector4(1f, 0.9f, 0.5f, 1f) : ((num9 < 1f) ? new Vector4(0.6f, 0.5f, 0.8f, 0.7f) : new Vector4(1f, 0.5f, 0.5f, 1f))));
|
|
DrawSummaryCards(num6, num5, flag, num9, coverageColor, num7, num8);
|
|
ImGui.Spacing();
|
|
ImGui.Spacing();
|
|
DrawSequenceGrid(num5, currentSequence, hashSet, dictionary, flag2);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
DrawErrorState("Error Loading Quest Data", ex.Message + "\nCheck logs for details.");
|
|
_logger.LogWarning(ex, "Failed to read quest sequence data from Lumina for {QuestId}", questId);
|
|
}
|
|
}
|
|
|
|
private static void DrawErrorState(string title, string message)
|
|
{
|
|
float y = ImGui.GetContentRegionAvail().Y;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() + y * 0.25f);
|
|
float num = (float)ImGui.GetTime();
|
|
float num2 = 0.7f + MathF.Sin(num * 2f) * 0.3f;
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
string text = FontAwesomeIcon.ExclamationTriangle.ToIconString();
|
|
Vector2 vector = ImGui.CalcTextSize(text);
|
|
ImGui.SetCursorPosX((x - (vector * 2f).X) * 0.5f);
|
|
ImGui.TextColored(new Vector4(1f * num2, 0.4f * num2, 0.4f * num2, 1f), text);
|
|
ImGui.PopFont();
|
|
ImGui.Spacing();
|
|
ImGui.Spacing();
|
|
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(title).X) * 0.5f);
|
|
ImGui.TextColored(new Vector4(1f, 0.5f, 0.5f, 1f), title);
|
|
ImGui.Spacing();
|
|
ImGui.SetCursorPosX((x - ImGui.CalcTextSize(message).X) * 0.5f);
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), message);
|
|
}
|
|
|
|
private static void DrawSummaryCards(int totalSequences, int maxSeq, bool hasQuestPath, float coverage, Vector4 coverageColor, int implementedCount, int expectedCount)
|
|
{
|
|
using ImRaii.IEndObject endObject = ImRaii.Table("SummaryCards", 2, ImGuiTableFlags.None);
|
|
if (!endObject)
|
|
{
|
|
return;
|
|
}
|
|
ImGui.TableSetupColumn("GameData", ImGuiTableColumnFlags.WidthStretch, 0.4f);
|
|
ImGui.TableSetupColumn("QuestPath", ImGuiTableColumnFlags.WidthStretch, 0.6f);
|
|
ImGui.TableNextRow();
|
|
ImGui.TableNextColumn();
|
|
DrawCard(80f, new Vector4(0.6f, 0.85f, 1f, 1f), FontAwesomeIcon.Gamepad, "Expected Sequences", delegate
|
|
{
|
|
ImGui.Spacing();
|
|
ImGui.Indent(10f);
|
|
Vector4 col = new Vector4(0.9f, 0.9f, 0.98f, 1f);
|
|
ImU8String text = new ImU8String(6, 0);
|
|
text.AppendLiteral("Count:");
|
|
ImGui.TextColored(in col, text);
|
|
ImGui.SameLine();
|
|
col = new Vector4(0.7f, 0.9f, 1f, 1f);
|
|
text = new ImU8String(0, 1);
|
|
text.AppendFormatted(totalSequences);
|
|
ImGui.TextColored(in col, text);
|
|
ImGui.Spacing();
|
|
col = new Vector4(0.9f, 0.9f, 0.98f, 1f);
|
|
text = new ImU8String(6, 0);
|
|
text.AppendLiteral("Range:");
|
|
ImGui.TextColored(in col, text);
|
|
ImGui.SameLine();
|
|
col = new Vector4(0.7f, 0.9f, 1f, 1f);
|
|
text = new ImU8String(9, 1);
|
|
text.AppendLiteral("0 → ");
|
|
text.AppendFormatted(maxSeq);
|
|
text.AppendLiteral(", 255");
|
|
ImGui.TextColored(in col, text);
|
|
ImGui.Unindent(10f);
|
|
});
|
|
ImGui.TableNextColumn();
|
|
DrawCard(80f, new Vector4(0.5f, 1f, 0.6f, 1f), FontAwesomeIcon.Code, "Implementation Status", delegate
|
|
{
|
|
if (hasQuestPath)
|
|
{
|
|
ImGui.Indent(10f);
|
|
ImGui.TextColored(new Vector4(0.9f, 0.9f, 0.98f, 1f), "Progress:");
|
|
ImGui.SameLine();
|
|
ref Vector4 col = ref coverageColor;
|
|
ImU8String text = new ImU8String(0, 1);
|
|
text.AppendFormatted(implementedCount);
|
|
ImGui.TextColored(in col, text);
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), "/");
|
|
ImGui.SameLine();
|
|
Vector4 col2 = new Vector4(0.9f, 0.9f, 0.98f, 1f);
|
|
text = new ImU8String(0, 1);
|
|
text.AppendFormatted(expectedCount);
|
|
ImGui.TextColored(in col2, text);
|
|
ImGui.SameLine();
|
|
ref Vector4 col3 = ref coverageColor;
|
|
text = new ImU8String(3, 1);
|
|
text.AppendLiteral("(");
|
|
text.AppendFormatted(coverage, "F0");
|
|
text.AppendLiteral("%)");
|
|
ImGui.TextColored(in col3, text);
|
|
ImGui.Spacing();
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float x = ImGui.GetContentRegionAvail().X - 10f;
|
|
using (ImRaii.PushColor(ImGuiCol.PlotHistogram, coverageColor))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.FrameBg, new Vector4(0.08f, 0.06f, 0.12f, 0.8f)))
|
|
{
|
|
ImGui.ProgressBar(coverage / 100f, new Vector2(x, 16f), "");
|
|
}
|
|
}
|
|
ImGui.GetWindowDrawList().AddRect(cursorScreenPos, cursorScreenPos + new Vector2(x, 16f), ImGui.ColorConvertFloat4ToU32(new Vector4(0.6f, 0.5f, 0.8f, 0.3f)), 2f);
|
|
ImGui.Unindent(10f);
|
|
}
|
|
else
|
|
{
|
|
ImGui.Spacing();
|
|
ImGui.Indent(10f);
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
ImGui.TextColored(new Vector4(0.6f, 0.5f, 0.8f, 0.8f), FontAwesomeIcon.Ban.ToIconString());
|
|
ImGui.PopFont();
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.6f, 0.5f, 0.8f, 0.8f), "Not Implemented");
|
|
ImGui.Spacing();
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), "No quest path data available");
|
|
ImGui.Unindent(10f);
|
|
}
|
|
});
|
|
}
|
|
|
|
private static void DrawCard(float height, Vector4 accentColor, FontAwesomeIcon icon, string title, System.Action content)
|
|
{
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.AddRectFilledMultiColor(cursorScreenPos, cursorScreenPos + new Vector2(x, height), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.1f, 0.08f, 0.14f, 0.7f)), ImGui.ColorConvertFloat4ToU32(new Vector4(0.12f, 0.1f, 0.16f, 0.7f)));
|
|
windowDrawList.AddRect(cursorScreenPos, cursorScreenPos + new Vector2(x, height), ImGui.ColorConvertFloat4ToU32(new Vector4(0.6f, 0.5f, 0.8f, 0.2f)), 4f, ImDrawFlags.None, 1f);
|
|
windowDrawList.AddLine(cursorScreenPos, cursorScreenPos + new Vector2(x, 0f), ImGui.ColorConvertFloat4ToU32(accentColor), 3f);
|
|
float num = cursorScreenPos.Y + 10f;
|
|
ImGui.SetCursorScreenPos(new Vector2(cursorScreenPos.X + 10f, num));
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
ImGui.TextColored(in accentColor, icon.ToIconString());
|
|
ImGui.PopFont();
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.98f, 0.98f, 1f, 1f), title);
|
|
ImGui.SetCursorScreenPos(new Vector2(cursorScreenPos.X + 10f, num + 24f));
|
|
content();
|
|
ImGui.SetCursorScreenPos(new Vector2(cursorScreenPos.X, cursorScreenPos.Y + height + 4f));
|
|
}
|
|
|
|
private void DrawSequenceGrid(int maxSeq, byte? currentSequence, HashSet<int> implementedSequences, Dictionary<int, (int StepCount, string? Comment)> sequenceDetails, bool hasEndSequence)
|
|
{
|
|
int val = maxSeq + 2;
|
|
float x = ImGui.GetContentRegionAvail().X;
|
|
int val2 = Math.Max(4, Math.Min(8, (int)(x / 100f)));
|
|
val2 = Math.Min(val2, val);
|
|
float y = ImGui.GetContentRegionAvail().Y;
|
|
using (ImRaii.PushColor(ImGuiCol.ChildBg, new Vector4(0.08f, 0.06f, 0.12f, 0.6f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Border, new Vector4(0.6f, 0.5f, 0.8f, 0.2f)))
|
|
{
|
|
using ImRaii.IEndObject endObject = ImRaii.Child("SequenceGrid", new Vector2(-1f, y), border: true, ImGuiWindowFlags.None);
|
|
if (!ImRaii.IEndObject.op_True(endObject))
|
|
{
|
|
return;
|
|
}
|
|
using (ImRaii.PushColor(ImGuiCol.TableBorderStrong, new Vector4(0.6f, 0.5f, 0.8f, 0.2f)))
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.TableBorderLight, new Vector4(0.6f, 0.5f, 0.8f, 0.15f)))
|
|
{
|
|
using ImRaii.IEndObject endObject2 = ImRaii.Table("SequenceGridTable", val2, ImGuiTableFlags.Borders | ImGuiTableFlags.SizingStretchSame);
|
|
if (!ImRaii.IEndObject.op_True(endObject2))
|
|
{
|
|
return;
|
|
}
|
|
int num = 0;
|
|
for (int i = 0; i <= maxSeq; i++)
|
|
{
|
|
if (num % val2 == 0)
|
|
{
|
|
ImGui.TableNextRow();
|
|
}
|
|
ImGui.TableNextColumn();
|
|
DrawSequenceCell(i, currentSequence, implementedSequences, sequenceDetails);
|
|
num++;
|
|
}
|
|
if (num % val2 == 0)
|
|
{
|
|
ImGui.TableNextRow();
|
|
}
|
|
ImGui.TableNextColumn();
|
|
DrawSequenceCell(255, currentSequence, implementedSequences, sequenceDetails, hasEndSequence);
|
|
for (num++; num % val2 != 0; num++)
|
|
{
|
|
ImGui.TableNextColumn();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawSequenceCell(int sequenceId, byte? currentSequence, HashSet<int> implementedSequences, Dictionary<int, (int StepCount, string? Comment)> sequenceDetails, bool? forcedImplemented = null)
|
|
{
|
|
bool flag = currentSequence.HasValue && sequenceId == currentSequence.Value;
|
|
bool flag2 = forcedImplemented ?? implementedSequences.Contains(sequenceId);
|
|
bool flag3 = _hoveredSequenceId == sequenceId;
|
|
string text = ((sequenceId == 255) ? "255" : $"{sequenceId}");
|
|
Vector4 input;
|
|
Vector4 input2;
|
|
if (flag)
|
|
{
|
|
input = (flag3 ? new Vector4(0.18f, 0.55f, 0.25f, 0.8f) : new Vector4(0.15f, 0.48f, 0.22f, 0.7f));
|
|
input2 = new Vector4(0.5f, 1f, 0.6f, flag3 ? 0.8f : 0.5f);
|
|
}
|
|
else if (flag2)
|
|
{
|
|
input = (flag3 ? new Vector4(0.14f, 0.38f, 0.18f, 0.6f) : new Vector4(0.12f, 0.34f, 0.16f, 0.5f));
|
|
input2 = new Vector4(0.5f, 1f, 0.6f, flag3 ? 0.5f : 0.25f);
|
|
}
|
|
else
|
|
{
|
|
input = (flag3 ? new Vector4(0.5f, 0.18f, 0.18f, 0.6f) : new Vector4(0.45f, 0.15f, 0.15f, 0.5f));
|
|
input2 = new Vector4(1f, 0.5f, 0.5f, flag3 ? 0.6f : 0.3f);
|
|
}
|
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
Vector2 vector = new Vector2(ImGui.GetContentRegionAvail().X, 75f);
|
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
windowDrawList.AddRectFilled(cursorScreenPos, cursorScreenPos + vector, ImGui.ColorConvertFloat4ToU32(input), 3f);
|
|
if (flag3)
|
|
{
|
|
windowDrawList.AddRect(cursorScreenPos - new Vector2(1f, 1f), cursorScreenPos + vector + new Vector2(1f, 1f), ImGui.ColorConvertFloat4ToU32(new Vector4(input2.X, input2.Y, input2.Z, input2.W * 0.3f)), 3f, ImDrawFlags.None, 3f);
|
|
}
|
|
windowDrawList.AddRect(cursorScreenPos, cursorScreenPos + vector, ImGui.ColorConvertFloat4ToU32(input2), 3f, ImDrawFlags.None, flag3 ? 2f : 1.5f);
|
|
float x = vector.X;
|
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
Vector4 input3 = (flag ? new Vector4(0.98f, 0.98f, 1f, 1f) : new Vector4(0.9f, 0.9f, 0.98f, 1f));
|
|
float y = cursorScreenPos.Y + (vector.Y - vector2.Y) * 0.5f;
|
|
windowDrawList.AddText(new Vector2(cursorScreenPos.X + (x - vector2.X) * 0.5f, y), ImGui.ColorConvertFloat4ToU32(input3), text);
|
|
ImGui.SetCursorScreenPos(cursorScreenPos);
|
|
ImU8String strId = new ImU8String(5, 1);
|
|
strId.AppendLiteral("##Seq");
|
|
strId.AppendFormatted(sequenceId);
|
|
ImGui.InvisibleButton(strId, vector);
|
|
if (ImGui.IsItemHovered())
|
|
{
|
|
_hoveredSequenceId = sequenceId;
|
|
using (ImRaii.Tooltip())
|
|
{
|
|
using (ImRaii.PushColor(ImGuiCol.Text, new Vector4(0.98f, 0.98f, 1f, 1f)))
|
|
{
|
|
strId = new ImU8String(9, 1);
|
|
strId.AppendLiteral("Sequence ");
|
|
strId.AppendFormatted(sequenceId);
|
|
ImGui.Text(strId);
|
|
}
|
|
ImGui.Separator();
|
|
if (flag2 && sequenceDetails.TryGetValue(sequenceId, out (int, string) value))
|
|
{
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
ImGui.TextColored(new Vector4(0.5f, 1f, 0.6f, 1f), FontAwesomeIcon.CheckCircle.ToIconString());
|
|
ImGui.PopFont();
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(0.5f, 1f, 0.6f, 1f), "Implemented");
|
|
ImGui.Spacing();
|
|
Vector4 col = new Vector4(0.9f, 0.9f, 0.98f, 1f);
|
|
strId = new ImU8String(6, 0);
|
|
strId.AppendLiteral("Steps:");
|
|
ImGui.TextColored(in col, strId);
|
|
ImGui.SameLine();
|
|
col = new Vector4(0.7f, 0.9f, 1f, 1f);
|
|
strId = new ImU8String(0, 1);
|
|
strId.AppendFormatted(value.Item1);
|
|
ImGui.TextColored(in col, strId);
|
|
if (!string.IsNullOrEmpty(value.Item2))
|
|
{
|
|
ImGui.Separator();
|
|
ImGui.PushTextWrapPos(250f);
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), value.Item2);
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
}
|
|
else if (!flag2)
|
|
{
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
ImGui.TextColored(new Vector4(1f, 0.5f, 0.5f, 1f), FontAwesomeIcon.TimesCircle.ToIconString());
|
|
ImGui.PopFont();
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(new Vector4(1f, 0.5f, 0.5f, 1f), "Not Implemented");
|
|
ImGui.Spacing();
|
|
ImGui.PushTextWrapPos(250f);
|
|
ImGui.TextColored(new Vector4(0.7f, 0.7f, 0.8f, 1f), "This sequence is missing from the quest path.");
|
|
ImGui.PopTextWrapPos();
|
|
}
|
|
if (flag)
|
|
{
|
|
ImGui.Separator();
|
|
ImGui.TextColored(new Vector4(1f, 0.85f, 0.5f, 1f), "► Currently Active");
|
|
}
|
|
}
|
|
}
|
|
else if (_hoveredSequenceId == sequenceId)
|
|
{
|
|
_hoveredSequenceId = -1;
|
|
}
|
|
ImGui.SetCursorScreenPos(cursorScreenPos + new Vector2(0f, vector.Y));
|
|
}
|
|
}
|