1
0
Fork 0
forked from aly/qstbak

muffin v7.5.12

This commit is contained in:
alydev 2026-08-19 13:19:57 +10:00
parent 3102923ce2
commit 911ed68baa
65 changed files with 2356 additions and 1539 deletions

View file

@ -786,18 +786,18 @@ internal sealed class CustomDeliveryController : MiniTaskController<CustomDelive
if (!_npcPositions.TryGetValue(npcIndex, out (ushort, Vector3) value))
{
_logger.LogWarning("No position found for delivery NPC index {NpcIndex}, skipping navigation", npcIndex);
_taskQueue.Enqueue(new Questionable.Controller.Steps.Common.Mount.UnmountTask());
return;
}
uint valueOrDefault = _npcDataIds.GetValueOrDefault(npcIndex);
_routeEnqueuer.SetDestination(value.Item1, value.Item2);
if (_clientState.TerritoryType != value.Item1 && !_routeEnqueuer.TryEnqueueToTerritory(_taskQueue, value.Item1, value.Item2))
{
_logger.LogWarning("Could not route to delivery NPC territory {TerritoryId}; falling back to normal routing", value.Item1);
EnqueueNavigateTo(value.Item1, value.Item2);
}
else
{
_taskQueue.Enqueue(new DeliveryNpcApproachTask(value.Item1, value.Item2, valueOrDefault));
}
_taskQueue.Enqueue(new Questionable.Controller.Steps.Common.Mount.UnmountTask());
_taskQueue.Enqueue(new DeliveryNpcApproachTask(value.Item1, value.Item2, valueOrDefault));
}
private void EnqueueNavigateTo(ushort territoryId, Vector3 position)
@ -808,12 +808,11 @@ internal sealed class CustomDeliveryController : MiniTaskController<CustomDelive
private void EnqueueTurnInSequence(DeliveryPlan plan)
{
EnqueueNavigateToNpc(plan.NpcIndex);
_taskQueue.Enqueue(new Questionable.Controller.Steps.Common.Mount.UnmountTask());
if (!_npcDataIds.ContainsKey(plan.NpcIndex))
{
_logger.LogWarning("No DataId for delivery NPC index {NpcIndex}, turn-in may fail", plan.NpcIndex);
}
_taskQueue.Enqueue(new SatisfactionSupplyTurnInTask(plan.NpcIndex, plan.Slot, plan.DeliveryCount, _npcDataIds.GetValueOrDefault(plan.NpcIndex)));
_taskQueue.Enqueue(new SatisfactionSupplyTurnInTask(plan.NpcIndex, plan.Slot, plan.DeliveryCount, _npcDataIds.GetValueOrDefault(plan.NpcIndex), plan.ItemId, plan.Collectability));
_taskQueue.Enqueue(new WaitAtEnd.WaitDelay());
}

View file

