100 lines
2.4 KiB
C#
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);
|
|
}
|
|
}
|