_configuration = configuration;
_yesAlreadyIpc = yesAlreadyIpc;
_taskFactories = taskFactories.ToList().AsReadOnly();
+
+ _condition.ConditionChange += OnConditionChange;
}
public (QuestProgress Progress, ECurrentQuestType Type)? CurrentQuestDetails
return IsRunning || DateTime.Now <= _lastTaskUpdate.Add(timeSpan);
}
+ private void OnConditionChange(ConditionFlag flag, bool value)
+ {
+ if (_currentTask is IConditionChangeAware conditionChangeAware)
+ conditionChangeAware.OnConditionChange(flag, value);
+ }
+
public sealed record StepProgress(
DateTime StartedAt,
int PointMenuCounter = 0);
--- /dev/null
+using Dalamud.Game.ClientState.Conditions;
+
+namespace Questionable.Controller.Steps;
+
+public interface IConditionChangeAware
+{
+ void OnConditionChange(ConditionFlag flag, bool value);
+}
}
internal sealed class DoInteract(GameFunctions gameFunctions, ICondition condition, ILogger<DoInteract> logger)
- : ITask
+ : ITask, IConditionChangeAware
{
private bool _needsUnmount;
- private bool _interacted;
+ private EInteractionState _interactionState = EInteractionState.None;
private DateTime _continueAt = DateTime.MinValue;
private uint DataId { get; set; }
return true;
}
- if (IsTargetable(gameObject) && HasAnyMarker(gameObject))
+ if (gameObject.IsTargetable && HasAnyMarker(gameObject))
{
- _interacted = gameFunctions.InteractWith(gameObject);
+ _interactionState = gameFunctions.InteractWith(gameObject)
+ ? EInteractionState.InteractionTriggered
+ : EInteractionState.None;
_continueAt = DateTime.Now.AddSeconds(0.5);
return true;
}
_needsUnmount = false;
}
- if (!_interacted)
- {
- IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
- if (gameObject == null || !IsTargetable(gameObject) || !HasAnyMarker(gameObject))
- return ETaskResult.StillRunning;
+ if (_interactionState == EInteractionState.InteractionConfirmed)
+ return ETaskResult.TaskComplete;
- _interacted = gameFunctions.InteractWith(gameObject);
- _continueAt = DateTime.Now.AddSeconds(0.5);
+ IGameObject? gameObject = gameFunctions.FindObjectByDataId(DataId);
+ if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject))
return ETaskResult.StillRunning;
- }
- return ETaskResult.TaskComplete;
+ _interactionState = gameFunctions.InteractWith(gameObject)
+ ? EInteractionState.InteractionTriggered
+ : EInteractionState.None;
+ _continueAt = DateTime.Now.AddSeconds(0.5);
+ return ETaskResult.StillRunning;
}
private unsafe bool HasAnyMarker(IGameObject gameObject)
return gameObjectStruct->NamePlateIconId != 0;
}
- private static bool IsTargetable(IGameObject gameObject)
+ public override string ToString() => $"Interact({DataId})";
+
+ public void OnConditionChange(ConditionFlag flag, bool value)
{
- return gameObject.IsTargetable;
+ logger.LogDebug("Condition change: {Flag} = {Value}", flag, value);
+ if (_interactionState == EInteractionState.InteractionTriggered &&
+ flag == ConditionFlag.OccupiedInQuestEvent && value)
+ {
+ logger.LogInformation("Interaction was most likely triggered");
+ _interactionState = EInteractionState.InteractionConfirmed;
+ }
}
- public override string ToString() => $"Interact({DataId})";
+ private enum EInteractionState
+ {
+ None,
+ InteractionTriggered,
+ InteractionConfirmed,
+ }
}
}
using System;
+using Dalamud.Game.Gui.Toast;
+using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
+using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Windows;
private readonly WindowSystem _windowSystem;
private readonly QuestWindow _questWindow;
private readonly ConfigWindow _configWindow;
+ private readonly IToastGui _toastGui;
+ private readonly ILogger<DalamudInitializer> _logger;
public DalamudInitializer(
IDalamudPluginInterface pluginInterface,
ConfigWindow configWindow,
QuestSelectionWindow questSelectionWindow,
QuestValidationWindow questValidationWindow,
- JournalProgressWindow journalProgressWindow)
+ JournalProgressWindow journalProgressWindow,
+ IToastGui toastGui,
+ ILogger<DalamudInitializer> logger)
{
_pluginInterface = pluginInterface;
_framework = framework;
_windowSystem = windowSystem;
_questWindow = questWindow;
_configWindow = configWindow;
+ _toastGui = toastGui;
+ _logger = logger;
_windowSystem.AddWindow(questWindow);
_windowSystem.AddWindow(configWindow);
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
_framework.Update += FrameworkUpdate;
_framework.RunOnTick(gameUiController.HandleCurrentDialogueChoices, TimeSpan.FromMilliseconds(200));
+ _toastGui.Toast += OnToast;
+ _toastGui.ErrorToast += OnErrorToast;
+ _toastGui.QuestToast += OnQuestToast;
}
private void FrameworkUpdate(IFramework framework)
}
}
+ private void OnToast(ref SeString message, ref ToastOptions options, ref bool isHandled)
+ => _logger.LogInformation("Normal Toast: {Message}", message);
+
+ private void OnErrorToast(ref SeString message, ref bool isHandled)
+ => _logger.LogInformation("Error Toast: {Message}", message);
+
+ private void OnQuestToast(ref SeString message, ref QuestToastOptions options, ref bool isHandled)
+ => _logger.LogInformation("Quest Toast: {Message}", message);
+
public void Dispose()
{
+ _toastGui.QuestToast -= OnQuestToast;
+ _toastGui.ErrorToast -= OnErrorToast;
+ _toastGui.Toast -= OnToast;
_framework.Update -= FrameworkUpdate;
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;
_pluginInterface.UiBuilder.OpenMainUi -= _questWindow.Toggle;
ICommandManager commandManager,
IAddonLifecycle addonLifecycle,
IKeyState keyState,
- IContextMenu contextMenu)
+ IContextMenu contextMenu,
+ IToastGui toastGui)
{
ArgumentNullException.ThrowIfNull(pluginInterface);
ArgumentNullException.ThrowIfNull(chatGui);
serviceCollection.AddSingleton(addonLifecycle);
serviceCollection.AddSingleton(keyState);
serviceCollection.AddSingleton(contextMenu);
+ serviceCollection.AddSingleton(toastGui);
serviceCollection.AddSingleton(new WindowSystem(nameof(Questionable)));
serviceCollection.AddSingleton((Configuration?)pluginInterface.GetPluginConfig() ?? new Configuration());