2023-09-21 13:43:22 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2023-09-21 21:17:46 +00:00
|
|
|
|
using Dalamud.Data;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
using Dalamud.Game;
|
|
|
|
|
using Dalamud.Game.ClientState;
|
2023-09-25 19:36:06 +00:00
|
|
|
|
using Dalamud.Game.ClientState.Conditions;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
using Dalamud.Game.ClientState.Objects;
|
|
|
|
|
using Dalamud.Game.ClientState.Objects.Types;
|
2023-09-25 19:40:10 +00:00
|
|
|
|
using Dalamud.Game.Command;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
using Dalamud.Game.Gui;
|
|
|
|
|
using Dalamud.Interface.Windowing;
|
|
|
|
|
using Dalamud.Logging;
|
|
|
|
|
using Dalamud.Plugin;
|
2023-09-22 19:44:56 +00:00
|
|
|
|
using Deliveroo.External;
|
2023-09-21 21:17:46 +00:00
|
|
|
|
using Deliveroo.GameData;
|
|
|
|
|
using Deliveroo.Windows;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
|
|
|
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
2023-09-22 06:59:31 +00:00
|
|
|
|
using Lumina.Excel.GeneratedSheets;
|
2023-09-25 19:36:06 +00:00
|
|
|
|
using Condition = Dalamud.Game.ClientState.Conditions.Condition;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
|
|
|
|
namespace Deliveroo;
|
|
|
|
|
|
2023-09-22 20:42:18 +00:00
|
|
|
|
public sealed partial class DeliverooPlugin : IDalamudPlugin
|
2023-09-21 13:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
private readonly WindowSystem _windowSystem = new(typeof(DeliverooPlugin).AssemblyQualifiedName);
|
|
|
|
|
|
|
|
|
|
private readonly DalamudPluginInterface _pluginInterface;
|
|
|
|
|
private readonly ChatGui _chatGui;
|
|
|
|
|
private readonly GameGui _gameGui;
|
|
|
|
|
private readonly Framework _framework;
|
|
|
|
|
private readonly ClientState _clientState;
|
|
|
|
|
private readonly ObjectTable _objectTable;
|
|
|
|
|
private readonly TargetManager _targetManager;
|
2023-09-25 19:36:06 +00:00
|
|
|
|
private readonly Condition _condition;
|
2023-09-25 19:40:10 +00:00
|
|
|
|
private readonly CommandManager _commandManager;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
2023-09-21 21:17:46 +00:00
|
|
|
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
|
|
|
private readonly Configuration _configuration;
|
2023-09-22 06:59:31 +00:00
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
|
|
|
private readonly YesAlreadyIpc _yesAlreadyIpc;
|
|
|
|
|
|
2023-09-21 21:17:46 +00:00
|
|
|
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
|
|
|
|
private readonly GcRewardsCache _gcRewardsCache;
|
2023-09-22 19:44:56 +00:00
|
|
|
|
|
2023-09-21 21:17:46 +00:00
|
|
|
|
private readonly ConfigWindow _configWindow;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
private readonly TurnInWindow _turnInWindow;
|
2023-09-22 06:59:31 +00:00
|
|
|
|
private readonly IReadOnlyDictionary<uint, uint> _sealCaps;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
private Stage _currentStageInternal = Stage.Stopped;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
private DateTime _continueAt = DateTime.MinValue;
|
2023-09-24 10:14:43 +00:00
|
|
|
|
private List<PurchaseItemRequest> _itemsToPurchaseNow = new();
|
2023-09-22 19:44:56 +00:00
|
|
|
|
private (bool Saved, bool? PreviousState) _yesAlreadyState = (false, null);
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
|
|
|
|
public DeliverooPlugin(DalamudPluginInterface pluginInterface, ChatGui chatGui, GameGui gameGui,
|
2023-09-21 21:17:46 +00:00
|
|
|
|
Framework framework, ClientState clientState, ObjectTable objectTable, TargetManager targetManager,
|
2023-09-25 19:40:10 +00:00
|
|
|
|
DataManager dataManager, Condition condition, CommandManager commandManager)
|
2023-09-21 13:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
_pluginInterface = pluginInterface;
|
|
|
|
|
_chatGui = chatGui;
|
|
|
|
|
_gameGui = gameGui;
|
|
|
|
|
_framework = framework;
|
|
|
|
|
_clientState = clientState;
|
|
|
|
|
_objectTable = objectTable;
|
|
|
|
|
_targetManager = targetManager;
|
2023-09-25 19:36:06 +00:00
|
|
|
|
_condition = condition;
|
2023-09-25 19:40:10 +00:00
|
|
|
|
_commandManager = commandManager;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
var dalamudReflector = new DalamudReflector(_pluginInterface, _framework);
|
|
|
|
|
_yesAlreadyIpc = new YesAlreadyIpc(dalamudReflector);
|
2023-09-21 21:17:46 +00:00
|
|
|
|
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
|
|
|
|
|
_gcRewardsCache = new GcRewardsCache(dataManager);
|
|
|
|
|
_configWindow = new ConfigWindow(_pluginInterface, this, _configuration, _gcRewardsCache);
|
|
|
|
|
_windowSystem.AddWindow(_configWindow);
|
2023-09-22 20:42:18 +00:00
|
|
|
|
_turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _gcRewardsCache, _configWindow);
|
2023-09-21 13:43:22 +00:00
|
|
|
|
_windowSystem.AddWindow(_turnInWindow);
|
2023-09-22 06:59:31 +00:00
|
|
|
|
_sealCaps = dataManager.GetExcelSheet<GrandCompanyRank>()!.Where(x => x.RowId > 0)
|
|
|
|
|
.ToDictionary(x => x.RowId, x => x.MaxSeals);
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
|
|
|
|
_framework.Update += FrameworkUpdate;
|
|
|
|
|
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
2023-09-21 21:17:46 +00:00
|
|
|
|
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
|
2023-09-25 19:40:10 +00:00
|
|
|
|
_commandManager.AddHandler("/deliveroo", new CommandInfo(ProcessCommand)
|
|
|
|
|
{
|
|
|
|
|
HelpMessage = "Open the configuration"
|
|
|
|
|
});
|
2023-09-21 13:43:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string Name => "Deliveroo";
|
|
|
|
|
|
2023-09-21 21:28:35 +00:00
|
|
|
|
internal Stage CurrentStage
|
2023-09-21 13:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
get => _currentStageInternal;
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (_currentStageInternal != value)
|
|
|
|
|
{
|
|
|
|
|
PluginLog.Information($"Changing stage from {_currentStageInternal} to {value}");
|
|
|
|
|
_currentStageInternal = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private unsafe void FrameworkUpdate(Framework f)
|
|
|
|
|
{
|
2023-09-22 20:42:18 +00:00
|
|
|
|
_turnInWindow.Error = string.Empty;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
if (!_clientState.IsLoggedIn || _clientState.TerritoryType is not 128 and not 130 and not 132 ||
|
2023-09-25 19:36:06 +00:00
|
|
|
|
_condition[ConditionFlag.OccupiedInCutSceneEvent] ||
|
2023-09-21 13:43:22 +00:00
|
|
|
|
GetDistanceToNpc(GetQuartermasterId(), out GameObject? quartermaster) >= 7f ||
|
2023-09-21 21:17:46 +00:00
|
|
|
|
GetDistanceToNpc(GetPersonnelOfficerId(), out GameObject? personnelOfficer) >= 7f ||
|
|
|
|
|
_configWindow.IsOpen)
|
2023-09-21 13:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
_turnInWindow.IsOpen = false;
|
2023-09-21 21:17:46 +00:00
|
|
|
|
_turnInWindow.State = false;
|
2023-09-22 19:44:56 +00:00
|
|
|
|
if (CurrentStage != Stage.Stopped)
|
|
|
|
|
{
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
CurrentStage = Stage.Stopped;
|
|
|
|
|
}
|
2023-09-21 13:43:22 +00:00
|
|
|
|
}
|
|
|
|
|
else if (DateTime.Now > _continueAt)
|
|
|
|
|
{
|
|
|
|
|
_turnInWindow.IsOpen = true;
|
|
|
|
|
_turnInWindow.Multiplier = GetSealMultiplier();
|
|
|
|
|
|
|
|
|
|
if (!_turnInWindow.State)
|
|
|
|
|
{
|
2023-09-22 19:44:56 +00:00
|
|
|
|
if (CurrentStage != Stage.Stopped)
|
|
|
|
|
{
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
CurrentStage = Stage.Stopped;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-21 13:43:22 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2023-09-22 19:44:56 +00:00
|
|
|
|
else if (_turnInWindow.State && CurrentStage == Stage.Stopped)
|
2023-09-21 13:43:22 +00:00
|
|
|
|
{
|
|
|
|
|
CurrentStage = Stage.TargetPersonnelOfficer;
|
2023-09-24 10:14:43 +00:00
|
|
|
|
_itemsToPurchaseNow = _turnInWindow.SelectedItems;
|
|
|
|
|
if (_itemsToPurchaseNow.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
PluginLog.Information("Items to purchase:");
|
|
|
|
|
foreach (var item in _itemsToPurchaseNow)
|
|
|
|
|
PluginLog.Information($" {item.Name} (limit = {item.EffectiveLimit})");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
PluginLog.Information("No items to purchase configured or available");
|
2023-09-21 21:17:46 +00:00
|
|
|
|
|
2023-09-24 10:14:43 +00:00
|
|
|
|
|
|
|
|
|
var nextItem = GetNextItemToPurchase();
|
|
|
|
|
if (nextItem != null && GetCurrentSealCount() >= _configuration.ReservedSealCount + nextItem.SealCost)
|
2023-09-21 18:18:05 +00:00
|
|
|
|
CurrentStage = Stage.TargetQuartermaster;
|
|
|
|
|
|
|
|
|
|
if (TryGetAddonByName<AddonGrandCompanySupplyList>("GrandCompanySupplyList", out var gcSupplyList) &&
|
|
|
|
|
IsAddonReady(&gcSupplyList->AtkUnitBase))
|
2023-09-22 20:42:18 +00:00
|
|
|
|
CurrentStage = Stage.SelectExpertDeliveryTab;
|
2023-09-21 18:18:05 +00:00
|
|
|
|
|
|
|
|
|
if (TryGetAddonByName<AtkUnitBase>("GrandCompanyExchange", out var gcExchange) &&
|
|
|
|
|
IsAddonReady(gcExchange))
|
2023-09-24 10:14:43 +00:00
|
|
|
|
CurrentStage = Stage.SelectRewardTier;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
if (CurrentStage != Stage.Stopped && CurrentStage != Stage.RequestStop && !_yesAlreadyState.Saved)
|
|
|
|
|
SaveYesAlready();
|
|
|
|
|
|
2023-09-21 13:43:22 +00:00
|
|
|
|
switch (CurrentStage)
|
|
|
|
|
{
|
|
|
|
|
case Stage.TargetPersonnelOfficer:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
InteractWithPersonnelOfficer(personnelOfficer!, quartermaster!);
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
2023-09-22 20:42:18 +00:00
|
|
|
|
|
2023-09-21 13:43:22 +00:00
|
|
|
|
case Stage.OpenGcSupply:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
OpenGcSupply();
|
|
|
|
|
break;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
|
2023-09-22 20:42:18 +00:00
|
|
|
|
case Stage.SelectExpertDeliveryTab:
|
|
|
|
|
SelectExpertDeliveryTab();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-22 20:42:18 +00:00
|
|
|
|
case Stage.SelectItemToTurnIn:
|
|
|
|
|
SelectItemToTurnIn();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-22 20:42:18 +00:00
|
|
|
|
case Stage.TurnInSelected:
|
|
|
|
|
TurnInSelectedItem();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.FinalizeTurnIn:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
FinalizeTurnInItem();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.CloseGcSupply:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
CloseGcSupply();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.CloseGcSupplyThenStop:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
CloseGcSupplyThenStop();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.TargetQuartermaster:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
InteractWithQuartermaster(personnelOfficer!, quartermaster!);
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-21 21:17:46 +00:00
|
|
|
|
case Stage.SelectRewardTier:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
SelectRewardTier();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-21 21:17:46 +00:00
|
|
|
|
case Stage.SelectRewardSubCategory:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
SelectRewardSubCategory();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.SelectReward:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
SelectReward();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-21 18:18:05 +00:00
|
|
|
|
case Stage.ConfirmReward:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
ConfirmReward();
|
2023-09-21 18:18:05 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-21 13:43:22 +00:00
|
|
|
|
case Stage.CloseGcExchange:
|
2023-09-22 20:42:18 +00:00
|
|
|
|
CloseGcExchange();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
case Stage.RequestStop:
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
CurrentStage = Stage.Stopped;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case Stage.Stopped:
|
2023-09-21 13:43:22 +00:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
PluginLog.Warning($"Unknown stage {CurrentStage}");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
2023-09-25 19:40:10 +00:00
|
|
|
|
_commandManager.RemoveHandler("/deliveroo");
|
2023-09-21 21:17:46 +00:00
|
|
|
|
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;
|
2023-09-21 13:43:22 +00:00
|
|
|
|
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
|
|
|
|
_framework.Update -= FrameworkUpdate;
|
2023-09-22 19:44:56 +00:00
|
|
|
|
|
|
|
|
|
RestoreYesAlready();
|
2023-09-21 13:43:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-25 19:40:10 +00:00
|
|
|
|
private void ProcessCommand(string command, string arguments) => _configWindow.Toggle();
|
|
|
|
|
|
2023-09-22 19:44:56 +00:00
|
|
|
|
private void SaveYesAlready()
|
|
|
|
|
{
|
|
|
|
|
if (_yesAlreadyState.Saved)
|
|
|
|
|
{
|
|
|
|
|
PluginLog.Information("Not overwriting yesalready state");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_yesAlreadyState = (true, _yesAlreadyIpc.DisableIfNecessary());
|
|
|
|
|
PluginLog.Information($"Previous yesalready state: {_yesAlreadyState.PreviousState}");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RestoreYesAlready()
|
|
|
|
|
{
|
|
|
|
|
if (_yesAlreadyState.Saved)
|
|
|
|
|
{
|
|
|
|
|
PluginLog.Information($"Restoring previous yesalready state: {_yesAlreadyState.PreviousState}");
|
|
|
|
|
if (_yesAlreadyState.PreviousState == true)
|
|
|
|
|
_yesAlreadyIpc.Enable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_yesAlreadyState = (false, null);
|
|
|
|
|
}
|
2023-09-21 13:43:22 +00:00
|
|
|
|
}
|