2023-10-01 20:50:21 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
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;
|
2023-10-01 20:50:21 +00:00
|
|
|
|
using Workshoppa.External;
|
|
|
|
|
using Workshoppa.GameData;
|
|
|
|
|
using Workshoppa.Windows;
|
|
|
|
|
|
|
|
|
|
namespace Workshoppa;
|
|
|
|
|
|
|
|
|
|
[SuppressMessage("ReSharper", "UnusedType.Global")]
|
|
|
|
|
public sealed partial class WorkshopPlugin : IDalamudPlugin
|
|
|
|
|
{
|
2023-10-05 19:56:12 +00:00
|
|
|
|
private readonly IReadOnlyList<uint> FabricationStationIds = new uint[] { 2005236, 2005238, 2005240, 2007821, 2011588 }.AsReadOnly();
|
|
|
|
|
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));
|
|
|
|
|
|
|
|
|
|
private readonly DalamudPluginInterface _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-01 20:50:21 +00:00
|
|
|
|
|
|
|
|
|
private readonly Configuration _configuration;
|
|
|
|
|
private readonly YesAlreadyIpc _yesAlreadyIpc;
|
|
|
|
|
private readonly WorkshopCache _workshopCache;
|
|
|
|
|
private readonly MainWindow _mainWindow;
|
|
|
|
|
|
|
|
|
|
private Stage _currentStageInternal = Stage.Stopped;
|
|
|
|
|
private DateTime _continueAt = DateTime.MinValue;
|
|
|
|
|
private (bool Saved, bool? PreviousState) _yesAlreadyState = (false, null);
|
|
|
|
|
|
2023-10-04 22:07:36 +00:00
|
|
|
|
public WorkshopPlugin(DalamudPluginInterface pluginInterface, IGameGui gameGui, IFramework framework,
|
|
|
|
|
ICondition condition, IClientState clientState, IObjectTable objectTable, IDataManager dataManager,
|
|
|
|
|
ICommandManager commandManager, IPluginLog pluginLog)
|
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-01 20:50:21 +00:00
|
|
|
|
|
2023-10-04 22:07:36 +00:00
|
|
|
|
var dalamudReflector = new DalamudReflector(_pluginInterface, _framework, _pluginLog);
|
2023-10-01 20:50:21 +00:00
|
|
|
|
_yesAlreadyIpc = new YesAlreadyIpc(dalamudReflector);
|
|
|
|
|
_configuration = (Configuration?)_pluginInterface.GetPluginConfig() ?? new Configuration();
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_workshopCache = new WorkshopCache(dataManager, _pluginLog);
|
2023-10-01 20:50:21 +00:00
|
|
|
|
|
2023-10-01 21:54:22 +00:00
|
|
|
|
_mainWindow = new(this, _pluginInterface, _clientState, _configuration, _workshopCache);
|
2023-10-01 20:50:21 +00:00
|
|
|
|
_windowSystem.AddWindow(_mainWindow);
|
|
|
|
|
|
|
|
|
|
_pluginInterface.UiBuilder.Draw += _windowSystem.Draw;
|
|
|
|
|
_pluginInterface.UiBuilder.OpenMainUi += _mainWindow.Toggle;
|
|
|
|
|
_framework.Update += FrameworkUpdate;
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_commandManager.AddHandler("/ws", new CommandInfo(ProcessCommand)
|
|
|
|
|
{
|
|
|
|
|
HelpMessage = "Open UI"
|
|
|
|
|
});
|
2023-10-01 20:50:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal Stage CurrentStage
|
|
|
|
|
{
|
|
|
|
|
get => _currentStageInternal;
|
|
|
|
|
private set
|
|
|
|
|
{
|
|
|
|
|
if (_currentStageInternal != value)
|
|
|
|
|
{
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_pluginLog.Information($"Changing stage from {_currentStageInternal} to {value}");
|
2023-10-01 20:50:21 +00:00
|
|
|
|
_currentStageInternal = value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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-05 19:56:12 +00:00
|
|
|
|
GetDistanceToEventObject(FabricationStationIds, out var fabricationStation) >= 5f)
|
2023-10-01 20:50:21 +00:00
|
|
|
|
{
|
|
|
|
|
_mainWindow.NearFabricationStation = false;
|
|
|
|
|
}
|
|
|
|
|
else if (DateTime.Now >= _continueAt)
|
|
|
|
|
{
|
|
|
|
|
_mainWindow.NearFabricationStation = true;
|
|
|
|
|
|
|
|
|
|
if (_mainWindow.State is MainWindow.ButtonState.Pause or MainWindow.ButtonState.Stop)
|
|
|
|
|
{
|
|
|
|
|
_mainWindow.State = MainWindow.ButtonState.None;
|
|
|
|
|
if (CurrentStage != Stage.Stopped)
|
|
|
|
|
{
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
CurrentStage = Stage.Stopped;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
else if (_mainWindow.State is MainWindow.ButtonState.Start or MainWindow.ButtonState.Resume && CurrentStage == Stage.Stopped)
|
|
|
|
|
{
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CurrentStage != Stage.Stopped && CurrentStage != Stage.RequestStop && !_yesAlreadyState.Saved)
|
|
|
|
|
SaveYesAlready();
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
if (InteractWithFabricationStation(fabricationStation!))
|
|
|
|
|
{
|
|
|
|
|
if (_configuration.CurrentlyCraftedItem is { StartedCrafting: true })
|
|
|
|
|
CurrentStage = Stage.SelectCraftBranch;
|
|
|
|
|
else
|
|
|
|
|
CurrentStage = Stage.OpenCraftingLog;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.OpenCraftingLog:
|
|
|
|
|
OpenCraftingLog();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.SelectCraftCategory:
|
|
|
|
|
SelectCraftCategory();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.SelectCraft:
|
|
|
|
|
SelectCraft();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.ConfirmCraft:
|
|
|
|
|
ConfirmCraft();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.RequestStop:
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
CurrentStage = Stage.Stopped;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.SelectCraftBranch:
|
|
|
|
|
SelectCraftBranch();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.ContributeMaterials:
|
|
|
|
|
ContributeMaterials();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.ConfirmMaterialDelivery:
|
|
|
|
|
ConfirmMaterialDelivery();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case Stage.ConfirmCollectProduct:
|
|
|
|
|
ConfirmCollectProduct();
|
|
|
|
|
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()
|
|
|
|
|
{
|
|
|
|
|
return _workshopCache.Crafts.Single(x => x.WorkshopItemId == _configuration.CurrentlyCraftedItem!.WorkshopItemId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ProcessCommand(string command, string arguments) => _mainWindow.Toggle();
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
_commandManager.RemoveHandler("/ws");
|
|
|
|
|
_pluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
|
|
|
|
|
_pluginInterface.UiBuilder.OpenMainUi -= _mainWindow.Toggle;
|
|
|
|
|
_framework.Update -= FrameworkUpdate;
|
|
|
|
|
|
|
|
|
|
RestoreYesAlready();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SaveYesAlready()
|
|
|
|
|
{
|
|
|
|
|
if (_yesAlreadyState.Saved)
|
|
|
|
|
{
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_pluginLog.Information("Not overwriting yesalready state");
|
2023-10-01 20:50:21 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_yesAlreadyState = (true, _yesAlreadyIpc.DisableIfNecessary());
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_pluginLog.Information($"Previous yesalready state: {_yesAlreadyState.PreviousState}");
|
2023-10-01 20:50:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RestoreYesAlready()
|
|
|
|
|
{
|
|
|
|
|
if (_yesAlreadyState.Saved)
|
|
|
|
|
{
|
2023-10-04 22:07:36 +00:00
|
|
|
|
_pluginLog.Information($"Restoring previous yesalready state: {_yesAlreadyState.PreviousState}");
|
2023-10-01 20:50:21 +00:00
|
|
|
|
if (_yesAlreadyState.PreviousState == true)
|
|
|
|
|
_yesAlreadyIpc.Enable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_yesAlreadyState = (false, null);
|
|
|
|
|
}
|
|
|
|
|
}
|