muffin v7.38.5

This commit is contained in:
alydev 2025-11-24 14:55:42 +10:00
parent 7177a5440c
commit ac85eea230
3 changed files with 966 additions and 420 deletions

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,8 @@ using System.Numerics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Dalamud.Plugin; using Dalamud.Plugin;
using Dalamud.Plugin.Ipc; using Dalamud.Plugin.Ipc;
using FFXIVClientStructs.FFXIV.Client.Game;
using Microsoft.Extensions.DependencyInjection;
using Questionable.Controller; using Questionable.Controller;
using Questionable.Controller.Steps; using Questionable.Controller.Steps;
using Questionable.Data; using Questionable.Data;
@ -13,6 +15,7 @@ using Questionable.Functions;
using Questionable.Model; using Questionable.Model;
using Questionable.Model.Questing; using Questionable.Model.Questing;
using Questionable.Windows; using Questionable.Windows;
using Questionable.Windows.JournalComponents;
using Questionable.Windows.QuestComponents; using Questionable.Windows.QuestComponents;
namespace Questionable.External; namespace Questionable.External;
@ -134,6 +137,20 @@ internal sealed class QuestionableIpc : IDisposable
private const string IpcSetSequenceStopCondition = "Questionable.SetSequenceStopCondition"; private const string IpcSetSequenceStopCondition = "Questionable.SetSequenceStopCondition";
private const string IpcGetAlliedSocietyRemainingAllowances = "Questionable.AlliedSociety.GetRemainingAllowances";
private const string IpcGetAlliedSocietyTimeUntilReset = "Questionable.AlliedSociety.GetTimeUntilReset";
private const string IpcGetAlliedSocietyAvailableQuestIds = "Questionable.AlliedSociety.GetAvailableQuestIds";
private const string IpcGetAlliedSocietyAllAvailableQuestCounts = "Questionable.AlliedSociety.GetAllAvailableQuestCounts";
private const string IpcGetAlliedSocietyIsMaxRank = "Questionable.AlliedSociety.IsMaxRank";
private const string IpcGetAlliedSocietyCurrentRank = "Questionable.AlliedSociety.GetCurrentRank";
private const string IpcGetAlliedSocietiesWithAvailableQuests = "Questionable.AlliedSociety.GetSocietiesWithAvailableQuests";
private readonly QuestController _questController; private readonly QuestController _questController;
private readonly QuestRegistry _questRegistry; private readonly QuestRegistry _questRegistry;
@ -150,6 +167,8 @@ internal sealed class QuestionableIpc : IDisposable
private readonly IDalamudPluginInterface _pluginInterface; private readonly IDalamudPluginInterface _pluginInterface;
private readonly IServiceProvider _serviceProvider;
private readonly ICallGateProvider<bool> _isRunning; private readonly ICallGateProvider<bool> _isRunning;
private readonly ICallGateProvider<string?> _getCurrentQuestId; private readonly ICallGateProvider<string?> _getCurrentQuestId;
@ -236,7 +255,21 @@ internal sealed class QuestionableIpc : IDisposable
private readonly ICallGateProvider<bool, int, bool> _setSequenceStopCondition; private readonly ICallGateProvider<bool, int, bool> _setSequenceStopCondition;
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, QuestData questData, ManualPriorityComponent manualPriorityComponent, PresetBuilderComponent presetBuilderComponent, Configuration configuration, IDalamudPluginInterface pluginInterface) private readonly ICallGateProvider<int> _getAlliedSocietyRemainingAllowances;
private readonly ICallGateProvider<long> _getAlliedSocietyTimeUntilReset;
private readonly ICallGateProvider<byte, List<string>> _getAlliedSocietyAvailableQuestIds;
private readonly ICallGateProvider<Dictionary<byte, int>> _getAlliedSocietyAllAvailableQuestCounts;
private readonly ICallGateProvider<byte, bool> _getAlliedSocietyIsMaxRank;
private readonly ICallGateProvider<byte, int> _getAlliedSocietyCurrentRank;
private readonly ICallGateProvider<List<byte>> _getAlliedSocietiesWithAvailableQuests;
public QuestionableIpc(QuestController questController, EventInfoComponent eventInfoComponent, QuestRegistry questRegistry, QuestFunctions questFunctions, QuestData questData, ManualPriorityComponent manualPriorityComponent, PresetBuilderComponent presetBuilderComponent, Configuration configuration, IDalamudPluginInterface pluginInterface, IServiceProvider serviceProvider)
{ {
QuestionableIpc questionableIpc = this; QuestionableIpc questionableIpc = this;
_questController = questController; _questController = questController;
@ -247,6 +280,7 @@ internal sealed class QuestionableIpc : IDisposable
_presetBuilderComponent = presetBuilderComponent; _presetBuilderComponent = presetBuilderComponent;
_configuration = configuration; _configuration = configuration;
_pluginInterface = pluginInterface; _pluginInterface = pluginInterface;
_serviceProvider = serviceProvider;
_isRunning = pluginInterface.GetIpcProvider<bool>("Questionable.IsRunning"); _isRunning = pluginInterface.GetIpcProvider<bool>("Questionable.IsRunning");
_isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning); _isRunning.RegisterFunc(() => questController.AutomationType != QuestController.EAutomationType.Manual || questController.IsRunning);
_getCurrentQuestId = pluginInterface.GetIpcProvider<string>("Questionable.GetCurrentQuestId"); _getCurrentQuestId = pluginInterface.GetIpcProvider<string>("Questionable.GetCurrentQuestId");
@ -334,6 +368,20 @@ internal sealed class QuestionableIpc : IDisposable
_getSequenceStopCondition.RegisterFunc(GetSequenceStopCondition); _getSequenceStopCondition.RegisterFunc(GetSequenceStopCondition);
_setSequenceStopCondition = pluginInterface.GetIpcProvider<bool, int, bool>("Questionable.SetSequenceStopCondition"); _setSequenceStopCondition = pluginInterface.GetIpcProvider<bool, int, bool>("Questionable.SetSequenceStopCondition");
_setSequenceStopCondition.RegisterFunc(SetSequenceStopCondition); _setSequenceStopCondition.RegisterFunc(SetSequenceStopCondition);
_getAlliedSocietyRemainingAllowances = pluginInterface.GetIpcProvider<int>("Questionable.AlliedSociety.GetRemainingAllowances");
_getAlliedSocietyRemainingAllowances.RegisterFunc(GetAlliedSocietyRemainingAllowances);
_getAlliedSocietyTimeUntilReset = pluginInterface.GetIpcProvider<long>("Questionable.AlliedSociety.GetTimeUntilReset");
_getAlliedSocietyTimeUntilReset.RegisterFunc(GetAlliedSocietyTimeUntilReset);
_getAlliedSocietyAvailableQuestIds = pluginInterface.GetIpcProvider<byte, List<string>>("Questionable.AlliedSociety.GetAvailableQuestIds");
_getAlliedSocietyAvailableQuestIds.RegisterFunc(GetAlliedSocietyAvailableQuestIds);
_getAlliedSocietyAllAvailableQuestCounts = pluginInterface.GetIpcProvider<Dictionary<byte, int>>("Questionable.AlliedSociety.GetAllAvailableQuestCounts");
_getAlliedSocietyAllAvailableQuestCounts.RegisterFunc(GetAlliedSocietyAllAvailableQuestCounts);
_getAlliedSocietyIsMaxRank = pluginInterface.GetIpcProvider<byte, bool>("Questionable.AlliedSociety.IsMaxRank");
_getAlliedSocietyIsMaxRank.RegisterFunc(GetAlliedSocietyIsMaxRank);
_getAlliedSocietyCurrentRank = pluginInterface.GetIpcProvider<byte, int>("Questionable.AlliedSociety.GetCurrentRank");
_getAlliedSocietyCurrentRank.RegisterFunc(GetAlliedSocietyCurrentRank);
_getAlliedSocietiesWithAvailableQuests = pluginInterface.GetIpcProvider<List<byte>>("Questionable.AlliedSociety.GetSocietiesWithAvailableQuests");
_getAlliedSocietiesWithAvailableQuests.RegisterFunc(GetAlliedSocietiesWithAvailableQuests);
} }
private bool StartQuest(string questId, bool single) private bool StartQuest(string questId, bool single)
@ -921,6 +969,97 @@ internal sealed class QuestionableIpc : IDisposable
return true; return true;
} }
private unsafe int GetAlliedSocietyRemainingAllowances()
{
QuestManager* ptr = QuestManager.Instance();
if (ptr == null)
{
return 12;
}
return (int)ptr->GetBeastTribeAllowance();
}
private long GetAlliedSocietyTimeUntilReset()
{
TimeSpan item = AlliedSocietyJournalComponent.CalculateTimeUntilReset().TimeUntilReset;
return item.Ticks;
}
private List<string> GetAlliedSocietyAvailableQuestIds(byte alliedSocietyId)
{
if (!Enum.IsDefined(typeof(EAlliedSociety), alliedSocietyId))
{
return new List<string>();
}
EAlliedSociety alliedSociety = (EAlliedSociety)alliedSocietyId;
return (from q in _serviceProvider.GetRequiredService<AlliedSocietyQuestFunctions>().GetAvailableAlliedSocietyQuests(alliedSociety)
select q.ToString()).ToList();
}
private Dictionary<byte, int> GetAlliedSocietyAllAvailableQuestCounts()
{
Dictionary<byte, int> dictionary = new Dictionary<byte, int>();
AlliedSocietyQuestFunctions requiredService = _serviceProvider.GetRequiredService<AlliedSocietyQuestFunctions>();
EAlliedSociety[] values = Enum.GetValues<EAlliedSociety>();
foreach (EAlliedSociety eAlliedSociety in values)
{
if (eAlliedSociety != EAlliedSociety.None)
{
int count = requiredService.GetAvailableAlliedSocietyQuests(eAlliedSociety).Count;
if (count > 0)
{
dictionary[(byte)eAlliedSociety] = count;
}
}
}
return dictionary;
}
private unsafe bool GetAlliedSocietyIsMaxRank(byte alliedSocietyId)
{
if (!Enum.IsDefined(typeof(EAlliedSociety), alliedSocietyId) || alliedSocietyId == 0)
{
return false;
}
QuestManager* ptr = QuestManager.Instance();
if (ptr == null)
{
return false;
}
byte num = (byte)(ptr->BeastReputation[alliedSocietyId - 1].Rank & 0x7F);
byte b = (byte)((alliedSocietyId <= 5) ? 8 : 3);
return num >= b;
}
private unsafe int GetAlliedSocietyCurrentRank(byte alliedSocietyId)
{
if (!Enum.IsDefined(typeof(EAlliedSociety), alliedSocietyId) || alliedSocietyId == 0)
{
return -1;
}
QuestManager* ptr = QuestManager.Instance();
if (ptr == null)
{
return -1;
}
return (byte)(ptr->BeastReputation[alliedSocietyId - 1].Rank & 0x7F);
}
private List<byte> GetAlliedSocietiesWithAvailableQuests()
{
List<byte> list = new List<byte>();
AlliedSocietyQuestFunctions requiredService = _serviceProvider.GetRequiredService<AlliedSocietyQuestFunctions>();
EAlliedSociety[] values = Enum.GetValues<EAlliedSociety>();
foreach (EAlliedSociety eAlliedSociety in values)
{
if (eAlliedSociety != EAlliedSociety.None && requiredService.GetAvailableAlliedSocietyQuests(eAlliedSociety).Count > 0)
{
list.Add((byte)eAlliedSociety);
}
}
return list;
}
public void Dispose() public void Dispose()
{ {
_exportQuestPriority.UnregisterFunc(); _exportQuestPriority.UnregisterFunc();
@ -966,5 +1105,12 @@ internal sealed class QuestionableIpc : IDisposable
_getStopQuestList.UnregisterFunc(); _getStopQuestList.UnregisterFunc();
_setStopConditionsEnabled.UnregisterFunc(); _setStopConditionsEnabled.UnregisterFunc();
_getStopConditionsEnabled.UnregisterFunc(); _getStopConditionsEnabled.UnregisterFunc();
_getAlliedSocietiesWithAvailableQuests.UnregisterFunc();
_getAlliedSocietyCurrentRank.UnregisterFunc();
_getAlliedSocietyIsMaxRank.UnregisterFunc();
_getAlliedSocietyAllAvailableQuestCounts.UnregisterFunc();
_getAlliedSocietyAvailableQuestIds.UnregisterFunc();
_getAlliedSocietyTimeUntilReset.UnregisterFunc();
_getAlliedSocietyRemainingAllowances.UnregisterFunc();
} }
} }

