qstbak/LLib/LLib.GameData/TeleportHelper.cs
2026-08-17 20:29:32 +10:00

100 lines
2.4 KiB
C#

using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.Logging;
namespace LLib.GameData;
public sealed class TeleportHelper
{
private const uint TeleportAction = 5u;
private readonly GameStateHelper _gameState;
private readonly ILogger<TeleportHelper> _logger;
private readonly uint _teleportUnlockLink;
public TeleportHelper(IDataManager dataManager, GameStateHelper gameState, ILogger<TeleportHelper> logger)
{
_gameState = gameState;
_logger = logger;
_teleportUnlockLink = dataManager.GetExcelSheet<Action>().GetRow(5u).UnlockLink.RowId;
}
public unsafe bool IsAetheryteUnlocked(uint aetheryteId)
{
UIState* ptr = UIState.Instance();
if (ptr != null)
{
return ptr->IsAetheryteUnlocked(aetheryteId);
}
return false;
}
public unsafe bool CanTeleport()
{
ActionManager* ptr = ActionManager.Instance();
if (ptr != null)
{
return ptr->GetActionStatus(ActionType.Action, 5u, 3758096384uL, checkRecastActive: true, checkCastingActive: true, null) == 0;
}
return false;
}
public unsafe bool IsTeleportUnlocked()
{
UIState* ptr = UIState.Instance();
if (ptr != null)
{
return ptr->IsUnlockLinkUnlocked(_teleportUnlockLink);
}
return false;
}
public unsafe bool IsFreeAetheryte(uint aetheryteId)
{
PlayerState* ptr = PlayerState.Instance();
if (ptr != null)
{
if (ptr->FreeAetheryteId != aetheryteId && ptr->FreeAetherytePSPlus != aetheryteId)
{
return ptr->FreeAetheryteNSO == aetheryteId;
}
return true;
}
return false;
}
public unsafe bool Teleport(uint aetheryteId, byte subIndex = 0)
{
if (!IsTeleportUnlocked())
{
_logger.LogWarning("Teleport action is not unlocked; skipping teleport to {Id}", aetheryteId);
return false;
}
if (!CanTeleport())
{
_logger.LogDebug("Teleport to {Id} blocked: action on cooldown", aetheryteId);
return false;
}
if (!IsAetheryteUnlocked(aetheryteId))
{
_logger.LogWarning("Aetheryte {Id} is not unlocked; skipping teleport", aetheryteId);
return false;
}
if (_gameState.IsLoadingScreenVisible())
{
_logger.LogDebug("Skipping teleport to {Id}: loading screen visible", aetheryteId);
return false;
}
Telepo* ptr = Telepo.Instance();
if (ptr == null)
{
return false;
}
_logger.LogInformation("Teleporting to aetheryte {Id}", aetheryteId);
return ptr->Teleport(aetheryteId, subIndex);
}
}