Skip to content

Commit

Permalink
convert deliveroo and tank buying to async tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaksuhn committed Jan 13, 2025
1 parent 7eb4ead commit cc6ba8e
Show file tree
Hide file tree
Showing 27 changed files with 813 additions and 275 deletions.
266 changes: 127 additions & 139 deletions Automaton/Features/ARCeruleum.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
using Automaton.IPC;
using Automaton.Tasks;
using Automaton.Utilities.Movement;
using ECommons.Automation.NeoTaskManager;
using ECommons.GameFunctions;
using ECommons.ImGuiMethods;
using ECommons.Throttlers;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using ECommons.UIHelpers.AddonMasterImplementations;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Control;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
using Lumina.Excel.Sheets;

namespace Automaton.Features;

Expand Down Expand Up @@ -37,31 +33,22 @@ public override void DrawConfig()

ImGuiX.DrawSection("Debug");

ImGui.TextUnformatted($"AR:{P.AutoRetainer.IsBusy()} {P.AutoRetainer.GetSuppressed()}");
if (Player.Available)
ImGui.TextUnformatted($"o:{PlayerEx.Occupied} m:{Player.IsMoving} mp:{Svc.Objects.FirstOrDefault(x => x.DataId == MammetVoyagerId) != null}");

if (ImGui.Button("request"))
AutoRetainer.RequestCharacterPostprocess();
if (ImGui.Button("FinishCharacterPostProcess"))
AutoRetainer.FinishCharacterPostProcess();

if (ImGui.Button("BuyTanks"))
BuyTanks();

if (TaskManager.Tasks.Count > 0)
ImGuiX.TaskState();
if (ImGuiComponents.IconButton(P.Automation.CurrentTask == null ? FontAwesomeIcon.Play : FontAwesomeIcon.Stop))
{
ImGuiX.DrawSection("Tasks");
if (ImGui.Button($"Kill Tasks : {TaskManager.NumQueuedTasks}"))
TaskManager.Abort();
ImGuiBB.Text($"[color=#33E6E6]{TaskManager.CurrentTask?.Name}:[/color] [color=#FFFFFF]{TaskManager.CurrentTask?.Function.Method.Name}[/color]");
foreach (var task in TaskManager.Tasks)
if (P.Automation.CurrentTask == null)
P.Automation.Start(new BuyCeruleumTanks(), () => { AutoRetainer.FinishCharacterPostProcess(); P.UsingARPostProcess = false; });
else
{
ImGui.Indent();
ImGuiBB.Text($"[color=#33E6E6]{task.Name}:[/color] [color=#FFFFFF]{task.Function.Method.Name}[/color]");
ImGui.Unindent();
P.Automation.Stop();
AutoRetainer.FinishCharacterPostProcess();
P.UsingARPostProcess = false;
}
}

ImGui.TextUnformatted($"AR:{P.AutoRetainer.IsBusy()} {P.AutoRetainer.GetSuppressed()}");
if (TryGetAddonMaster<AddonMaster.FreeCompanyCreditShop>(out var am))
ImGui.TextUnformatted($"FC:{am.Items[0].QuantityInInventory} {Inventory.GetItemCount(CeruleumTankId)}");
}

private const uint CeruleumTankId = 10155;
Expand All @@ -82,115 +69,116 @@ private unsafe void CheckCharacter()
Svc.Log.Info("Skipping post process turn in for character: inventory above threshold or not in workshop.");
}