View file

@ -1,9 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui; using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors; using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
using Dalamud.Interface.Utility.Raii; using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using Microsoft.Extensions.Logging;
using Questionable.Controller; using Questionable.Controller;
using Questionable.Data; using Questionable.Data;
using Questionable.Functions; using Questionable.Functions;
@ -17,6 +23,10 @@ internal sealed class AlliedSocietyJournalComponent
{ {
private static readonly string[] RankNames = new string[8] { "Neutral", "Recognized", "Friendly", "Trusted", "Respected", "Honored", "Sworn", "Allied" }; private static readonly string[] RankNames = new string[8] { "Neutral", "Recognized", "Friendly", "Trusted", "Respected", "Honored", "Sworn", "Allied" };
private const int DefaultDailyQuestLimit = 3;
private const int SharedDailyAllowanceLimit = 12;
private readonly AlliedSocietyQuestFunctions _alliedSocietyQuestFunctions; private readonly AlliedSocietyQuestFunctions _alliedSocietyQuestFunctions;
private readonly QuestData _questData; private readonly QuestData _questData;
@ -29,7 +39,13 @@ internal sealed class AlliedSocietyJournalComponent
private readonly UiUtils _uiUtils; private readonly UiUtils _uiUtils;
public AlliedSocietyJournalComponent(AlliedSocietyQuestFunctions alliedSocietyQuestFunctions, QuestData questData, QuestRegistry questRegistry, QuestJournalUtils questJournalUtils, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils) private readonly QuestController _questController;
private readonly IChatGui _chatGui;
private readonly ILogger<AlliedSocietyJournalComponent> _logger;
public AlliedSocietyJournalComponent(AlliedSocietyQuestFunctions alliedSocietyQuestFunctions, QuestData questData, QuestRegistry questRegistry, QuestJournalUtils questJournalUtils, QuestTooltipComponent questTooltipComponent, UiUtils uiUtils, QuestController questController, IChatGui chatGui, ILogger<AlliedSocietyJournalComponent> logger)
{ {
_alliedSocietyQuestFunctions = alliedSocietyQuestFunctions; _alliedSocietyQuestFunctions = alliedSocietyQuestFunctions;
_questData = questData; _questData = questData;
@ -37,6 +53,9 @@ internal sealed class AlliedSocietyJournalComponent
_questJournalUtils = questJournalUtils; _questJournalUtils = questJournalUtils;
_questTooltipComponent = questTooltipComponent; _questTooltipComponent = questTooltipComponent;
_uiUtils = uiUtils; _uiUtils = uiUtils;
_questController = questController;
_chatGui = chatGui;
_logger = logger;
} }
public void DrawAlliedSocietyQuests() public void DrawAlliedSocietyQuests()
@ -46,39 +65,394 @@ internal sealed class AlliedSocietyJournalComponent
{ {
return; return;
} }
DrawDailyAllowanceHeader();
foreach (EAlliedSociety item in from x in Enum.GetValues<EAlliedSociety>() foreach (EAlliedSociety item in from x in Enum.GetValues<EAlliedSociety>()
where x != EAlliedSociety.None where x != EAlliedSociety.None
select x) select x)
{ {
List<QuestInfo> list = (from x in _alliedSocietyQuestFunctions.GetAvailableAlliedSocietyQuests(item) List<QuestInfo> list = (from x in _alliedSocietyQuestFunctions.GetAvailableAlliedSocietyQuests(item)
select (QuestInfo)_questData.GetQuestInfo(x)).ToList(); select (QuestInfo)_questData.GetQuestInfo(x)).ToList();
if (list.Count == 0 || !ImGui.CollapsingHeader($"{item}###AlliedSociety{item}")) if (list.Count != 0 && DrawAlliedSocietyHeader(item, list))
{ {
continue; using (ImRaii.PushIndent())
}
if ((int)item <= 5)
{ {
byte i = 1; DrawAddToPriorityButtons(item, list);
while (i <= 8) ImGui.Spacing();
{ ImGui.Separator();
List<QuestInfo> list2 = list.Where((QuestInfo x) => x.AlliedSocietyRank == i).ToList(); ImGui.Spacing();
if (list2.Count != 0) DrawQuestList(item, list);
{
ImGui.Text(RankNames[i - 1]);
foreach (QuestInfo item2 in list2)
{
DrawQuest(item2);
} }
} }
byte b = (byte)(i + 1);
i = b;
} }
continue;
} }
foreach (QuestInfo item3 in list)
private unsafe void DrawDailyAllowanceHeader()
{ {
DrawQuest(item3); QuestManager* ptr = QuestManager.Instance();
if (ptr != null)
{
byte b = (byte)ptr->GetBeastTribeAllowance();
int value = 12 - b;
(DateTime ResetTime, TimeSpan TimeUntilReset) tuple = CalculateTimeUntilReset();
DateTime item = tuple.ResetTime;
string value2 = FormatTimeSpan(tuple.TimeUntilReset);
Vector4 col = ((b > 0) ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed);
ImU8String text = new ImU8String(31, 2);
text.AppendLiteral("Daily Allowances: ");
text.AppendFormatted(b);
text.AppendLiteral(" / ");
text.AppendFormatted(12);
text.AppendLiteral(" remaining");
ImGui.TextColored(in col, text);
ImGui.SameLine();
col = ImGuiColors.DalamudGrey3;
text = new ImU8String(13, 1);
text.AppendLiteral("(Resets in: ");
text.AppendFormatted(value2);
text.AppendLiteral(")");
ImGui.TextColored(in col, text);
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.TextUnformatted("Shared across ALL allied societies (all expansions)");
text = new ImU8String(12, 1);
text.AppendLiteral("Used today: ");
text.AppendFormatted(value);
ImGui.TextUnformatted(text);
ImGui.TextUnformatted("Each allied society has a limit of 3 quests per day");
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
col = ImGuiColors.DalamudGrey3;
text = new ImU8String(12, 1);
text.AppendLiteral("Next reset: ");
text.AppendFormatted(item, "g");
ImGui.TextColored(in col, text);
col = ImGuiColors.DalamudGrey3;
text = new ImU8String(18, 1);
text.AppendLiteral("Time until reset: ");
text.AppendFormatted(value2);
ImGui.TextColored(in col, text);
ImGui.EndTooltip();
} }
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
}
}
internal static (DateTime ResetTime, TimeSpan TimeUntilReset) CalculateTimeUntilReset()
{
DateTime utcNow = DateTime.UtcNow;
DateTime dateTime = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, 15, 0, 0, DateTimeKind.Utc);
DateTime dateTime2 = ((utcNow >= dateTime) ? dateTime.AddDays(1.0) : dateTime);
TimeSpan item = dateTime2 - utcNow;
return (ResetTime: dateTime2.ToLocalTime(), TimeUntilReset: item);
}
private static string FormatTimeSpan(TimeSpan timeSpan)
{
if (timeSpan.TotalMinutes < 1.0)
{
return "< 1m";
}
if (!(timeSpan.TotalHours < 1.0))
{
if (!(timeSpan.TotalDays < 1.0))
{
return $"{(int)timeSpan.TotalDays}d {timeSpan.Hours}h";
}
return $"{timeSpan.Hours}h {timeSpan.Minutes}m";
}
return $"{timeSpan.Minutes}m";
}
private bool DrawAlliedSocietyHeader(EAlliedSociety alliedSociety, List<QuestInfo> quests)
{
return ImGui.CollapsingHeader($"{alliedSociety}###AlliedSociety{alliedSociety}");
}
private void DrawQuestList(EAlliedSociety alliedSociety, List<QuestInfo> quests)
{
if ((int)alliedSociety <= 5)
{
byte rank = 1;
while (rank <= 8)
{
List<QuestInfo> list = quests.Where((QuestInfo x) => x.AlliedSocietyRank == rank).ToList();
if (list.Count != 0)
{
ImGui.Text(RankNames[rank - 1]);
foreach (QuestInfo item in list)
{
DrawQuest(item);
}
}
byte b = (byte)(rank + 1);
rank = b;
}
return;
}
foreach (QuestInfo quest in quests)
{
DrawQuest(quest);
}
}
private void DrawAddToPriorityButtons(EAlliedSociety alliedSociety, List<QuestInfo> quests)
{
bool flag = (int)alliedSociety <= 5;
int dailyLimit = (flag ? 12 : 3);
int remainingAllowances = GetRemainingAllowances();
Quest quest;
List<QuestInfo> list = (from q in quests
where _questRegistry.TryGetQuest(q.QuestId, out quest) && !quest.Root.Disabled
where !_questController.ManualPriorityQuests.Any((Quest pq) => pq.Id.Equals(q.QuestId))
orderby q.AlliedSocietyRank descending
select q).ToList();
if (list.Count == 0)
{
DrawDisabledAddButton();
}
else if (flag && list.Count > 3)
{
DrawArrSocietyButtons(alliedSociety, list, dailyLimit, remainingAllowances);
}
else
{
DrawStandardAddButton(alliedSociety, list, remainingAllowances);
}
}
private unsafe int GetRemainingAllowances()
{
QuestManager* ptr = QuestManager.Instance();
if (ptr == null)
{
return 12;
}
return (int)ptr->GetBeastTribeAllowance();
}
private static void DrawDisabledAddButton()
{
using (ImRaii.Disabled(disabled: true))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, "Add to Priority");
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
ImGui.SetTooltip("No quests available to add (may be disabled, already in priority, or not available)");
}
}
private void DrawArrSocietyButtons(EAlliedSociety alliedSociety, List<QuestInfo> availableQuests, int dailyLimit, int remainingAllowances)
{
int num = Math.Min(Math.Min(dailyLimit, remainingAllowances), availableQuests.Count);
using (ImRaii.Disabled(remainingAllowances == 0))
{
string text = ((num == remainingAllowances) ? $"Add {num} (Today's Remaining)" : $"Add {num} (Recommended)");
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, text))
{
AddQuestsToPriority(alliedSociety, availableQuests.Take(num).ToList());
}
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
DrawRecommendedButtonTooltip(num, remainingAllowances, dailyLimit, alliedSociety, availableQuests.Count);
}
ImGui.SameLine();
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ListOl, $"Add All {availableQuests.Count} (Ignore Limit)"))
{
AddQuestsToPriority(alliedSociety, availableQuests);
}
if (ImGui.IsItemHovered())
{
DrawAddAllButtonTooltip(availableQuests.Count, remainingAllowances, dailyLimit, alliedSociety);
}
}
private static void DrawRecommendedButtonTooltip(int questsToAddCount, int remainingAllowances, int dailyLimit, EAlliedSociety alliedSociety, int availableCount)
{
ImGui.BeginTooltip();
if (remainingAllowances == 0)
{
ImGui.TextUnformatted("No daily allowances remaining");
Vector4 col = ImGuiColors.DalamudGrey3;
ImU8String text = new ImU8String(44, 1);
text.AppendLiteral("You've used all ");
text.AppendFormatted(12);
text.AppendLiteral(" shared allowances for today");
ImGui.TextColored(in col, text);
}
else if (questsToAddCount == remainingAllowances)
{
ImU8String text = new ImU8String(47, 1);
text.AppendLiteral("Add ");
text.AppendFormatted(questsToAddCount);
text.AppendLiteral(" quests - matches your remaining allowances");
ImGui.TextUnformatted(text);
Vector4 col = ImGuiColors.ParsedGreen;
text = new ImU8String(50, 1);
text.AppendLiteral("You can complete ");
text.AppendFormatted(remainingAllowances);
text.AppendLiteral(" more allied society quests today");
ImGui.TextColored(in col, text);
ImGui.Spacing();
ImGui.TextColored(ImGuiColors.DalamudGrey3, "Prioritises highest rank quests first");
}
else if (questsToAddCount == dailyLimit)
{
ImU8String text = new ImU8String(41, 1);
text.AppendLiteral("Add ");
text.AppendFormatted(dailyLimit);
text.AppendLiteral(" quests - using all shared allowances");
ImGui.TextUnformatted(text);
ImGui.TextColored(ImGuiColors.DalamudGrey3, "This will use all 12 shared allowances");
ImGui.Spacing();
ImGui.TextColored(ImGuiColors.DalamudGrey3, "Prioritises highest rank quests first");
}
else
{
ImU8String text = new ImU8String(12, 2);
text.AppendLiteral("Add ");
text.AppendFormatted(questsToAddCount);
text.AppendLiteral(" ");
text.AppendFormatted(alliedSociety);
text.AppendLiteral(" quests");
ImGui.TextUnformatted(text);
Vector4 col = ImGuiColors.DalamudGrey3;
text = new ImU8String(55, 2);
text.AppendLiteral("Limited by available quests (");
text.AppendFormatted(availableCount);
text.AppendLiteral(") and shared allowances (");
text.AppendFormatted(remainingAllowances);
text.AppendLiteral(")");
ImGui.TextColored(in col, text);
ImGui.Spacing();
ImGui.TextColored(ImGuiColors.DalamudGrey3, "Prioritises highest rank quests first");
}
ImGui.EndTooltip();
}
private static void DrawAddAllButtonTooltip(int availableCount, int remainingAllowances, int dailyLimit, EAlliedSociety alliedSociety)
{
ImGui.BeginTooltip();
if (availableCount > remainingAllowances)
{
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ExclamationTriangle, "Warning: Exceeds shared allowances");
}
ImGui.Spacing();
ImU8String text = new ImU8String(54, 1);
text.AppendLiteral("This adds all ");
text.AppendFormatted(availableCount);
text.AppendLiteral(" available quests to your priority list,");
ImGui.TextUnformatted(text);
text = new ImU8String(47, 1);
text.AppendLiteral("but you only have ");
text.AppendFormatted(remainingAllowances);
text.AppendLiteral(" shared allowances remaining.");
ImGui.TextUnformatted(text);
ImGui.Spacing();
ImGui.TextColored(ImGuiColors.DalamudGrey3, "The excess quests won't be completable until tomorrow.");
}
else if (availableCount > dailyLimit)
{
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ExclamationTriangle, "Warning: Exceeds shared allowances");
}
ImGui.Spacing();
ImU8String text = new ImU8String(32, 1);
text.AppendLiteral("This adds all ");
text.AppendFormatted(availableCount);
text.AppendLiteral(" available quests,");
ImGui.TextUnformatted(text);
text = new ImU8String(57, 1);
text.AppendLiteral("but you can only complete ");
text.AppendFormatted(12);
text.AppendLiteral(" allied society quests per day.");
ImGui.TextUnformatted(text);
ImGui.Spacing();
ImGui.TextColored(ImGuiColors.DalamudGrey3, "You'll need multiple days to complete them all.");
}
else
{
ImU8String text = new ImU8String(26, 2);
text.AppendLiteral("Add all ");
text.AppendFormatted(availableCount);
text.AppendLiteral(" available ");
text.AppendFormatted(alliedSociety);
text.AppendLiteral(" quests");
ImGui.TextUnformatted(text);
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.ParsedGreen))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, $"All can be completed today ({remainingAllowances} shared allowances remaining)");
}
}
ImGui.EndTooltip();
}
private void DrawStandardAddButton(EAlliedSociety alliedSociety, List<QuestInfo> availableQuests, int remainingAllowances)
{
if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Plus, availableQuests.Count switch
{
1 => "Add Quest to Priority",
2 => "Add Both Quests to Priority",
3 => "Add All 3 Quests to Priority",
_ => $"Add All {availableQuests.Count} Quests to Priority",
}))
{
AddQuestsToPriority(alliedSociety, availableQuests);
}
if (!ImGui.IsItemHovered())
{
return;
}
ImGui.BeginTooltip();
ImU8String text = new ImU8String(18, 3);
text.AppendLiteral("Add ");
text.AppendFormatted(availableQuests.Count);
text.AppendLiteral(" ");
text.AppendFormatted(alliedSociety);
text.AppendLiteral(" ");
text.AppendFormatted((availableQuests.Count == 1) ? "quest" : "quests");
text.AppendLiteral(" to priority");
ImGui.TextUnformatted(text);
if (availableQuests.Count <= remainingAllowances)
{
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.ParsedGreen))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.Check, $"Uses {availableQuests.Count} of {remainingAllowances} shared allowances");
}
}
else
{
using (ImRaii.PushColor(ImGuiCol.Text, ImGuiColors.DalamudOrange))
{
ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ExclamationTriangle, $"Exceeds remaining allowances ({remainingAllowances})");
}
}
ImGui.EndTooltip();
}
private void AddQuestsToPriority(EAlliedSociety alliedSociety, List<QuestInfo> questsToAdd)
{
int num = 0;
foreach (QuestInfo item in questsToAdd)
{
if (_questController.AddQuestPriority(item.QuestId))
{
num++;
}
}
if (num > 0)
{
string text = ((num == 1) ? "quest" : "quests");
_logger.LogInformation("Added {Count} {Society} {QuestWord} to priority list", num, alliedSociety, text);
_chatGui.Print($"Added {num} {alliedSociety} {text} to priority list.", "Questionable", 576);
} }
} }