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 _logger; private readonly IDataManager _dataManager; private readonly IObjectTable _objectTable; public long ReturnRequestedAt { get; set; } public AetheryteFunctions(IServiceProvider serviceProvider, ILogger 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().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().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; } }