Workship/Workshoppa/WorkshopPlugin.cs

315 lines
12 KiB
C#
Raw Permalink Normal View History

2023-10-01 20:50:21 +00:00
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
2023-10-13 20:08:22 +00:00
using Dalamud.Game.Addon.Lifecycle;
2023-10-01 20:50:21 +00:00
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;
2023-10-04 22:07:36 +00:00
using Dalamud.Plugin.Services;
using ImGuiNET;
2023-11-01 09:51:53 +00:00
using LLib;
2023-10-01 20:50:21 +00:00
using Workshoppa.External;
using Workshoppa.GameData;
using Workshoppa.Windows;
namespace Workshoppa;
2024-03-20 18:52:54 +00:00
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
2023-10-01 20:50:21 +00:00
public sealed partial class WorkshopPlugin : IDalamudPlugin
{
2023-11-01 09:51:53 +00:00
private readonly IReadOnlyList<uint> _fabricationStationIds =
new uint[] { 2005236, 2005238, 2005240, 2007821, 2011588 }.AsReadOnly();
2023-10-05 19:56:12 +00:00
internal readonly IReadOnlyList<ushort> WorkshopTerritories = new ushort[] { 423, 424, 425, 653, 984 }.AsReadOnly();
2023-10-01 20:50:21 +00:00
private readonly WindowSystem _windowSystem = new WindowSystem(nameof(WorkshopPlugin));
2024-07-04 10:04:50 +00:00
private readonly IDalamudPluginInterface _pluginInterface;
2023-10-04 22:07:36 +00:00
private readonly IGameGui _gameGui;
private readonly IFramework _framework;
private readonly ICondition _condition;
private readonly IClientState _clientState;
private readonly IObjectTable _objectTable;
private readonly ICommandManager _commandManager;
private readonly IPluginLog _pluginLog;
2023-10-13 20:08:22 +00:00
private readonly IAddonLifecycle _addonLifecycle;
private readonly IChatGui _chatGui;
2023-10-01 20:50:21 +00:00
private readonly Configuration _configuration;
2023-10-19 18:46:01 +00:00
private readonly ExternalPluginHandler _externalPluginHandler;
2023-10-01 20:50:21 +00:00
private readonly WorkshopCache _workshopCache;
2023-10-13 20:08:22 +00:00
private readonly GameStrings _gameStrings;
2023-10-01 20:50:21 +00:00
private readonly MainWindow _mainWindow;
2023-10-13 20:08:22 +00:00
private readonly ConfigWindow _configWindow;
private readonly RepairKitWindow _repairKitWindow;
2023-10-24 22:19:42 +00:00
private readonly CeruleumTankWindow _ceruleumTankWindow;
2023-10-01 20:50:21 +00:00
private Stage _currentStageInternal = Stage.Stopped;
private DateTime _continueAt = DateTime.MinValue;
2023-10-19 18:46:01 +00:00
private DateTime _fallbackAt = DateTime.MaxValue;
2023-10-01 20:50:21 +00:00
2024-07-04 10:04:50 +00:00
public WorkshopPlugin(IDalamudPluginInterface pluginInterface, IGameGui gameGui, IFramework framework,
2023-10-04 22:07:36 +00:00
ICondition condition, IClientState clientState, IObjectTable objectTable, IDataManager dataManager,
2023-11-01 09:51:53 +00:00
ICommandManager commandManager, IPluginLog pluginLog, IAddonLifecycle addonLifecycle, IChatGui chatGui,
ITextureProvider textureProvider)
2023-10-01 20:50:21 +00:00
{
_pluginInterface = pluginInterface;
_gameGui = gameGui;
_framework = framework;
_condition = condition;
_clientState = clientState;
_objectTable = objectTable;
_commandManager = commandManager;
2023-10-04 22:07:36 +00:00
_pluginLog = pluginLog;
2023-10-13 20:08:22 +00:00
_addonLifecycle = addonLifecycle;
_chatGui = chatGui;
2023-10-01 20:50:21 +00:00
2023-11-07 19:07:22 +00:00
_externalPluginHandler = new ExternalPluginHandler(_pluginInterface, _pluginLog);
2023-10-01 20:50:21 +00:00
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
2023-10-04 22:07:36 +00:00
_workshopCache = new WorkshopCache(dataManager, _pluginLog);
2023-10-13 20:08:22 +00:00
_gameStrings = new(dataManager, _pluginLog);
2023-10-01 20:50:21 +00:00
2023-11-01 09:51:53 +00:00
_mainWindow = new(this, _pluginInterface, _clientState, _configuration, _workshopCache,
new IconCache(textureProvider), _chatGui, new RecipeTree(dataManager, _pluginLog), _pluginLog);
2023-10-01 20:50:21 +00:00
_windowSystem.AddWindow(_mainWindow);
2023-10-13 20:08:22 +00:00
_configWindow = new(_pluginInterface, _configuration);
_windowSystem.AddWindow(_configWindow);
_repairKitWindow = new(this, _pluginLog, _gameGui, addonLifecycle, _configuration,
2023-11-01 09:51:53 +00:00
_externalPluginHandler);
2023-10-13 20:08:22 +00:00
_windowSystem.AddWindow(_repairKitWindow);
_ceruleumTankWindow = new(this, _pluginLog, _gameGui, addonLifecycle, _configuration,
_externalPluginHandler, _chatGui);
2023-10-24 22:19:42 +00:00
_windowSystem.AddWindow(_ceruleumTankWindow);
2023-10-01 20:50:21 +00:00
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
_pluginInterface.UiBuilder.OpenMainUi += OpenMainUi;
2023-10-13 20:08:22 +00:00
_pluginInterface.UiBuilder.OpenConfigUi += _configWindow.Toggle;
2023-10-01 20:50:21 +00:00
_framework.Update += FrameworkUpdate;
2023-10-04 22:07:36 +00:00
_commandManager.AddHandler("/ws", new CommandInfo(ProcessCommand)
{
HelpMessage = "Open UI"
});
_commandManager.AddHandler("/workshoppa", new CommandInfo(ProcessCommand)
{
ShowInHelp = false,
});
_commandManager.AddHandler("/buy-tanks", new CommandInfo(ProcessBuyCommand)
{
HelpMessage = "Buy a given number of ceruleum tank stacks.",
});
_commandManager.AddHandler("/fill-tanks", new CommandInfo(ProcessFillCommand)
{
HelpMessage = "Fill your inventory with a given number of ceruleum tank stacks.",
});
2023-10-13 20:08:22 +00:00
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesNoPostSetup);
2023-10-19 18:46:01 +00:00
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "Request", RequestPostSetup);
_addonLifecycle.RegisterListener(AddonEvent.PostRefresh, "Request", RequestPostRefresh);
_addonLifecycle.RegisterListener(AddonEvent.PostUpdate, "ContextIconMenu", ContextIconMenuPostReceiveEvent);
2023-10-01 20:50:21 +00:00
}
internal Stage CurrentStage
{
get => _currentStageInternal;
private set
{
if (_currentStageInternal != value)
{
2023-10-19 18:46:01 +00:00
_pluginLog.Debug($"Changing stage from {_currentStageInternal} to {value}");
2023-10-01 20:50:21 +00:00
_currentStageInternal = value;
}
if (value != Stage.Stopped)
_mainWindow.Flags |= ImGuiWindowFlags.NoCollapse;
else
_mainWindow.Flags &= ~ImGuiWindowFlags.NoCollapse;
2023-10-01 20:50:21 +00:00
}
}
2023-10-04 22:07:36 +00:00
private void FrameworkUpdate(IFramework framework)
2023-10-01 20:50:21 +00:00
{
if (!_clientState.IsLoggedIn ||
2023-10-05 19:56:12 +00:00
!WorkshopTerritories.Contains(_clientState.TerritoryType) ||
2023-10-01 20:50:21 +00:00
_condition[ConditionFlag.BoundByDuty] ||
2023-10-14 14:26:06 +00:00
_condition[ConditionFlag.BetweenAreas] ||
_condition[ConditionFlag.BetweenAreas51] ||
2023-10-24 22:19:42 +00:00
GetDistanceToEventObject(_fabricationStationIds, out var fabricationStation) >= 3f)
2023-10-01 20:50:21 +00:00
{
_mainWindow.NearFabricationStation = false;
if (_mainWindow.IsOpen &&
_mainWindow.OpenReason == MainWindow.EOpenReason.NearFabricationStation &&
_configuration.CurrentlyCraftedItem == null &&
_configuration.ItemQueue.Count == 0)
{
_mainWindow.IsOpen = false;
}
2023-10-01 20:50:21 +00:00
}
else if (DateTime.Now >= _continueAt)
{
_mainWindow.NearFabricationStation = true;
if (!_mainWindow.IsOpen)
{
_mainWindow.IsOpen = true;
_mainWindow.OpenReason = MainWindow.EOpenReason.NearFabricationStation;
}
2023-10-01 20:50:21 +00:00
if (_mainWindow.State is MainWindow.ButtonState.Pause or MainWindow.ButtonState.Stop)
{
_mainWindow.State = MainWindow.ButtonState.None;
if (CurrentStage != Stage.Stopped)
{
2023-10-19 18:46:01 +00:00
_externalPluginHandler.Restore();
2023-10-01 20:50:21 +00:00
CurrentStage = Stage.Stopped;
}
return;
}
2023-11-01 09:51:53 +00:00
else if (_mainWindow.State is MainWindow.ButtonState.Start or MainWindow.ButtonState.Resume &&
CurrentStage == Stage.Stopped)
2023-10-01 20:50:21 +00:00
{
2023-10-04 22:57:44 +00:00
// TODO Error checking, we should ensure the player has the required job level for *all* crafting parts
2023-10-01 20:50:21 +00:00
_mainWindow.State = MainWindow.ButtonState.None;
CurrentStage = Stage.TakeItemFromQueue;
}
2023-10-19 18:46:01 +00:00
if (CurrentStage != Stage.Stopped && CurrentStage != Stage.RequestStop && !_externalPluginHandler.Saved)
_externalPluginHandler.Save();
2023-10-01 20:50:21 +00:00
switch (CurrentStage)
{
case Stage.TakeItemFromQueue:
2023-10-04 22:57:44 +00:00
if (CheckContinueWithDelivery())
CurrentStage = Stage.ContributeMaterials;
else
TakeItemFromQueue();
2023-10-01 20:50:21 +00:00
break;
case Stage.TargetFabricationStation:
2023-11-01 09:51:53 +00:00
if (_configuration.CurrentlyCraftedItem is { StartedCrafting: true })
CurrentStage = Stage.SelectCraftBranch;
else
CurrentStage = Stage.OpenCraftingLog;
2023-10-19 18:46:01 +00:00
2023-11-01 09:51:53 +00:00
InteractWithFabricationStation(fabricationStation!);
2023-10-01 20:50:21 +00:00
break;
case Stage.OpenCraftingLog:
OpenCraftingLog();
2023-10-01 20:50:21 +00:00
break;
case Stage.SelectCraftCategory:
SelectCraftCategory();
break;
case Stage.SelectCraft:
SelectCraft();
break;
case Stage.ConfirmCraft:
ConfirmCraft();
break;
case Stage.RequestStop:
2023-10-19 18:46:01 +00:00
_externalPluginHandler.Restore();
2023-10-01 20:50:21 +00:00
CurrentStage = Stage.Stopped;
break;
case Stage.SelectCraftBranch:
SelectCraftBranch();
break;
case Stage.ContributeMaterials:
ContributeMaterials();
break;
2023-10-19 18:46:01 +00:00
case Stage.OpenRequestItemWindow:
// see RequestPostSetup and related
if (DateTime.Now > _fallbackAt)
goto case Stage.ContributeMaterials;
break;
case Stage.OpenRequestItemSelect:
case Stage.ConfirmRequestItemWindow:
// see RequestPostSetup and related
break;
2023-10-01 20:50:21 +00:00
case Stage.ConfirmMaterialDelivery:
2023-10-19 18:46:01 +00:00
// see SelectYesNoPostSetup
2023-10-01 20:50:21 +00:00
break;
case Stage.ConfirmCollectProduct:
// see SelectYesNoPostSetup
2023-10-01 20:50:21 +00:00
break;
case Stage.Stopped:
break;
default:
2023-10-04 22:07:36 +00:00
_pluginLog.Warning($"Unknown stage {CurrentStage}");
2023-10-01 20:50:21 +00:00
break;
}
}
}
private WorkshopCraft GetCurrentCraft()
{
2023-11-01 09:51:53 +00:00
return _workshopCache.Crafts.Single(
x => x.WorkshopItemId == _configuration.CurrentlyCraftedItem!.WorkshopItemId);
2023-10-01 20:50:21 +00:00
}
private void ProcessCommand(string command, string arguments)
2023-10-13 20:08:22 +00:00
{
if (arguments is "c" or "config")
_configWindow.Toggle();
else
_mainWindow.Toggle(MainWindow.EOpenReason.Command);
}
private void ProcessBuyCommand(string command, string arguments)
{
if (_ceruleumTankWindow.TryParseBuyRequest(arguments, out int missingQuantity))
_ceruleumTankWindow.StartPurchase(missingQuantity);
else
_chatGui.PrintError($"Usage: {command} <stacks>");
}
private void ProcessFillCommand(string command, string arguments)
{
if (_ceruleumTankWindow.TryParseFillRequest(arguments, out int missingQuantity))
_ceruleumTankWindow.StartPurchase(missingQuantity);
else
_chatGui.PrintError($"Usage: {command} <stacks>");
}
private void OpenMainUi()
=> _mainWindow.Toggle(MainWindow.EOpenReason.PluginInstaller);
2023-10-01 20:50:21 +00:00
public void Dispose()
{
2023-10-19 18:46:01 +00:00
_addonLifecycle.UnregisterListener(AddonEvent.PostUpdate, "ContextIconMenu", ContextIconMenuPostReceiveEvent);
_addonLifecycle.UnregisterListener(AddonEvent.PostRefresh, "Request", RequestPostRefresh);
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "Request", RequestPostSetup);
2023-10-13 20:08:22 +00:00
_addonLifecycle.UnregisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesNoPostSetup);
_commandManager.RemoveHandler("/fill-tanks");
_commandManager.RemoveHandler("/buy-tanks");
_commandManager.RemoveHandler("/workshoppa");
2023-10-01 20:50:21 +00:00
_commandManager.RemoveHandler("/ws");
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
2023-10-13 20:08:22 +00:00
_pluginInterface.UiBuilder.OpenConfigUi -= _configWindow.Toggle;
_pluginInterface.UiBuilder.OpenMainUi -= OpenMainUi;
2023-10-01 20:50:21 +00:00
_framework.Update -= FrameworkUpdate;
2023-10-24 22:19:42 +00:00
_ceruleumTankWindow.Dispose();
2023-10-13 20:08:22 +00:00
_repairKitWindow.Dispose();
2023-10-19 18:46:01 +00:00
_externalPluginHandler.RestoreTextAdvance();
_externalPluginHandler.Restore();
2023-10-01 20:50:21 +00:00
}
}