muffin v7.4.18

This commit is contained in:
alydev 2026-03-26 14:56:12 +10:00
parent 53aa9fdee8
commit f82b9ce2a2
50 changed files with 142364 additions and 230361 deletions

View file

@ -87,9 +87,7 @@ internal sealed class MoveExecutor : TaskExecutor<MoveTask>, IToastAware, ITaskE
int num = 1;
List<Vector3> list = new List<Vector3>(num);
CollectionsMarshal.SetCount(list, num);
Span<Vector3> span = CollectionsMarshal.AsSpan(list);
int index = 0;
span[index] = _destination;
CollectionsMarshal.AsSpan(list)[0] = _destination;
movementController.NavigateTo(EMovementType.Quest, dataId, list, base.Task.Fly, base.Task.Sprint ?? (!_mountDuringMovement.HasValue), base.Task.StopDistance, base.Task.IgnoreDistanceToObject ? new float?(float.MaxValue) : ((float?)null), base.Task.Land);
};
}

View file

@ -18,6 +18,10 @@ internal static class MoveTo
{
public IEnumerable<ITask> CreateAllTasks(Quest quest, QuestSequence sequence, QuestStep step)
{
if (step.DataIds.Count > 0)
{
return Array.Empty<ITask>();
}
if (step.Position.HasValue)
{
return CreateMoveTasks(step, step.Position.Value);
@ -26,6 +30,10 @@ internal static class MoveTo
{
return new global::_003C_003Ez__ReadOnlySingleElementList<ITask>(new WaitForNearDataId(step.DataId.Value, step.StopDistance.Value));
}
if (step != null && step.DataId.HasValue && !step.Position.HasValue)
{
return CreateMoveToObjectTasks(step);
}
EAetheryteLocation valueOrDefault = default(EAetheryteLocation);
bool flag;
if (step != null)
@ -38,13 +46,13 @@ internal static class MoveTo
{
valueOrDefault = aetheryte.GetValueOrDefault();
flag = true;
goto IL_00a3;
goto IL_00e2;
}
}
}
flag = false;
goto IL_00a3;
IL_00a3:
goto IL_00e2;
IL_00e2:
if (flag)
{
return CreateMoveTasks(step, aetheryteData.Locations[valueOrDefault]);
@ -61,6 +69,16 @@ internal static class MoveTo
return Array.Empty<ITask>();
}
private IEnumerable<ITask> CreateMoveToObjectTasks(QuestStep step)
{
yield return new WaitCondition.Task(() => clientState.TerritoryType == step.TerritoryId, "Wait(territory: " + territoryData.GetNameAndId(step.TerritoryId) + ")");
if (!step.DisableNavmesh)
{
yield return new WaitNavmesh.Task();
}
yield return new MoveToObject(step);
}
private IEnumerable<ITask> CreateMoveTasks(QuestStep step, Vector3 destination)
{
IGameObject gameObject = objectTable[0];

View file

@ -0,0 +1,16 @@
using Questionable.Model.Questing;
namespace Questionable.Controller.Steps.Movement;
internal sealed record MoveToObject(QuestStep Step) : ITask
{
public bool ShouldRedoOnInterrupt()
{
return true;
}
public override string ToString()
{
return $"MoveToObject({Step.DataId})";
}
}

View file

@ -0,0 +1,127 @@
using System;
using System.Numerics;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using Microsoft.Extensions.Logging;
using Questionable.Functions;
using Questionable.Model;
namespace Questionable.Controller.Steps.Movement;
internal sealed class MoveToObjectExecutor(MovementController movementController, GameFunctions gameFunctions, IClientState clientState, IObjectTable objectTable, ILogger<MoveToObjectExecutor> logger) : TaskExecutor<MoveToObject>()
{
private DateTime _startedLookingAt = DateTime.MaxValue;
private Vector3 _destination;
private bool _moving;
protected override bool Start()
{
if (!base.Task.Step.DataId.HasValue)
{
logger.LogWarning("MoveToObject task has no DataId");
return false;
}
if (clientState.TerritoryType != base.Task.Step.TerritoryId)
{
logger.LogInformation("Not in correct territory yet, waiting");
return true;
}
_startedLookingAt = DateTime.Now;
return TryStartMovement();
}
private IGameObject? FindDistantObjectByDataId(uint dataId)
{
IGameObject gameObject = objectTable[0];
if (gameObject == null)
{
return null;
}
float num = base.Task.Step.CalculateActualStopDistance();
IGameObject result = null;
float num2 = float.MaxValue;
foreach (IGameObject item in objectTable)
{
ObjectKind objectKind = item.ObjectKind;
bool flag = ((objectKind == ObjectKind.Player || objectKind - 8 <= ObjectKind.BattleNpc || objectKind == ObjectKind.Housing) ? true : false);
if (!flag && item.BaseId == dataId)
{
float num3 = Vector3.Distance(gameObject.Position, item.Position);
if (!(num3 <= num) && num3 < num2)
{
result = item;
num2 = num3;
}
}
}
return result;
}
private bool TryStartMovement()
{
IGameObject gameObject = FindDistantObjectByDataId(base.Task.Step.DataId.Value);
if (gameObject == null)
{
gameObject = gameFunctions.FindObjectByDataId(base.Task.Step.DataId.Value, null, warnIfMissing: false);
if (gameObject == null)
{
logger.LogInformation("Object {DataId} not found yet, waiting", base.Task.Step.DataId);
return true;
}
IGameObject gameObject2 = objectTable[0];
float num = base.Task.Step.CalculateActualStopDistance();
if (gameObject2 != null && Vector3.Distance(gameObject2.Position, gameObject.Position) <= num)
{
logger.LogInformation("Only nearby objects with DataId {DataId} remain, skipping", base.Task.Step.DataId);
return true;
}
}
_destination = gameObject.Position;
logger.LogInformation("Moving to object {DataId} at {Position}", base.Task.Step.DataId, _destination);
movementController.NavigateTo(EMovementType.Quest, base.Task.Step.DataId, _destination, fly: false, base.Task.Step.Sprint ?? true, base.Task.Step.CalculateActualStopDistance());
_moving = true;
return true;
}
public override ETaskResult Update()
{
if (clientState.TerritoryType != base.Task.Step.TerritoryId)
{
return ETaskResult.StillRunning;
}
if (!_moving)
{
if (_startedLookingAt != DateTime.MaxValue && DateTime.Now > _startedLookingAt.AddSeconds(3.0))
{
logger.LogInformation("Object {DataId} not found after timeout, skipping step", base.Task.Step.DataId);
return ETaskResult.TaskComplete;
}
if (!TryStartMovement())
{
return ETaskResult.TaskComplete;
}
if (!_moving)
{
return ETaskResult.StillRunning;
}
}
if (movementController.IsPathfinding || movementController.IsPathRunning)
{
return ETaskResult.StillRunning;
}
DateTime movementStartedAt = movementController.MovementStartedAt;
if (movementStartedAt == DateTime.MaxValue || movementStartedAt.AddSeconds(2.0) >= DateTime.Now)
{
return ETaskResult.StillRunning;
}
return ETaskResult.TaskComplete;
}
public override bool ShouldInterruptOnDamage()
{
return false;
}
}