using Microsoft.Extensions.Logging; using Questionable.Functions; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Controller.Steps.Common; internal static class NextQuest { internal sealed class Factory(QuestFunctions questFunctions) : SimpleTaskFactory() { public override ITask? CreateTask(Quest quest, QuestSequence sequence, QuestStep step) { if (step.InteractionType != EInteractionType.CompleteQuest) { return null; } if (step.NextQuestId == null) { return null; } if (step.NextQuestId == quest.Id) { return null; } if (questFunctions.GetPriorityQuests(onlyClassAndRoleQuests: true).Contains(step.NextQuestId)) { return null; } return new SetQuestTask(step.NextQuestId, quest.Id); } } internal sealed record SetQuestTask(ElementId NextQuestId, ElementId CurrentQuestId) : ITask { public bool ShouldRedoOnInterrupt() { return true; } public override string ToString() { return $"SetNextQuest({NextQuestId})"; } } internal sealed class NextQuestExecutor(QuestRegistry questRegistry, QuestController questController, QuestFunctions questFunctions, ILogger logger) : TaskExecutor() { protected override bool Start() { QuestController.EAutomationType automationType = questController.AutomationType; Quest quest; if ((uint)(automationType - 3) <= 1u) { logger.LogInformation("Won't set next quest to {QuestId}, automation type is CurrentQuestOnly", base.Task.NextQuestId); questController.SetNextQuest(null); } else if (questFunctions.IsQuestLocked(base.Task.NextQuestId, base.Task.CurrentQuestId)) { logger.LogInformation("Can't set next quest to {QuestId}, quest is locked", base.Task.NextQuestId); questController.SetNextQuest(null); } else if (questRegistry.TryGetQuest(base.Task.NextQuestId, out quest)) { logger.LogInformation("Setting next quest to {QuestId}: '{QuestName}'", base.Task.NextQuestId, quest.Info.Name); questController.SetNextQuest(quest); } else { logger.LogInformation("Next quest with id {QuestId} not found", base.Task.NextQuestId); questController.SetNextQuest(null); } return true; } public override ETaskResult Update() { return ETaskResult.TaskComplete; } public override bool ShouldInterruptOnDamage() { return false; } } }