Fixes for early limsa quests

This commit is contained in:
Liza 2024-08-22 12:14:12 +02:00
parent ee2980bef9
commit 6ea9f282f3
Signed by: liza
GPG Key ID: 7199F8D727D55F67
6 changed files with 37 additions and 10 deletions

View File

@ -44,6 +44,8 @@ internal static class QuestStepExtensions
Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart, Assignment(nameof(QuestStep.DelaySecondsAtStart), step.DelaySecondsAtStart,
emptyStep.DelaySecondsAtStart) emptyStep.DelaySecondsAtStart)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.PickUpItemId), step.PickUpItemId, emptyStep.PickUpItemId)
.AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled) Assignment(nameof(QuestStep.Disabled), step.Disabled, emptyStep.Disabled)
.AsSyntaxNodeOrToken(), .AsSyntaxNodeOrToken(),
Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh, Assignment(nameof(QuestStep.DisableNavmesh), step.DisableNavmesh,

View File

@ -29,7 +29,8 @@
}, },
"TerritoryId": 134, "TerritoryId": 134,
"InteractionType": "Interact", "InteractionType": "Interact",
"Comment": "Technically triggers combat, but can be ignored" "Comment": "Technically triggers combat, but can be ignored",
"PickUpItemId": 2000342
} }
] ]
}, },

View File

@ -59,6 +59,7 @@
"StopDistance": 5, "StopDistance": 5,
"TerritoryId": 134, "TerritoryId": 134,
"InteractionType": "Interact", "InteractionType": "Interact",
"DelaySecondsAtStart": 3,
"DialogueChoices": [ "DialogueChoices": [
{ {
"Type": "List", "Type": "List",

View File

@ -440,6 +440,11 @@
} }
}, },
"then": { "then": {
"properties": {
"PickUpItemId": {
"type": "number"
}
},
"required": [ "required": [
"DataId" "DataId"
] ]

View File

@ -27,6 +27,7 @@ public sealed class QuestStep
public float? NpcWaitDistance { get; set; } public float? NpcWaitDistance { get; set; }
public ushort? TargetTerritoryId { get; set; } public ushort? TargetTerritoryId { get; set; }
public float? DelaySecondsAtStart { get; set; } public float? DelaySecondsAtStart { get; set; }
public uint? PickUpItemId { get; set; }
public bool Disabled { get; set; } public bool Disabled { get; set; }
public bool DisableNavmesh { get; set; } public bool DisableNavmesh { get; set; }

View File

@ -4,6 +4,7 @@ using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects.Enums; using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Questionable.Controller.Steps.Shared; using Questionable.Controller.Steps.Shared;
@ -15,7 +16,8 @@ namespace Questionable.Controller.Steps.Interactions;
internal static class Interact internal static class Interact
{ {
internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory) : ITaskFactory internal sealed class Factory(GameFunctions gameFunctions, ICondition condition, ILoggerFactory loggerFactory)
: ITaskFactory
{ {
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step) public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{ {
@ -39,13 +41,14 @@ internal static class Interact
yield return new WaitAtEnd.WaitDelay(); yield return new WaitAtEnd.WaitDelay();
yield return Interact(step.DataId.Value, quest, step.InteractionType, yield return Interact(step.DataId.Value, quest, step.InteractionType,
step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId); step.TargetTerritoryId != null || quest.Id is SatisfactionSupplyNpcId, step.PickUpItemId);
} }
internal ITask Interact(uint dataId, Quest? quest, EInteractionType interactionType, bool skipMarkerCheck = false) internal ITask Interact(uint dataId, Quest? quest, EInteractionType interactionType,
bool skipMarkerCheck = false, uint? pickUpItemId = null)
{ {
return new DoInteract(dataId, quest, interactionType, skipMarkerCheck, gameFunctions, condition, return new DoInteract(dataId, quest, interactionType, skipMarkerCheck, pickUpItemId, gameFunctions,
loggerFactory.CreateLogger<DoInteract>()); condition, loggerFactory.CreateLogger<DoInteract>());
} }
} }
@ -54,6 +57,7 @@ internal static class Interact
Quest? quest, Quest? quest,
EInteractionType interactionType, EInteractionType interactionType,
bool skipMarkerCheck, bool skipMarkerCheck,
uint? pickUpItemId,
GameFunctions gameFunctions, GameFunctions gameFunctions,
ICondition condition, ICondition condition,
ILogger<DoInteract> logger) ILogger<DoInteract> logger)
@ -64,6 +68,7 @@ internal static class Interact
private DateTime _continueAt = DateTime.MinValue; private DateTime _continueAt = DateTime.MinValue;
public Quest? Quest => quest; public Quest? Quest => quest;
public EInteractionType InteractionType public EInteractionType InteractionType
{ {
get => interactionType; get => interactionType;
@ -119,11 +124,23 @@ internal static class Interact
_needsUnmount = false; _needsUnmount = false;
} }
if (_interactionState == EInteractionState.InteractionConfirmed) if (pickUpItemId != null)
return ETaskResult.TaskComplete; {
unsafe
{
InventoryManager* inventoryManager = InventoryManager.Instance();
if (inventoryManager->GetInventoryItemCount(pickUpItemId.Value) > 0)
return ETaskResult.TaskComplete;
}
}
else
{
if (_interactionState == EInteractionState.InteractionConfirmed)
return ETaskResult.TaskComplete;
if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering]) if (interactionType == EInteractionType.InternalGather && condition[ConditionFlag.Gathering])
return ETaskResult.TaskComplete; return ETaskResult.TaskComplete;
}
IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId); IGameObject? gameObject = gameFunctions.FindObjectByDataId(dataId);
if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject)) if (gameObject == null || !gameObject.IsTargetable || !HasAnyMarker(gameObject))