private static uint Amount;
private unsafe void BuyTanks()
{
TaskManager.Enqueue(GoToMammet);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(OpenShop);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(SelectCreditExchange);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(WaitForShopOpen);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(() => // not sure how to get around being unable to make this its own function since it'd be a void return and that can't work
{
if (TryGetAddonMaster<AddonMaster.SelectYesno>(out var m))
{
if (m.Text.ContainsAny(TanksStr))
if (EzThrottler.Throttle("CeruleumYesNo")) m.Yes();
}
if (TryGetAddonMaster<AddonMaster.FreeCompanyCreditShop>(out var am))
{
if (Amount != am.CompanyCredits)
{
EzThrottler.Reset("CeruleumYesNo");
EzThrottler.Reset("FCBuy");
Amount = am.CompanyCredits;
}
if (am.CompanyCredits < 100) return true;
if (EzThrottler.Throttle("FCBuy", 2000))
{
var tanks = am.Items[0];
if (tanks.QuantityInInventory != InventoryManager.Instance()->GetInventoryItemCount(tanks.ItemId)) return false; // last purchase hasn't gone through yet
var desiredQty = (int)GetRow<Item>(tanks.ItemId)!.Value.StackSize - tanks.QuantityInInventory;
var maxCanBuyAtOnce = Math.Min(desiredQty, tanks.MaxPurchaseSize);
var maxAfford = (int)(am.CompanyCredits / tanks.Price);
var toBuy = Math.Min(maxCanBuyAtOnce, maxAfford);
if (toBuy >= 1)
tanks.Buy(toBuy);
else
{
am.Addon->Close(true);
return true; // we're at 999 or can't afford more
}
}
}
else
return null;
return false;
}, BuyConfig);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(WaitForShopClose);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(AutoRetainer.FinishCharacterPostProcess);
TaskManager.Enqueue(() => P.UsingARPostProcess = false);
}

private bool GoToMammet()
{
if (Player.DistanceTo(MammetPos) < 0.5f) { movement.Enabled = false; return true; }

movement.Enabled = true;
movement.DesiredPosition = MammetPos;
return false;
}

private unsafe bool OpenShop()
{
var mammet = Svc.Objects.FirstOrDefault(x => x.DataId == MammetVoyagerId);
if (mammet == null) return false;
if (mammet.IsTarget())
{
if (EzThrottler.Throttle(nameof(OpenShop)))
{
TargetSystem.Instance()->InteractWithObject(mammet.Struct(), false);
return true;
}
}
else
{
if (EzThrottler.Throttle("MammetSetTarget"))
{
Svc.Targets.Target = mammet;
return false;
}
}
return false;
}

private bool SelectCreditExchange()
{
if (TryGetAddonMaster<AddonMaster.SelectIconString>(out var m))
{
foreach (var e in m.Entries)
{
if (e.Text.EqualsIgnoreCase(GetRow<FccShop>(2752515)!.Value.Name.ToString()))
{
if (EzThrottler.Throttle($"{nameof(SelectCreditExchange)}"))
{
e.Select();
return true;
}
}
}
return false;
}
else return false;
}

private unsafe bool WaitForShopOpen() => TryGetAddonByName<AtkUnitBase>("FreeCompanyCreditShop", out var addon) && IsAddonReady(addon);
private unsafe bool WaitForShopClose() => !TryGetAddonByName<AtkUnitBase>("FreeCompanyCreditShop", out _) && !PlayerEx.Occupied;

private TaskManagerConfiguration BuyConfig => new(timeLimitMS: 10 * 60 * 1000);
private unsafe void BuyTanks() => P.Automation.Start(new BuyCeruleumTanks(), () => { AutoRetainer.FinishCharacterPostProcess(); P.UsingARPostProcess = false; });
//private static uint Amount;
//private unsafe void BuyTanks()
//{
// TaskManager.Enqueue(GoToMammet);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(OpenShop);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(SelectCreditExchange);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(WaitForShopOpen);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(() => // not sure how to get around being unable to make this its own function since it'd be a void return and that can't work
// {
// if (TryGetAddonMaster<AddonMaster.SelectYesno>(out var m))
// {
// if (m.Text.ContainsAny(TanksStr))
// if (EzThrottler.Throttle("CeruleumYesNo")) m.Yes();
// }
// if (TryGetAddonMaster<AddonMaster.FreeCompanyCreditShop>(out var am))
// {
// if (Amount != am.CompanyCredits)
// {
// EzThrottler.Reset("CeruleumYesNo");
// EzThrottler.Reset("FCBuy");
// Amount = am.CompanyCredits;
// }
// if (am.CompanyCredits < 100) return true;
// if (EzThrottler.Throttle("FCBuy", 2000))
// {
// var tanks = am.Items[0];
// if (tanks.QuantityInInventory != InventoryManager.Instance()->GetInventoryItemCount(tanks.ItemId)) return false; // last purchase hasn't gone through yet
// var desiredQty = (int)GetRow<Item>(tanks.ItemId)!.Value.StackSize - tanks.QuantityInInventory;
// var maxCanBuyAtOnce = Math.Min(desiredQty, tanks.MaxPurchaseSize);
// var maxAfford = (int)(am.CompanyCredits / tanks.Price);
// var toBuy = Math.Min(maxCanBuyAtOnce, maxAfford);
// if (toBuy >= 1)
// tanks.Buy(toBuy);
// else
// {
// am.Addon->Close(true);
// return true; // we're at 999 or can't afford more
// }
// }
// }
// else
// return null;
// return false;
// }, BuyConfig);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(WaitForShopClose);
// TaskManager.EnqueueDelay(1000);
// TaskManager.Enqueue(AutoRetainer.FinishCharacterPostProcess);
// TaskManager.Enqueue(() => P.UsingARPostProcess = false);
//}