@ -7,6 +7,7 @@ using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Plugin.Services;
using LLib;
using LLib.GameData;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@ -106,7 +107,11 @@ internal abstract class MiniTaskController<T> : IDisposable
InterruptQueueWithCombat();
return;
}
if (currentTaskExecutor.HasTimedOut(_configuration.Advanced.InteractionTimeoutSeconds))
if (ConditionHelper.IsInCutscene(_condition))
{
currentTaskExecutor.ResetTimeout();
}
else if (currentTaskExecutor.HasTimedOut(_configuration.Advanced.InteractionTimeoutSeconds))
{
_logger.LogWarning("Task {TaskName} timed out after {Timeout}s", currentTask, _configuration.Advanced.InteractionTimeoutSeconds);
if (_condition[ConditionFlag.InCombat])

View file

@ -61,6 +61,11 @@ internal sealed class QuestController : MiniTaskController<QuestController>
}
}
internal void ResetInitialQuestWork(QuestProgressInfo? questWork)
{
InitialQuestWork = questWork;
}
public void SetSequence(byte sequence, int step = 0)
{
Sequence = sequence;
@ -180,6 +185,8 @@ internal sealed class QuestController : MiniTaskController<QuestController>
private QuestProgress? _pendingQuest;
private (ElementId QuestId, QuestProgressInfo QuestWork)? _initialQuestWorkPreservedForReload;
private EAutomationType _automationType;
private bool _commandAfterStopFired;
@ -210,6 +217,10 @@ internal sealed class QuestController : MiniTaskController<QuestController>
private bool _resumeAfterSideTasks;
private bool _resumeAfterDutyExit;
private bool _resumeAfterOccupiedQuestTransition;
private bool _runningDebugTasks;
private const char ClipboardSeparator = ';';
@ -360,6 +371,13 @@ internal sealed class QuestController : MiniTaskController<QuestController>
Dictionary<GatheringPointId, GatheringRoot> gatheringPoints = _gatheringPointRegistry.Build();
_framework.RunOnFrameworkThread(delegate
{
QuestProgress questProgress = CurrentQuestDetails?.Progress;
QuestProgressInfo questProgressInfo = questProgress?.InitialQuestWork;
if (questProgress != null && questProgressInfo == null)
{
questProgressInfo = _questFunctions.GetQuestProgressInfo(questProgress.Quest.Id);
}
_initialQuestWorkPreservedForReload = ((questProgress != null && questProgressInfo != null) ? new(ElementId, QuestProgressInfo)?((questProgress.Quest.Id, questProgressInfo)) : (((ElementId, QuestProgressInfo)?)null));
ResetInternalState();
_gatheringPointRegistry.Publish(gatheringPoints);
_questRegistry.Publish(questSnapshot);
@ -373,6 +391,8 @@ internal sealed class QuestController : MiniTaskController<QuestController>
_pendingQuest = null;
_simulatedQuest = null;
_safeAnimationEnd = 0L;
_resumeAfterDutyExit = false;
_resumeAfterOccupiedQuestTransition = false;
DebugState = null;
}
@ -501,6 +521,28 @@ internal sealed class QuestController : MiniTaskController<QuestController>
DebugState = "Not logged in";
return;
}
if (_resumeAfterDutyExit)
{
if (ConditionHelper.IsBetweenAreas(_condition) || IsInsideDutyInstance())
{
DebugState = "Waiting for duty exit";
return;
}
_resumeAfterDutyExit = false;
CheckNextTasks("Resume after duty exit");
return;
}
if (_resumeAfterOccupiedQuestTransition)
{
if (_gameFunctions.IsOccupied())
{
DebugState = "Waiting for quest transition to finish";
return;
}
_resumeAfterOccupiedQuestTransition = false;
CheckNextTasks("Resume after occupied quest transition");
return;
}
if (_runningDebugTasks)
{
if (!_taskQueue.AllTasksComplete)
@ -638,8 +680,32 @@ internal sealed class QuestController : MiniTaskController<QuestController>
}
else if (questProgress.Sequence != b)
{
if (IsDutyChainActive())
{
DebugState = "Waiting for duty to finish";
return;
}
questProgress.SetSequence(b);
CheckNextTasks($"New sequence {questProgress == _startedQuest}");
QuestProgressInfo questProgressInfo = _questFunctions.GetQuestProgressInfo(questProgress.Quest.Id);
questProgress.ResetInitialQuestWork(questProgressInfo);
_logger.LogDebug("Captured initial quest variables for {QuestId} sequence {Sequence}: {QuestWork}", questProgress.Quest.Id, b, questProgressInfo);
bool flag = _gameFunctions.IsOccupied();
if (flag)
{
EAutomationType automationType = AutomationType;
bool flag2 = (uint)(automationType - 1) <= 2u;
flag = flag2;
}
if (flag)
{
ClearTasksInternal();
_resumeAfterOccupiedQuestTransition = true;
DebugState = "Waiting for quest transition to finish";
}
else
{
CheckNextTasks($"New sequence {questProgress == _startedQuest}");
}
}
else if (questProgress.Step == 255)
{
@ -770,6 +836,25 @@ internal sealed class QuestController : MiniTaskController<QuestController>
return (null, 0);
}
private bool IsInsideDutyInstance()
{
uint territoryType = _clientState.TerritoryType;
if (_territoryData.IsDutyInstance(territoryType))
{
return !_territoryData.IsFieldOperation(territoryType);
}
return false;
}
private bool IsDutyChainActive()
{
if (!(_taskQueue.CurrentTaskExecutor?.CurrentTask is IDutyTask))
{
return _taskQueue.RemainingTasks.Any((ITask x) => x is IDutyTask);
}
return true;
}
private bool IsLevelingModeActive()
{
ITask task = _taskQueue.CurrentTaskExecutor?.CurrentTask;
@ -890,6 +975,8 @@ internal sealed class QuestController : MiniTaskController<QuestController>
_deathCount = 0;
_deathRecoveryPending = false;
_resumeAfterSideTasks = false;
_resumeAfterDutyExit = false;
_resumeAfterOccupiedQuestTransition = false;
SessionConditions.Clear();
_conditionsMetAtStart.Clear();
}
@ -1179,12 +1266,29 @@ internal sealed class QuestController : MiniTaskController<QuestController>
{
return null;
}
questProgress.CaptureInitialQuestWork(_questFunctions.GetQuestProgressInfo(questId));
return questProgress.InitialQuestWork;
}
private QuestProgress CreateQuestProgress(Quest quest, byte sequence = 0, int step = 0)
{
return new QuestProgress(quest, sequence, step, _questFunctions.GetQuestProgressInfo(quest.Id));
(ElementId, QuestProgressInfo)? initialQuestWorkPreservedForReload = _initialQuestWorkPreservedForReload;
QuestProgressInfo questProgressInfo;
if (initialQuestWorkPreservedForReload.HasValue)
{
(ElementId, QuestProgressInfo) valueOrDefault = initialQuestWorkPreservedForReload.GetValueOrDefault();
if (valueOrDefault.Item1.Equals(quest.Id))
{
questProgressInfo = valueOrDefault.Item2;
_initialQuestWorkPreservedForReload = null;
_logger.LogDebug("Restored initial quest variables for {QuestId} after data reload: {QuestWork}", quest.Id, questProgressInfo);
goto IL_0075;
}
}
questProgressInfo = _questFunctions.GetQuestProgressInfo(quest.Id);
goto IL_0075;
IL_0075:
return new QuestProgress(quest, sequence, step, questProgressInfo);
}
private void CaptureInitialQuestWork(QuestProgress? progress, ElementId questId)
@ -1257,8 +1361,9 @@ internal sealed class QuestController : MiniTaskController<QuestController>
return;
}
}
if (questStep != null && questStep.TerritoryId != _clientState.TerritoryType && (_territoryData.IsDutyInstance(_clientState.TerritoryType) || _territoryData.IsQuestBattleInstance(_clientState.TerritoryType)))
if (questStep != null && questStep.TerritoryId != _clientState.TerritoryType && IsInsideDutyInstance())
{
_resumeAfterDutyExit = true;
_logger.LogDebug("Deferring next step: step territory {StepTerritory} != current instance territory {CurrentTerritory}, waiting for duty exit", questStep.TerritoryId, _clientState.TerritoryType);
DebugState = "Waiting for duty exit";
return;

View file

@ -84,7 +84,7 @@ internal sealed class QuestPriorityResolver
{
return QuestResolution.Slot(EQuestResolutionType.Simulated, slots.Simulated, "Simulated quest");
}
if (slots.Next != null)
if (slots.Next != null && !_questFunctions.IsQuestBlacklisted(slots.Next.Quest.Id))
{
return QuestResolution.Slot(EQuestResolutionType.NextQuest, slots.Next, $"Next quest {slots.Next.Quest.Id}");
}
@ -93,7 +93,7 @@ internal sealed class QuestPriorityResolver
private QuestResolution ResolveFromGameState(List<Quest> manualPriorityQuests, QuestController.EAutomationType automationType)
{
bool allowNewMsq = automationType != QuestController.EAutomationType.SingleQuestB;
bool flag = automationType != QuestController.EAutomationType.SingleQuestB;
QuestReference resolvedMsqQuest = GetResolvedMsqQuest();
int num = _objectTable.LocalPlayer?.Level ?? 0;
EClassJob valueOrDefault = ((EClassJob?)_objectTable.LocalPlayer?.ClassJob.RowId).GetValueOrDefault();
@ -103,6 +103,16 @@ internal sealed class QuestPriorityResolver
QuestResolution valueOrDefault2 = questResolution.GetValueOrDefault();
return ApplyQuestRedirects(valueOrDefault2);
}
uint territoryType = _clientState.TerritoryType;
bool flag2 = territoryType - 181 <= 2;
if (flag2 && flag && _configuration.General.MsqPriority != Configuration.EMsqPriorityMode.Manual)
{
ElementId currentQuest = resolvedMsqQuest.CurrentQuest;
if ((object)currentQuest != null && currentQuest.Value > 0 && !_questFunctions.IsQuestAccepted(currentQuest))
{
return QuestResolution.ForQuest(EQuestResolutionType.MsqImmediate, currentQuest, resolvedMsqQuest.Sequence, resolvedMsqQuest.State, $"Starting city opening MSQ {currentQuest}");
}
}
questResolution = TryResolveInProgressClassQuest(valueOrDefault, resolvedMsqQuest.State);
if (questResolution.HasValue)
{
@ -130,7 +140,7 @@ internal sealed class QuestPriorityResolver
_lastLoggedPriorityClassQuest = null;
_loggedNoClassQuestsAvailable = false;
_loggedAdventurerClass = false;
questResolution = TryResolveMsqImmediate(resolvedMsqQuest, allowNewMsq);
questResolution = TryResolveMsqImmediate(resolvedMsqQuest, flag);
if (questResolution.HasValue)
{
return questResolution.GetValueOrDefault();
@ -147,7 +157,7 @@ internal sealed class QuestPriorityResolver
QuestResolution valueOrDefault4 = questResolution.GetValueOrDefault();
return ApplyQuestRedirects(valueOrDefault4);
}
questResolution = TryResolveMsqFallback(resolvedMsqQuest, allowNewMsq);
questResolution = TryResolveMsqFallback(resolvedMsqQuest, flag);
if (questResolution.HasValue)
{
return questResolution.GetValueOrDefault();
@ -259,8 +269,14 @@ internal sealed class QuestPriorityResolver
{
return null;
}
(ElementId, byte) tuple = (from x in manualPriorityQuests
where _questFunctions.IsQuestAccepted(x.Id) ? ((!_configuration.Advanced.AutoPrioritizeAlliedSocietyRankUp || !(x.Id is QuestId questId) || !_questFunctions.WouldOvercapAlliedSocietyReputation(questId)) ? true : false) : _questFunctions.IsReadyToAcceptQuest(x.Id)
(ElementId, byte) tuple = (from x in manualPriorityQuests.Where(delegate(Quest x)
{
if (_questFunctions.IsQuestBlacklisted(x.Id))
{
return false;
}
return _questFunctions.IsQuestAccepted(x.Id) ? ((!_configuration.Advanced.AutoPrioritizeAlliedSocietyRankUp || !(x.Id is QuestId questId) || !_questFunctions.WouldOvercapAlliedSocietyReputation(questId)) ? true : false) : _questFunctions.IsReadyToAcceptQuest(x.Id);
})
select (QuestId: x.Id, Sequence: _questFunctions.GetQuestProgressInfo(x.Id)?.Sequence ?? 0)).FirstOrDefault();
if ((object)tuple.Item1 != null)
{
@ -271,12 +287,12 @@ internal sealed class QuestPriorityResolver
private QuestResolution? TryResolveInProgressClassQuest(EClassJob currentClassJob, MainScenarioQuestState msqState)
{
if (currentClassJob == EClassJob.Adventurer)
if (_configuration.Advanced.SkipClassJobQuests || currentClassJob == EClassJob.Adventurer)
{
return null;
}
QuestInfo questInfo = (from x in _questData.GetClassJobQuests(currentClassJob)
where (x.Level <= 5 || !_configuration.Advanced.SkipClassJobQuests) && _questFunctions.IsQuestAccepted(x.QuestId) && !_questFunctions.IsQuestComplete(x.QuestId)
where !_questFunctions.IsQuestBlacklisted(x.QuestId) && _questFunctions.IsQuestAccepted(x.QuestId) && !_questFunctions.IsQuestComplete(x.QuestId)
orderby x.Level
select x).FirstOrDefault();
if (questInfo == null)
@ -422,10 +438,14 @@ internal sealed class QuestPriorityResolver
{
case 1:
{
ElementId elementId = new QuestId(ptr->NormalQuests[trackingWork.Index].QuestId);
if (_questRegistry.IsKnownQuest(elementId) && !_questFunctions.IsQuestBlacklisted(elementId))
QuestWork questWork = ptr->NormalQuests[trackingWork.Index];
if (!questWork.IsHidden)
{
list.Add((elementId, QuestManager.GetQuestSequence(elementId.Value)));
ElementId elementId = new QuestId(questWork.QuestId);
if (_questRegistry.IsKnownQuest(elementId) && !_questFunctions.IsQuestBlacklisted(elementId))
{
list.Add((elementId, QuestManager.GetQuestSequence(elementId.Value)));
}
}
break;
}