1
0
Fork 0
forked from aly/qstbak
qstbak/Questionable/Questionable.Functions/AetheryteFunctions.cs
2026-08-17 20:29:32 +10:00

142 lines
4.5 KiB
C#

using System;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using LLib.GameData;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Questionable.Model.Questing;
using SmartNav.Model;
namespace Questionable.Functions;
internal sealed class AetheryteFunctions
{
private const uint TeleportAction = 5u;
private const uint ReturnAction = 6u;
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<AetheryteFunctions> _logger;
private readonly IDataManager _dataManager;
private readonly IObjectTable _objectTable;
public long ReturnRequestedAt { get; set; }
public AetheryteFunctions(IServiceProvider serviceProvider, ILogger<AetheryteFunctions> logger, IDataManager dataManager, IObjectTable objectTable)
{
_serviceProvider = serviceProvider;
_logger = logger;
_dataManager = dataManager;
_objectTable = objectTable;
}
public unsafe bool IsAetheryteUnlocked(uint aetheryteId, out byte subIndex)
{
subIndex = 0;
UIState* ptr = UIState.Instance();
if (ptr != null)
{
return ptr->IsAetheryteUnlocked(aetheryteId);
}
return false;
}
public bool IsAetheryteUnlocked(EAetheryteLocation aetheryteLocation)
{
if (aetheryteLocation.IsFirmamentAetheryte())
{
return _serviceProvider.GetRequiredService<QuestFunctions>().IsQuestComplete(new QuestId(3672));
}
byte subIndex;
return IsAetheryteUnlocked((uint)aetheryteLocation, out subIndex);
}
public unsafe bool CanTeleport(EAetheryteLocation aetheryteLocation)
{
if ((ushort)aetheryteLocation == PlayerStateHelper.GetHomeAetheryteId() && ActionManager.Instance()->GetActionStatus(ActionType.Action, 6u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0)
{
return true;
}
return ActionManager.Instance()->GetActionStatus(ActionType.Action, 5u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0;
}
public unsafe bool IsTeleportUnlocked()
{
uint rowId = _dataManager.GetExcelSheet<Lumina.Excel.Sheets.Action>().GetRow(5u).UnlockLink.RowId;
UIState* ptr = UIState.Instance();
if (ptr != null)
{
return ptr->IsUnlockLinkUnlocked(rowId);
}
return false;
}
public unsafe bool IsReturnAvailable()
{
return ActionManager.Instance()->GetActionStatus(ActionType.Action, 6u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0;
}
public unsafe bool TeleportAetheryte(uint aetheryteId)
{
_logger.LogDebug("Attempting to teleport to aetheryte {AetheryteId}", aetheryteId);
if (IsAetheryteUnlocked(aetheryteId, out var subIndex))
{
if (aetheryteId == PlayerStateHelper.GetHomeAetheryteId() && ActionManager.Instance()->GetActionStatus(ActionType.Action, 6u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0)
{
ReturnRequestedAt = Environment.TickCount64;
if (ActionManager.Instance()->UseAction(ActionType.Action, 6u, 3758096384uL, 0u, ActionManager.UseActionMode.None, 0u, null))
{
_logger.LogInformation("Using 'return' for home aetheryte");
return true;
}
}
if (ActionManager.Instance()->GetActionStatus(ActionType.Action, 5u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0)
{
_logger.LogInformation("Teleporting to aetheryte {AetheryteId}", aetheryteId);
return Telepo.Instance()->Teleport(aetheryteId, subIndex);
}
}
return false;
}
public bool TeleportAetheryte(EAetheryteLocation aetheryteLocation)
{
return TeleportAetheryte((uint)aetheryteLocation);
}
public static bool IsFreeAetheryte(EAetheryteLocation aetheryteLocation)
{
return PlayerStateHelper.IsFreeAetheryte((uint)aetheryteLocation);
}
public AetheryteRegistrationResult CanRegisterFreeOrFavoriteAetheryte(EAetheryteLocation aetheryteLocation)
{
if (_objectTable[0] == null)
{
return AetheryteRegistrationResult.NotPossible;
}
if (IsFreeAetheryte(aetheryteLocation))
{
return AetheryteRegistrationResult.NotPossible;
}
if (PlayerStateHelper.IsFavouriteAetheryte((uint)aetheryteLocation))
{
return AetheryteRegistrationResult.NotPossible;
}
bool flag = PlayerStateHelper.HasFavouriteSlotAvailable();
if (PlayerStateHelper.IsPlayerStateFlagSet(PlayerStateFlag.IsLoginSecurityToken) && PlayerStateHelper.GetFreeAetheryteId() == 0)
{
return AetheryteRegistrationResult.SecurityTokenFreeDestinationAvailable;
}
if (!flag)
{
return AetheryteRegistrationResult.NotPossible;
}
return AetheryteRegistrationResult.FavoredDestinationAvailable;
}
}