//private bool GoToMammet()
//{
// if (Player.DistanceTo(MammetPos) < 0.5f) { movement.Enabled = false; return true; }

// movement.Enabled = true;
// movement.DesiredPosition = MammetPos;
// return false;
//}

//private unsafe bool OpenShop()
//{
// var mammet = Svc.Objects.FirstOrDefault(x => x.DataId == MammetVoyagerId);
// if (mammet == null) return false;
// if (mammet.IsTarget())
// {
// if (EzThrottler.Throttle(nameof(OpenShop)))
// {
// TargetSystem.Instance()->InteractWithObject(mammet.Struct(), false);
// return true;
// }
// }
// else
// {
// if (EzThrottler.Throttle("MammetSetTarget"))
// {
// Svc.Targets.Target = mammet;
// return false;
// }
// }
// return false;
//}

//private bool SelectCreditExchange()
//{
// if (TryGetAddonMaster<AddonMaster.SelectIconString>(out var m))
// {
// foreach (var e in m.Entries)
// {
// if (e.Text.EqualsIgnoreCase(GetRow<FccShop>(2752515)!.Value.Name.ToString()))
// {
// if (EzThrottler.Throttle($"{nameof(SelectCreditExchange)}"))
// {
// e.Select();
// return true;
// }
// }
// }
// return false;
// }
// else return false;
//}

//private unsafe bool WaitForShopOpen() => TryGetAddonByName<AtkUnitBase>("FreeCompanyCreditShop", out var addon) && IsAddonReady(addon);
//private unsafe bool WaitForShopClose() => !TryGetAddonByName<AtkUnitBase>("FreeCompanyCreditShop", out _) && !PlayerEx.IsBusy;

//private TaskManagerConfiguration BuyConfig => new(timeLimitMS: 10 * 60 * 1000);
}
61 changes: 12 additions & 49 deletions Automaton/Features/ARTurnIn.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Automaton.IPC;
using ECommons.Automation.NeoTaskManager;
using ECommons.ImGuiMethods;
using Automaton.Tasks;
using Dalamud.Interface;
using Dalamud.Interface.Components;
using ImGuiNET;

namespace Automaton.Features;
Expand Down Expand Up @@ -48,36 +49,16 @@ public override void DrawConfig()

ImGuiX.DrawSection("Debug");

ImGui.TextUnformatted($"LS:{P.Lifestream.IsBusy()} AR:{P.AutoRetainer.IsBusy()} D:{P.Deliveroo.IsTurnInRunning()} N:{P.Navmesh.IsRunning()}");
if (Player.Available)
ImGui.TextUnformatted($"o:{PlayerEx.Occupied} m:{Player.IsMoving} c:{PlayerEx.IsCasting} l:{PlayerEx.AnimationLock}");

if (ImGui.Button("FinishCharacterPostProcess"))
AutoRetainer.FinishCharacterPostProcess();

if (ImGui.Button("TurnIn (All Tasks Combined)"))
TurnIn();

if (ImGui.Button($"GoToGC"))
TaskManager.Enqueue(GoToGC);

if (ImGui.Button($"TurnInGear"))
TaskManager.Enqueue(Deliveroo);

if (ImGui.Button($"GoHome"))
TaskManager.Enqueue(GoHome);

