216 lines
5.3 KiB
C#
216 lines
5.3 KiB
C#
using System;
|
|
using Dalamud.Plugin.Services;
|
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
|
using FFXIVClientStructs.Interop;
|
|
using LLib.GameUI;
|
|
|
|
namespace LLib.Shop;
|
|
|
|
public static class SatisfactionSupplyActions
|
|
{
|
|
public readonly record struct NpcState(int Rank, int SatisfactionCurrent, int SatisfactionMax, int UsedDeliveries);
|
|
|
|
private const string SatisfactionSupplyAddon = "SatisfactionSupply";
|
|
|
|
private const string SatisfactionSupplyResultAddon = "SatisfactionSupplyResult";
|
|
|
|
private const string TalkAddon = "Talk";
|
|
|
|
public unsafe static bool IsSatisfactionSupplyReady(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("SatisfactionSupply", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
return LAddon.IsAddonReady(addonPtr);
|
|
}
|
|
|
|
public unsafe static bool IsSatisfactionSupplyFullyReady(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("SatisfactionSupply", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
if (!LAddon.IsAddonReady(addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
AgentSatisfactionSupply* ptr = AgentSatisfactionSupply.Instance();
|
|
if (ptr != null && ptr->IsAgentActive() && ptr->NpcInfo.Valid)
|
|
{
|
|
return ptr->NpcInfo.Initialized;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public unsafe static bool TrySelectDeliverySlot(IGameGui gameGui, int slot)
|
|
{
|
|
if (!IsSatisfactionSupplyFullyReady(gameGui))
|
|
{
|
|
return false;
|
|
}
|
|
AgentSatisfactionSupply* ptr = AgentSatisfactionSupply.Instance();
|
|
AtkValue atkValue = new AtkValue();
|
|
Span<AtkValue> span = stackalloc AtkValue[2];
|
|
span[0].SetInt(1);
|
|
span[1].SetInt(slot);
|
|
ptr->ReceiveEvent(&atkValue, span.GetPointer(0), 2u, 0uL);
|
|
return true;
|
|
}
|
|
|
|
public unsafe static bool TryCloseSatisfactionSupply(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("SatisfactionSupply", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
addonPtr->FireCallbackInt(0);
|
|
return true;
|
|
}
|
|
|
|
public unsafe static bool IsTalkInProgress(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("Talk", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
if (addonPtr->IsVisible)
|
|
{
|
|
return LAddon.IsAddonReady(addonPtr);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public unsafe static bool TryProgressTalk(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("Talk", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
if (!addonPtr->IsVisible || !LAddon.IsAddonReady(addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
addonPtr->FireCallbackInt(0);
|
|
return true;
|
|
}
|
|
|
|
public unsafe static bool IsSatisfactionSupplyResultVisible(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("SatisfactionSupplyResult", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
return LAddon.IsAddonReady(addonPtr);
|
|
}
|
|
|
|
public unsafe static bool TryCloseSatisfactionSupplyResult(IGameGui gameGui)
|
|
{
|
|
if (!gameGui.TryGetAddonByName<AtkUnitBase>("SatisfactionSupplyResult", out var addonPtr))
|
|
{
|
|
return false;
|
|
}
|
|
addonPtr->Close(fireCallback: true);
|
|
return true;
|
|
}
|
|
|
|
public unsafe static bool IsNpcTradeReady()
|
|
{
|
|
AgentNpcTrade* ptr = AgentNpcTrade.Instance();
|
|
if (ptr != null)
|
|
{
|
|
return ptr->IsAgentActive();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public unsafe static (bool Exists, bool Active, int SelectedSlot) GetNpcTradeState()
|
|
{
|
|
AgentNpcTrade* ptr = AgentNpcTrade.Instance();
|
|
if (ptr == null)
|
|
{
|
|
return (Exists: false, Active: false, SelectedSlot: -99);
|
|
}
|
|
return (Exists: true, Active: ptr->IsAgentActive(), SelectedSlot: ptr->SelectedTurnInSlot);
|
|
}
|
|
|
|
public unsafe static bool TryConfirmTrade()
|
|
{
|
|
AgentNpcTrade* ptr = AgentNpcTrade.Instance();
|
|
if (ptr == null || !ptr->IsAgentActive())
|
|
{
|
|
return false;
|
|
}
|
|
AtkValue atkValue = new AtkValue();
|
|
Span<AtkValue> span = stackalloc AtkValue[4];
|
|
if (ptr->SelectedTurnInSlot < 0)
|
|
{
|
|
span[0].SetInt(2);
|
|
span[1].SetInt(0);
|
|
span[2].SetInt(0);
|
|
span[3].SetInt(0);
|
|
ptr->ReceiveEvent(&atkValue, span.GetPointer(0), 4u, 0uL);
|
|
if (ptr->SelectedTurnInSlot != 0 || ptr->SelectedTurnInSlotItemOptions <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else if (ptr->SelectedTurnInSlot != 0)
|
|
{
|
|
return false;
|
|
}
|
|
span[0].SetInt(0);
|
|
span[1].SetInt(0);
|
|
span[2].SetInt(0);
|
|
span[3].SetInt(0);
|
|
ptr->ReceiveEvent(&atkValue, span.GetPointer(0), 4u, 1uL);
|
|
ptr->ReceiveEvent(&atkValue, span.GetPointer(0), 4u, 0uL);
|
|
return true;
|
|
}
|
|
|
|
public unsafe static int GetRemainingAllowances()
|
|
{
|
|
SatisfactionSupplyManager* ptr = SatisfactionSupplyManager.Instance();
|
|
if (ptr == null)
|
|
{
|
|
return 0;
|
|
}
|
|
return ptr->GetRemainingAllowances();
|
|
}
|
|
|
|
public unsafe static NpcState GetNpcState(int npcIndex)
|
|
{
|
|
SatisfactionSupplyManager* ptr = SatisfactionSupplyManager.Instance();
|
|
if (ptr == null)
|
|
{
|
|
return default(NpcState);
|
|
}
|
|
if (npcIndex < 0 || npcIndex >= ptr->SatisfactionRanks.Length)
|
|
{
|
|
return default(NpcState);
|
|
}
|
|
return new NpcState(ptr->SatisfactionRanks[npcIndex], ptr->Satisfaction[npcIndex], 0, ptr->UsedAllowances[npcIndex]);
|
|
}
|
|
|
|
public unsafe static uint GetSupplySeed()
|
|
{
|
|
SatisfactionSupplyManager* ptr = SatisfactionSupplyManager.Instance();
|
|
if (ptr == null)
|
|
{
|
|
return 0u;
|
|
}
|
|
return ptr->SupplySeed;
|
|
}
|
|
|
|
public unsafe static byte GetBonusGuaranteeRowId()
|
|
{
|
|
SatisfactionSupplyManager* ptr = SatisfactionSupplyManager.Instance();
|
|
if (ptr == null)
|
|
{
|
|
return byte.MaxValue;
|
|
}
|
|
return ptr->BonusGuaranteeRowId;
|
|
}
|
|
}
|