forked from liza/Questionable
Seasonal event info panel
This commit is contained in:
parent
57712b1c0c
commit
3ba342aa48
@ -18,6 +18,7 @@ internal sealed class Configuration : IPluginConfiguration
|
|||||||
public GrandCompany GrandCompany { get; set; } = GrandCompany.None;
|
public GrandCompany GrandCompany { get; set; } = GrandCompany.None;
|
||||||
public bool HideInAllInstances { get; set; } = true;
|
public bool HideInAllInstances { get; set; } = true;
|
||||||
public bool UseEscToCancelQuesting { get; set; } = true;
|
public bool UseEscToCancelQuesting { get; set; } = true;
|
||||||
|
public bool ShowIncompleteSeasonalEvents { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class AdvancedConfiguration
|
internal sealed class AdvancedConfiguration
|
||||||
|
@ -208,6 +208,7 @@ public sealed class QuestionablePlugin : IDalamudPlugin
|
|||||||
serviceCollection.AddSingleton<ActiveQuestComponent>();
|
serviceCollection.AddSingleton<ActiveQuestComponent>();
|
||||||
serviceCollection.AddSingleton<ARealmRebornComponent>();
|
serviceCollection.AddSingleton<ARealmRebornComponent>();
|
||||||
serviceCollection.AddSingleton<CreationUtilsComponent>();
|
serviceCollection.AddSingleton<CreationUtilsComponent>();
|
||||||
|
serviceCollection.AddSingleton<EventInfoComponent>();
|
||||||
serviceCollection.AddSingleton<QuestTooltipComponent>();
|
serviceCollection.AddSingleton<QuestTooltipComponent>();
|
||||||
serviceCollection.AddSingleton<QuickAccessButtonsComponent>();
|
serviceCollection.AddSingleton<QuickAccessButtonsComponent>();
|
||||||
serviceCollection.AddSingleton<RemainingTasksComponent>();
|
serviceCollection.AddSingleton<RemainingTasksComponent>();
|
||||||
|
@ -83,6 +83,13 @@ internal sealed class ConfigWindow : LWindow, IPersistableWindowConfig
|
|||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool showIncompleteSeasonalEvents = _configuration.General.ShowIncompleteSeasonalEvents;
|
||||||
|
if (ImGui.Checkbox("Show details for incomplete seasonal events", ref showIncompleteSeasonalEvents))
|
||||||
|
{
|
||||||
|
_configuration.General.ShowIncompleteSeasonalEvents = showIncompleteSeasonalEvents;
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.EndTabItem();
|
ImGui.EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
133
Questionable/Windows/QuestComponents/EventInfoComponent.cs
Normal file
133
Questionable/Windows/QuestComponents/EventInfoComponent.cs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using Dalamud.Interface.Components;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Humanizer;
|
||||||
|
using Humanizer.Localisation;
|
||||||
|
using ImGuiNET;
|
||||||
|
using Questionable.Controller;
|
||||||
|
using Questionable.Data;
|
||||||
|
using Questionable.Functions;
|
||||||
|
using Questionable.Model;
|
||||||
|
using Questionable.Model.Questing;
|
||||||
|
|
||||||
|
namespace Questionable.Windows.QuestComponents;
|
||||||
|
|
||||||
|
internal sealed class EventInfoComponent
|
||||||
|
{
|
||||||
|
private readonly List<EventQuest> _eventQuests =
|
||||||
|
[
|
||||||
|
new EventQuest("Moonfire Faire", [new(5182), new(5183)],
|
||||||
|
new DateTime(new DateOnly(2024, 8, 26), new TimeOnly(14, 59), DateTimeKind.Utc)),
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly QuestData _questData;
|
||||||
|
private readonly QuestRegistry _questRegistry;
|
||||||
|
private readonly QuestFunctions _questFunctions;
|
||||||
|
private readonly UiUtils _uiUtils;
|
||||||
|
private readonly QuestController _questController;
|
||||||
|
private readonly QuestTooltipComponent _questTooltipComponent;
|
||||||
|
private readonly Configuration _configuration;
|
||||||
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
|
|
||||||
|
public EventInfoComponent(QuestData questData, QuestRegistry questRegistry, QuestFunctions questFunctions,
|
||||||
|
UiUtils uiUtils, QuestController questController, QuestTooltipComponent questTooltipComponent,
|
||||||
|
Configuration configuration, IDalamudPluginInterface pluginInterface)
|
||||||
|
{
|
||||||
|
_questData = questData;
|
||||||
|
_questRegistry = questRegistry;
|
||||||
|
_questFunctions = questFunctions;
|
||||||
|
_uiUtils = uiUtils;
|
||||||
|
_questController = questController;
|
||||||
|
_questTooltipComponent = questTooltipComponent;
|
||||||
|
_configuration = configuration;
|
||||||
|
_pluginInterface = pluginInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ShouldDraw => _configuration.General.ShowIncompleteSeasonalEvents && _eventQuests.Any(IsIncomplete);
|
||||||
|
|
||||||
|
public void Draw()
|
||||||
|
{
|
||||||
|
foreach (var eventQuest in _eventQuests)
|
||||||
|
{
|
||||||
|
if (IsIncomplete(eventQuest))
|
||||||
|
DrawEventQuest(eventQuest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawEventQuest(EventQuest eventQuest)
|
||||||
|
{
|
||||||
|
string time = (eventQuest.EndsAtUtc - DateTime.UtcNow).Humanize(
|
||||||
|
precision: 1,
|
||||||
|
culture: CultureInfo.InvariantCulture,
|
||||||
|
minUnit: TimeUnit.Minute,
|
||||||
|
maxUnit: TimeUnit.Day);
|
||||||
|
ImGui.Text($"{eventQuest.Name} ({time})");
|
||||||
|
|
||||||
|
float width;
|
||||||
|
using (var _ = _pluginInterface.UiBuilder.IconFontHandle.Push())
|
||||||
|
width = ImGui.CalcTextSize(FontAwesomeIcon.Play.ToIconString()).X + ImGui.GetStyle().FramePadding.X;
|
||||||
|
|
||||||
|
using (var _ = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||||
|
width -= ImGui.CalcTextSize(FontAwesomeIcon.Check.ToIconString()).X;
|
||||||
|
|
||||||
|
List<QuestId> startableQuests = eventQuest.QuestIds.Where(x =>
|
||||||
|
_questRegistry.IsKnownQuest(x) &&
|
||||||
|
_questFunctions.IsReadyToAcceptQuest(x) &&
|
||||||
|
x != _questController.StartedQuest?.Quest.Id &&
|
||||||
|
x != _questController.NextQuest?.Quest.Id)
|
||||||
|
.ToList();
|
||||||
|
if (startableQuests.Count == 0)
|
||||||
|
width = 0;
|
||||||
|
|
||||||
|
foreach (var questId in eventQuest.QuestIds)
|
||||||
|
{
|
||||||
|
if (_questFunctions.IsQuestComplete(questId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string questName = _questData.GetQuestInfo(questId).Name;
|
||||||
|
if (startableQuests.Contains(questId) &&
|
||||||
|
_questRegistry.TryGetQuest(questId, out Quest? quest))
|
||||||
|
{
|
||||||
|
ImGuiComponents.IconButton(FontAwesomeIcon.Play);
|
||||||
|
if (ImGui.IsItemClicked())
|
||||||
|
{
|
||||||
|
_questController.SetNextQuest(quest);
|
||||||
|
_questController.Start("SeasonalEventSelection");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hovered = ImGui.IsItemHovered();
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.Text(questName);
|
||||||
|
hovered |= ImGui.IsItemHovered();
|
||||||
|
|
||||||
|
if (hovered)
|
||||||
|
_questTooltipComponent.Draw(quest.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (width > 0)
|
||||||
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + width);
|
||||||
|
|
||||||
|
var style = _uiUtils.GetQuestStyle(questId);
|
||||||
|
if (_uiUtils.ChecklistItem(questName, style.Color, style.Icon, ImGui.GetStyle().FramePadding.X))
|
||||||
|
_questTooltipComponent.Draw(_questData.GetQuestInfo(questId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsIncomplete(EventQuest eventQuest)
|
||||||
|
{
|
||||||
|
if (eventQuest.EndsAtUtc <= DateTime.UtcNow)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !eventQuest.QuestIds.All(x => _questFunctions.IsQuestComplete(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed record EventQuest(string Name, List<QuestId> QuestIds, DateTime EndsAtUtc);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using Dalamud.Interface;
|
using Dalamud.Game.Text;
|
||||||
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
using Dalamud.Interface.Utility.Raii;
|
using Dalamud.Interface.Utility.Raii;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
@ -44,6 +45,9 @@ internal sealed class QuestTooltipComponent
|
|||||||
using var tooltip = ImRaii.Tooltip();
|
using var tooltip = ImRaii.Tooltip();
|
||||||
if (tooltip)
|
if (tooltip)
|
||||||
{
|
{
|
||||||
|
ImGui.Text($"{SeIconChar.LevelEn.ToIconString()}{quest.Level}");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
var (color, _, tooltipText) = _uiUtils.GetQuestStyle(quest.QuestId);
|
var (color, _, tooltipText) = _uiUtils.GetQuestStyle(quest.QuestId);
|
||||||
ImGui.TextColored(color, tooltipText);
|
ImGui.TextColored(color, tooltipText);
|
||||||
if (quest.IsRepeatable)
|
if (quest.IsRepeatable)
|
||||||
|
@ -25,6 +25,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
|||||||
private readonly ActiveQuestComponent _activeQuestComponent;
|
private readonly ActiveQuestComponent _activeQuestComponent;
|
||||||
private readonly ARealmRebornComponent _aRealmRebornComponent;
|
private readonly ARealmRebornComponent _aRealmRebornComponent;
|
||||||
private readonly CreationUtilsComponent _creationUtilsComponent;
|
private readonly CreationUtilsComponent _creationUtilsComponent;
|
||||||
|
private readonly EventInfoComponent _eventInfoComponent;
|
||||||
private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
|
private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
|
||||||
private readonly RemainingTasksComponent _remainingTasksComponent;
|
private readonly RemainingTasksComponent _remainingTasksComponent;
|
||||||
private readonly IFramework _framework;
|
private readonly IFramework _framework;
|
||||||
@ -38,6 +39,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
|||||||
TerritoryData territoryData,
|
TerritoryData territoryData,
|
||||||
ActiveQuestComponent activeQuestComponent,
|
ActiveQuestComponent activeQuestComponent,
|
||||||
ARealmRebornComponent aRealmRebornComponent,
|
ARealmRebornComponent aRealmRebornComponent,
|
||||||
|
EventInfoComponent eventInfoComponent,
|
||||||
CreationUtilsComponent creationUtilsComponent,
|
CreationUtilsComponent creationUtilsComponent,
|
||||||
QuickAccessButtonsComponent quickAccessButtonsComponent,
|
QuickAccessButtonsComponent quickAccessButtonsComponent,
|
||||||
RemainingTasksComponent remainingTasksComponent,
|
RemainingTasksComponent remainingTasksComponent,
|
||||||
@ -53,6 +55,7 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
|||||||
_territoryData = territoryData;
|
_territoryData = territoryData;
|
||||||
_activeQuestComponent = activeQuestComponent;
|
_activeQuestComponent = activeQuestComponent;
|
||||||
_aRealmRebornComponent = aRealmRebornComponent;
|
_aRealmRebornComponent = aRealmRebornComponent;
|
||||||
|
_eventInfoComponent = eventInfoComponent;
|
||||||
_creationUtilsComponent = creationUtilsComponent;
|
_creationUtilsComponent = creationUtilsComponent;
|
||||||
_quickAccessButtonsComponent = quickAccessButtonsComponent;
|
_quickAccessButtonsComponent = quickAccessButtonsComponent;
|
||||||
_remainingTasksComponent = remainingTasksComponent;
|
_remainingTasksComponent = remainingTasksComponent;
|
||||||
@ -135,6 +138,12 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_eventInfoComponent.ShouldDraw)
|
||||||
|
{
|
||||||
|
_eventInfoComponent.Draw();
|
||||||
|
ImGui.Separator();
|
||||||
|
}
|
||||||
|
|
||||||
_creationUtilsComponent.Draw();
|
_creationUtilsComponent.Draw();
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ internal sealed class UiUtils
|
|||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Vector4 color, FontAwesomeIcon icon, string status) GetQuestStyle(ElementId elementId)
|
public (Vector4 Color, FontAwesomeIcon Icon, string Status) GetQuestStyle(ElementId elementId)
|
||||||
{
|
{
|
||||||
if (_questFunctions.IsQuestAccepted(elementId))
|
if (_questFunctions.IsQuestAccepted(elementId))
|
||||||
return (ImGuiColors.DalamudYellow, FontAwesomeIcon.PersonWalkingArrowRight, "Active");
|
return (ImGuiColors.DalamudYellow, FontAwesomeIcon.PersonWalkingArrowRight, "Active");
|
||||||
@ -42,7 +42,7 @@ internal sealed class UiUtils
|
|||||||
return (ImGuiColors.DalamudRed, FontAwesomeIcon.Times);
|
return (ImGuiColors.DalamudRed, FontAwesomeIcon.Times);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ChecklistItem(string text, Vector4 color, FontAwesomeIcon icon)
|
public bool ChecklistItem(string text, Vector4 color, FontAwesomeIcon icon, float extraPadding = 0)
|
||||||
{
|
{
|
||||||
// ReSharper disable once UnusedVariable
|
// ReSharper disable once UnusedVariable
|
||||||
using (var font = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
using (var font = _pluginInterface.UiBuilder.IconFontFixedWidthHandle.Push())
|
||||||
@ -53,6 +53,8 @@ internal sealed class UiUtils
|
|||||||
bool hover = ImGui.IsItemHovered();
|
bool hover = ImGui.IsItemHovered();
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
if (extraPadding > 0)
|
||||||
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + extraPadding);
|
||||||
ImGui.TextUnformatted(text);
|
ImGui.TextUnformatted(text);
|
||||||
return hover;
|
return hover;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user