if (TaskManager.Tasks.Count > 0)
ImGuiX.TaskState();
if (ImGuiComponents.IconButton(P.Automation.CurrentTask == null ? FontAwesomeIcon.Play : FontAwesomeIcon.Stop))
{
ImGuiX.DrawSection("Tasks");
if (ImGui.Button($"Kill Tasks : {TaskManager.NumQueuedTasks}"))
TaskManager.Abort();
ImGuiBB.Text($"[color=#33E6E6]{TaskManager.CurrentTask?.Name}:[/color] [color=#FFFFFF]{TaskManager.CurrentTask?.Function.Method.Name}[/color]");
foreach (var task in TaskManager.Tasks)
if (P.Automation.CurrentTask == null)
P.Automation.Start(new AutoDeliveroo(), () => { AutoRetainer.FinishCharacterPostProcess(); P.UsingARPostProcess = false; });
else
{
ImGui.Indent();
ImGuiBB.Text($"[color=#33E6E6]{task.Name}:[/color] [color=#FFFFFF]{task.Function.Method.Name}[/color]");
ImGui.Unindent();
P.Automation.Stop();
AutoRetainer.FinishCharacterPostProcess();
P.UsingARPostProcess = false;
}
}
}
Expand All @@ -98,23 +79,5 @@ private void CheckCharacter()
}
}

private void TurnIn()
{
TaskManager.Enqueue(GoToGC, configuration: LSConfig);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(Deliveroo, configuration: DConfig);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(GoHome, configuration: LSConfig);
TaskManager.EnqueueDelay(1000);
TaskManager.Enqueue(AutoRetainer.FinishCharacterPostProcess);
TaskManager.Enqueue(() => P.UsingARPostProcess = false);
}

// bless lifestream for doing literally all the annoying work for me already
private void GoToGC() => TaskManager.InsertMulti([new(() => P.Lifestream.ExecuteCommand("gc")), new(() => P.Lifestream.IsBusy()), new(() => !P.Lifestream.IsBusy(), LSConfig)]);
private void Deliveroo() => TaskManager.InsertMulti([new(() => Svc.Commands.ProcessCommand("/deliveroo enable")), new(() => P.Deliveroo.IsTurnInRunning()), new(() => !P.Deliveroo.IsTurnInRunning(), DConfig)]);
private void GoHome() => TaskManager.InsertMulti([new(() => P.Lifestream.ExecuteCommand("auto")), new(() => P.Lifestream.IsBusy()), new(() => !P.Lifestream.IsBusy(), LSConfig)]);

private TaskManagerConfiguration LSConfig => new(timeLimitMS: 2 * 60 * 1000);
private TaskManagerConfiguration DConfig => new(timeLimitMS: 10 * 60 * 1000, abortOnTimeout: false);
private void TurnIn() => P.Automation.Start(new AutoDeliveroo(), () => { AutoRetainer.FinishCharacterPostProcess(); P.UsingARPostProcess = false; });
}
2 changes: 1 addition & 1 deletion Automaton/Features/AutoMerge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class InventorySlot

private unsafe void OnSetup(string addonName)
{
if (PlayerEx.Occupied || !inventoryAddonNames.Contains(addonName)) return;
if (PlayerEx.IsBusy || !inventoryAddonNames.Contains(addonName)) return;

inventorySlots.Clear();
var inv = InventoryManager.Instance();
Expand Down
2 changes: 1 addition & 1 deletion Automaton/Features/AutoPillion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class AutoPillion : Tweak

private unsafe void OnUpdate(IFramework framework)
{
if (!Player.Available || PlayerEx.Occupied || Svc.Condition[ConditionFlag.Mounted])
if (!Player.Available || PlayerEx.IsBusy || Svc.Condition[ConditionFlag.Mounted])
{
if (TaskManager.Tasks.Count > 0)
TaskManager.Abort();
Expand Down
2 changes: 1 addition & 1 deletion Automaton/Features/AutoSelectGardening.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public override void DrawConfig()
{
ImGuiX.DrawSection("Configuration");

if (Utils.AnyNull(Seeds, Soils, Fertilizers)) return;
if (AnyNull(Seeds, Soils, Fertilizers)) return;

ImGui.Checkbox("Show Only Inventory Items", ref Config.OnlyShowInventoryItems);

Expand Down
Loading

0 comments on commit cc6ba8e

Please sign in to comment.