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

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;
}
}