qstbak/Questionable/Questionable.Controller.GameUi/CraftworksSupplyController.cs
2025-10-09 07:47:19 +10:00

155 lines
4.3 KiB
C#

using System;
using System.Threading;
using Dalamud.Game.Addon.Lifecycle;
using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib.GameUI;
using Microsoft.Extensions.Logging;
namespace Questionable.Controller.GameUi;
internal sealed class CraftworksSupplyController : IDisposable
{
private readonly QuestController _questController;
private readonly IAddonLifecycle _addonLifecycle;
private readonly IGameGui _gameGui;
private readonly IFramework _framework;
private readonly ILogger<CraftworksSupplyController> _logger;
private bool ShouldHandleUiInteractions => _questController.IsRunning;
public CraftworksSupplyController(QuestController questController, IAddonLifecycle addonLifecycle, IGameGui gameGui, IFramework framework, ILogger<CraftworksSupplyController> logger)
{
_questController = questController;
_addonLifecycle = addonLifecycle;
_gameGui = gameGui;
_framework = framework;
_logger = logger;
_addonLifecycle.RegisterListener(AddonEvent.PostReceiveEvent, "ContextIconMenu", ContextIconMenuPostReceiveEvent);
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "BankaCraftworksSupply", BankaCraftworksSupplyPostUpdate);
}
private unsafe void BankaCraftworksSupplyPostUpdate(AddonEvent type, AddonArgs args)
{
if (ShouldHandleUiInteractions)
{
AtkUnitBase* address = (AtkUnitBase*)args.Addon.Address;
InteractWithBankaCraftworksSupply(address);
}
}
private unsafe void InteractWithBankaCraftworksSupply()
{
if (_gameGui.TryGetAddonByName<AtkUnitBase>("BankaCraftworksSupply", out var addonPtr))
{
InteractWithBankaCraftworksSupply(addonPtr);
}
}
private unsafe void InteractWithBankaCraftworksSupply(AtkUnitBase* addon)
{
AtkValue* atkValues = addon->AtkValues;
uint uInt = atkValues[7].UInt;
uint num = 6 - uInt;
for (int i = 0; i < num; i++)
{
if (atkValues[31 + i].UInt == 0)
{
_logger.LogInformation("Selecting an item for slot {Slot}", i);
AtkValue* values = stackalloc AtkValue[2]
{
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int,
Int = 2
},
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int,
Int = i
}
};
addon->FireCallback(2u, values);
return;
}
}
if (atkValues[31].UInt != 0)
{
_logger.LogInformation("Confirming turn-in");
addon->FireCallbackInt(0);
}
}
private unsafe void ContextIconMenuPostReceiveEvent(AddonEvent type, AddonArgs args)
{
if (!ShouldHandleUiInteractions)
{
return;
}
AddonContextIconMenu* address = (AddonContextIconMenu*)args.Addon.Address;
if (!address->IsVisible)
{
return;
}
ushort contextMenuParentId = address->ContextMenuParentId;
if (contextMenuParentId == 0)
{
return;
}
AtkUnitBase* addonById = AtkStage.Instance()->RaptureAtkUnitManager->GetAddonById(contextMenuParentId);
if (addonById->NameString == "BankaCraftworksSupply")
{
_logger.LogInformation("Picking item for {AddonName}", addonById->NameString);
AtkValue* values = stackalloc AtkValue[5]
{
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int,
Int = 0
},
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Int,
Int = 0
},
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.UInt,
UInt = 20802u
},
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.UInt,
UInt = 0u
},
new AtkValue
{
Type = FFXIVClientStructs.FFXIV.Component.GUI.ValueType.Undefined,
Int = 0
}
};
address->FireCallback(5u, values);
address->Close(fireCallback: true);
if (addonById->NameString == "BankaCraftworksSupply")
{
_framework.RunOnTick((Action)InteractWithBankaCraftworksSupply, TimeSpan.FromMilliseconds(50L, 0L), 0, default(CancellationToken));
}
}
else
{
_logger.LogTrace("Ignoring contextmenu event for {AddonName}", addonById->NameString);
}
}
public void Dispose()
{
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "BankaCraftworksSupply", BankaCraftworksSupplyPostUpdate);
_addonLifecycle.UnregisterListener(AddonEvent.PostReceiveEvent, "ContextIconMenu", ContextIconMenuPostReceiveEvent);
}
}