qstbak/Questionable/Questionable.Windows.JournalComponents/CustomDeliveryJournalComponent.cs
2026-08-17 20:29:32 +10:00

757 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using LLib.GameData;
using LLib.Inventory;
using LLib.Shop;
using Lumina.Excel;
using Lumina.Excel.Sheets;
using Microsoft.Extensions.Logging;
using Questionable.Controller;
using Questionable.Controller.CustomDelivery;
using Questionable.Data;
using Questionable.Model;
using Questionable.Model.Questing;
using Questionable.Windows.QuestComponents;
namespace Questionable.Windows.JournalComponents;
internal sealed class CustomDeliveryJournalComponent
{
private const int WeeklyAllowanceLimit = 12;
private const int DeliveriesPerWeek = 6;
private static readonly string[] SlotLabels = new string[3] { "Craft", "Gather", "Fish" };
private static readonly EDeliverySlot[] Slots = new EDeliverySlot[3]
{
EDeliverySlot.Craft,
EDeliverySlot.Gather,
EDeliverySlot.Fish
};
private static readonly string[] JobModeNames = new string[2] { "Preferred", "Current Job" };
private static readonly string[] CrafterNames = new string[8] { "Carpenter", "Blacksmith", "Armorer", "Goldsmith", "Leatherworker", "Weaver", "Alchemist", "Culinarian" };
private static readonly EClassJob[] CrafterJobs = new EClassJob[8]
{
EClassJob.Carpenter,
EClassJob.Blacksmith,
EClassJob.Armorer,
EClassJob.Goldsmith,
EClassJob.Leatherworker,
EClassJob.Weaver,
EClassJob.Alchemist,
EClassJob.Culinarian
};
private static readonly string[] GathererNames = new string[2] { "Miner", "Botanist" };
private static readonly EClassJob[] GathererJobs = new EClassJob[2]
{
EClassJob.Miner,
EClassJob.Botanist
};
private static readonly string[] OvercapModeNames = new string[3] { "Ignore", "Cap", "Block" };
private static readonly string[] CollectabilityTierNames = new string[3] { "High", "Mid", "Low" };
private readonly QuestController _questController;
private readonly CustomDeliveryController _customDeliveryController;
private readonly FateController _fateController;
private readonly SeasonalDutyController _seasonalDutyController;
private readonly AttunementController _attunementController;
private readonly DeliveryPlannerService _plannerService;
private readonly CustomDeliveryNpcData _customDeliveryNpcData;
private readonly SatisfactionSupplyHelper _supplyHelper;
private readonly DeliveryRewardCalculator _rewardCalculator;
private readonly QuestRegistry _questRegistry;
private readonly QuestTooltipComponent _questTooltip;
private readonly QuestData _questData;
private readonly Configuration _configuration;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly IDataManager _dataManager;
private readonly ILogger<CustomDeliveryJournalComponent> _logger;
private List<IGrouping<EExpansionVersion, CustomDeliveryNpc>>? _npcsByExpansion;
private readonly Dictionary<string, bool> _npcHeaderStates = new Dictionary<string, bool>();
public CustomDeliveryJournalComponent(QuestController questController, CustomDeliveryController customDeliveryController, FateController fateController, SeasonalDutyController seasonalDutyController, AttunementController attunementController, DeliveryPlannerService plannerService, CustomDeliveryNpcData customDeliveryNpcData, SatisfactionSupplyHelper supplyHelper, DeliveryRewardCalculator rewardCalculator, QuestRegistry questRegistry, QuestTooltipComponent questTooltip, QuestData questData, Configuration configuration, IDalamudPluginInterface pluginInterface, IDataManager dataManager, ILogger<CustomDeliveryJournalComponent> logger)
{
_questController = questController;
_customDeliveryController = customDeliveryController;
_fateController = fateController;
_seasonalDutyController = seasonalDutyController;
_attunementController = attunementController;
_plannerService = plannerService;
_customDeliveryNpcData = customDeliveryNpcData;
_supplyHelper = supplyHelper;
_rewardCalculator = rewardCalculator;
_questRegistry = questRegistry;
_questTooltip = questTooltip;
_questData = questData;
_configuration = configuration;
_pluginInterface = pluginInterface;
_dataManager = dataManager;
_logger = logger;
}
public void DrawCustomDeliveries()
{
DrawWeeklyAllowanceBar();
List<int> deliveryQueue = _configuration.CustomDeliveries.DeliveryQueue;
if (deliveryQueue.Count > 0)
{
ImGui.SameLine();
using (ImRaii.Disabled(_customDeliveryController.IsRunning || _questController.IsRunning || _fateController.IsRunning || _seasonalDutyController.IsRunning || _attunementController.IsRunning))
{
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Play, $"Start Queue ({deliveryQueue.Count})"))
{
_questController.Stop("Custom delivery queue start");
_fateController.Stop("Custom delivery queue start");
_seasonalDutyController.Stop("Custom delivery queue start");
_attunementController.Stop("Custom delivery queue start");
_customDeliveryController.StartQueue();
}
}
}
ImGui.Separator();
ImGui.Spacing();
DrawBonusNpcCallout();
DrawJobSelectionSettings();
ImGui.Spacing();
List<IGrouping<EExpansionVersion, CustomDeliveryNpc>> list = _npcsByExpansion ?? (_npcsByExpansion = (from x in _customDeliveryNpcData.AllNpcs
group x by x.Expansion into g
orderby (int)g.Key
select g).ToList());
if (list.Count == 0)
{
ImGui.TextColored(in UiThemeUtils.MutedTextColor, "No custom delivery NPCs found.");
return;
}
foreach (IGrouping<EExpansionVersion, CustomDeliveryNpc> item in list)
{
UiThemeUtils.SubSectionHeader(GetExpansionName(item.Key));
ImGui.Spacing();
foreach (CustomDeliveryNpc item2 in item.OrderBy((CustomDeliveryNpc x) => x.NpcRowId))
{
DrawNpcSection(item2, item2.NpcIndex);
}
ImGui.Spacing();
}
}
private static void DrawWeeklyAllowanceBar()
{
int remainingAllowances = SatisfactionSupplyActions.GetRemainingAllowances();
int num = 12 - remainingAllowances;
TimeSpan item = CalculateWeeklyReset().TimeUntilReset;
JournalUiShared.DrawAllowanceHeader(num, 12, "weekly allowances", item, $"Shared across all custom delivery NPCs\nUsed this week: {num}");
}
private void DrawBonusNpcCallout()
{
byte b = SatisfactionSupplyActions.GetBonusGuaranteeRowId();
if (b == byte.MaxValue)
{
int timestamp = (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds();
int num = _supplyHelper.CalculateBonusGuaranteeIndex(timestamp);
if (num < 0 || !_dataManager.GetExcelSheet<SatisfactionBonusGuarantee>().TryGetRow((uint)num, out var row))
{
return;
}
b = (byte)row.RowId;
}
if (_customDeliveryNpcData.TryGetByRowId(b, out CustomDeliveryNpc npc))
{
ImGui.TextColored(in UiThemeUtils.DimTextColor, "Bonus this week: ");
ImGui.SameLine(0f, 4f);
ImGui.TextColored(in UiThemeUtils.AccentColor, npc.Name);
ImGui.Spacing();
}
}
private void DrawJobSelectionSettings()
{
Configuration.CustomDeliveryConfiguration customDeliveries = _configuration.CustomDeliveries;
UiThemeUtils.SectionHeader("Job Preferences");
var (contentStartPos, availableWidth, drawList) = UiThemeUtils.BeginCard();
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X * 0.4f, 150f));
int currentItem = (int)customDeliveries.CraftJobMode;
if (UiThemeUtils.ThemedCombo("Crafter", ref currentItem, JobModeNames, JobModeNames.Length))
{
customDeliveries.CraftJobMode = (Configuration.CustomDeliveryConfiguration.EJobSelectionMode)currentItem;
_pluginInterface.SavePluginConfig(_configuration);
}
ImGui.SameLine();
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X, 150f));
int currentItem2 = Array.IndexOf(CrafterJobs, customDeliveries.PreferredCraftJob);
if (currentItem2 < 0)
{
currentItem2 = 0;
}
if (UiThemeUtils.ThemedCombo("##CrafterJob", ref currentItem2, CrafterNames, CrafterNames.Length))
{
customDeliveries.PreferredCraftJob = CrafterJobs[currentItem2];
_pluginInterface.SavePluginConfig(_configuration);
}
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X * 0.4f, 150f));
int currentItem3 = (int)customDeliveries.GatherJobMode;
if (UiThemeUtils.ThemedCombo("Gatherer", ref currentItem3, JobModeNames, JobModeNames.Length))
{
customDeliveries.GatherJobMode = (Configuration.CustomDeliveryConfiguration.EJobSelectionMode)currentItem3;
_pluginInterface.SavePluginConfig(_configuration);
}
ImGui.SameLine();
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X, 150f));
int currentItem4 = Array.IndexOf(GathererJobs, customDeliveries.PreferredGatherJob);
if (currentItem4 < 0)
{
currentItem4 = 0;
}
if (UiThemeUtils.ThemedCombo("##GathererJob", ref currentItem4, GathererNames, GathererNames.Length))
{
customDeliveries.PreferredGatherJob = GathererJobs[currentItem4];
_pluginInterface.SavePluginConfig(_configuration);
}
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X * 0.4f, 150f));
int currentItem5 = (int)customDeliveries.ScripOvercapMode;
if (UiThemeUtils.ThemedCombo("Scrip Overcap", ref currentItem5, OvercapModeNames, OvercapModeNames.Length))
{
customDeliveries.ScripOvercapMode = (Configuration.CustomDeliveryConfiguration.EScripOvercapMode)currentItem5;
_pluginInterface.SavePluginConfig(_configuration);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Ignore: no protection\nCap: reduce deliveries to avoid overcap\nBlock: skip NPC entirely if any delivery would overcap");
}
ImGui.SetNextItemWidth(MathF.Min(ImGui.GetContentRegionAvail().X * 0.4f, 150f));
int currentItem6 = (int)customDeliveries.CollectabilityTier;
if (UiThemeUtils.ThemedCombo("Collectability", ref currentItem6, CollectabilityTierNames, CollectabilityTierNames.Length))
{
customDeliveries.CollectabilityTier = (Configuration.CustomDeliveryConfiguration.ECollectabilityTier)currentItem6;
_pluginInterface.SavePluginConfig(_configuration);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("High: best rewards, requires good gear\nMid: moderate rewards, easier to hit\nLow: minimal rewards, lowest threshold");
}
UiThemeUtils.EndCard(contentStartPos, availableWidth, drawList);
}
private void DrawNpcSection(CustomDeliveryNpc npc, int npcIndex)
{
bool num = _plannerService.IsNpcUnlocked(npcIndex);
SatisfactionSupplyActions.NpcState npcState = SatisfactionSupplyActions.GetNpcState(npcIndex);
if (!num)
{
string value = (HasAnyDoHDoLAtLevel(npc.Level) ? "Locked" : "No DoH/DoL at level");
bool open = false;
UiThemeUtils.ThemedAccordion($"CustomDeliveryNpc{npcIndex}", npc.Name, $"Lv. {npc.Level} - {value}", ref open, enabled: false);
if (npc.UnlockQuestId.Value == 0)
{
return;
}
QuestId questId = npc.UnlockQuestId;
bool disabled = _questController.ManualPriorityQuests.Any((Questionable.Model.Quest q) => q.Id.Equals(questId));
ImGui.SameLine();
using (ImRaii.Disabled(disabled))
{
ImU8String id = new ImU8String(6, 1);
id.AppendLiteral("unlock");
id.AppendFormatted(npcIndex);
using (ImRaii.PushId(id))
{
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Unlock, "Unlock"))
{
_questController.AddQuestPriority(questId);
}
}
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled) && _questData.TryGetQuestInfo(questId, out IQuestInfo questInfo))
{
_questTooltip.Draw(questInfo);
}
return;
}
string text = $"CustomDeliveryNpc{npcIndex}";
bool open2 = _npcHeaderStates.GetValueOrDefault(text, defaultValue: false);
UiThemeUtils.ThemedAccordion(text, npc.Name, null, ref open2);
_npcHeaderStates[text] = open2;
if (!open2)
{
return;
}
using (ImRaii.PushIndent())
{
using (ImRaii.PushId(npcIndex))
{
DrawSatisfactionProgress(npcIndex, npcState);
int num2 = 6 - npcState.UsedDeliveries;
ImU8String text2 = new ImU8String(38, 3);
text2.AppendLiteral("Deliveries this week: ");
text2.AppendFormatted(npcState.UsedDeliveries);
text2.AppendLiteral(" / ");
text2.AppendFormatted(6);
text2.AppendLiteral(" (");
text2.AppendFormatted(num2);
text2.AppendLiteral(" remaining)");
ImGui.TextColored(in UiThemeUtils.DimTextColor, text2);
ImGui.Spacing();
DrawAchievementGoal(npcIndex, npcState);
DrawPredictedItems(npcIndex, npcState, num2);
}
}
}
private void DrawSatisfactionProgress(int npcIndex, SatisfactionSupplyActions.NpcState npcState)
{
int num = 0;
if (_dataManager.GetExcelSheet<SatisfactionNpc>().TryGetRow((uint)(npcIndex + 1), out var row) && npcState.Rank > 0 && npcState.Rank < row.SatisfactionNpcParams.Count)
{
num = row.SatisfactionNpcParams[npcState.Rank].SatisfactionRequired;
}
if (num <= 0)
{
ImU8String text = new ImU8String(5, 1);
text.AppendLiteral("Rank ");
text.AppendFormatted(npcState.Rank);
ImGui.TextColored(in UiThemeUtils.DimTextColor, text);
}
else
{
float fraction = (float)npcState.SatisfactionCurrent / (float)num;
ImU8String text2 = new ImU8String(9, 3);
text2.AppendLiteral("Rank ");
text2.AppendFormatted(npcState.Rank);
text2.AppendLiteral(" - ");
text2.AppendFormatted(npcState.SatisfactionCurrent);
text2.AppendLiteral("/");
text2.AppendFormatted(num);
ImGui.TextColored(in UiThemeUtils.DimTextColor, text2);
using (UiThemeUtils.PushProgressBarColors())
{
Vector2 sizeArg = new Vector2(-1E-45f, 0f);
ImU8String overlay = new ImU8String(1, 2);
overlay.AppendFormatted(npcState.SatisfactionCurrent);
overlay.AppendLiteral("/");
overlay.AppendFormatted(num);
ImGui.ProgressBar(fraction, sizeArg, overlay);
}
}
ImGui.Spacing();
}
private void DrawAchievementGoal(int npcIndex, SatisfactionSupplyActions.NpcState npcState)
{
ushort key = (ushort)(npcIndex + 1);
Dictionary<ushort, Configuration.AchievementGoal> achievementGoals = _configuration.CustomDeliveries.AchievementGoals;
achievementGoals.TryGetValue(key, out var value);
uint usedDeliveries = (uint)npcState.UsedDeliveries;
if (value != null && value.Active)
{
bool num = usedDeliveries >= value.TargetCount;
Vector4 col = (num ? UiThemeUtils.StatusComplete : UiThemeUtils.StatusActive);
ImU8String text = new ImU8String(9, 2);
text.AppendLiteral("Goal: ");
text.AppendFormatted(usedDeliveries);
text.AppendLiteral(" / ");
text.AppendFormatted(value.TargetCount);
ImGui.TextColored(in col, text);
if (num)
{
ImGui.SameLine();
ImGui.TextColored(in UiThemeUtils.StatusComplete, "(met)");
}
ImGui.SameLine();
if (UiThemeUtils.IconButton(FontAwesomeIcon.Edit, ImGui.GetFrameHeight()))
{
ImU8String strId = new ImU8String(8, 1);
strId.AppendLiteral("goalEdit");
strId.AppendFormatted(npcIndex);
ImGui.OpenPopup(strId);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Edit goal");
}
ImGui.SameLine();
if (UiThemeUtils.IconButton(FontAwesomeIcon.Times, ImGui.GetFrameHeight()))
{
achievementGoals.Remove(key);
_pluginInterface.SavePluginConfig(_configuration);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Remove goal");
}
}
else
{
if (UiThemeUtils.IconButton(FontAwesomeIcon.Bullseye, ImGui.GetFrameHeight()))
{
ImU8String strId2 = new ImU8String(8, 1);
strId2.AppendLiteral("goalEdit");
strId2.AppendFormatted(npcIndex);
ImGui.OpenPopup(strId2);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Set weekly delivery goal");
}
}
ImU8String strId3 = new ImU8String(8, 1);
strId3.AppendLiteral("goalEdit");
strId3.AppendFormatted(npcIndex);
if (ImGui.BeginPopup(strId3))
{
int data = (int)(value?.TargetCount ?? 6);
ImGui.SetNextItemWidth(100f);
if (ImGui.InputInt("Target", ref data, 1, 1) && data >= 1 && data <= 12)
{
if (value == null)
{
value = new Configuration.AchievementGoal();
}
value.TargetCount = (uint)data;
value.Active = true;
achievementGoals[key] = value;
_pluginInterface.SavePluginConfig(_configuration);
}
if (value != null)
{
bool value2 = value.Active;
if (UiThemeUtils.WrappedCheckbox("Active", ref value2))
{
value.Active = value2;
_pluginInterface.SavePluginConfig(_configuration);
}
}
ImGui.EndPopup();
}
ImGui.Spacing();
}
private void DrawPredictedItems(int npcIndex, SatisfactionSupplyActions.NpcState npcState, int deliveriesRemaining)
{
uint supplySeed = SatisfactionSupplyActions.GetSupplySeed();
if (supplySeed == 0)
{
ImGui.TextColored(in UiThemeUtils.MutedTextColor, "Log in to see predicted items.");
}
else
{
if (!_dataManager.GetExcelSheet<SatisfactionNpc>().TryGetRow((uint)(npcIndex + 1), out var row) || npcState.Rank <= 0 || npcState.Rank >= row.SatisfactionNpcParams.Count)
{
return;
}
uint supplyIndex = (uint)row.SatisfactionNpcParams[npcState.Rank].SupplyIndex;
uint[] array = _supplyHelper.CalculateRequestedItems(supplyIndex, supplySeed);
SubrowExcelSheet<SatisfactionSupply> subrowExcelSheet = _dataManager.GetSubrowExcelSheet<SatisfactionSupply>();
int remainingAllowances = SatisfactionSupplyActions.GetRemainingAllowances();
int num;
if (_customDeliveryController.State != CustomDeliveryController.EDeliveryState.Idle)
{
DeliveryPlan? currentPlan = _customDeliveryController.CurrentPlan;
num = ((currentPlan != null && currentPlan.NpcIndex == npcIndex) ? 1 : 0);
}
else
{
num = 0;
}
bool flag = (byte)num != 0;
for (int i = 0; i < 3; i++)
{
using (ImRaii.PushId(i))
{
EDeliverySlot eDeliverySlot = Slots[i];
string value = SlotLabels[i];
uint num2 = array[i];
if (num2 == uint.MaxValue)
{
ImU8String text = new ImU8String(4, 1);
text.AppendLiteral("[");
text.AppendFormatted(value);
text.AppendLiteral("] -");
ImGui.TextColored(in UiThemeUtils.MutedTextColor, text);
continue;
}
if (!subrowExcelSheet.TryGetSubrow(supplyIndex, (ushort)num2, out var subrow))
{
ImU8String text2 = new ImU8String(4, 1);
text2.AppendLiteral("[");
text2.AppendFormatted(value);
text2.AppendLiteral("] ?");
ImGui.TextColored(in UiThemeUtils.MutedTextColor, text2);
continue;
}
uint rowId = subrow.Item.RowId;
string itemName = GetItemName(rowId);
ImU8String text3 = new ImU8String(2, 1);
text3.AppendLiteral("[");
text3.AppendFormatted(value);
text3.AppendLiteral("]");
ImGui.TextColored(in UiThemeUtils.DimTextColor, text3);
ImGui.SameLine(0f, 6f);
float x;
using (ImRaii.PushFont(UiBuilder.IconFont))
{
x = ImGui.CalcTextSize(FontAwesomeIcon.Play.ToIconString()).X;
}
float reservedRightWidth = x + 6f + ImGui.CalcTextSize("Start").X + ImGui.GetStyle().FramePadding.X * 2f + ImGui.GetStyle().ItemSpacing.X;
UiThemeUtils.RowLabel(itemName, reservedRightWidth);
bool flag2 = !flag && remainingAllowances > 0 && deliveriesRemaining > 0 && _customDeliveryController.State == CustomDeliveryController.EDeliveryState.Idle && !_questController.IsRunning && !_fateController.IsRunning && !_seasonalDutyController.IsRunning && !_attunementController.IsRunning;
ImGui.SameLine();
using (ImRaii.Disabled(!flag2))
{
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Play, "Start"))
{
_logger.LogInformation("Starting custom delivery for NPC {NpcIndex} slot {Slot}", npcIndex, eDeliverySlot);
_questController.Stop("Custom delivery start");
_fateController.Stop("Custom delivery start");
_seasonalDutyController.Stop("Custom delivery start");
_attunementController.Stop("Custom delivery start");
_customDeliveryController.Start(npcIndex, eDeliverySlot);
}
}
if (!flag2 && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
if (_questController.IsRunning)
{
ImGui.SetTooltip("Quest automation is running. Stop it first.");
}
else if (_fateController.IsRunning)
{
ImGui.SetTooltip("FATE farming is running. Stop it first.");
}
else if (_seasonalDutyController.IsRunning)
{
ImGui.SetTooltip("Seasonal duty farming is running. Stop it first.");
}
else if (_attunementController.IsRunning)
{
ImGui.SetTooltip("Attunement is running. Stop it first.");
}
else if (flag)
{
ImGui.SetTooltip("Automation is already running for this NPC.");
}
else if (_customDeliveryController.State != CustomDeliveryController.EDeliveryState.Idle)
{
ImGui.SetTooltip("Another delivery is already in progress.");
}
else if (remainingAllowances <= 0)
{
ImGui.SetTooltip("No weekly allowances remaining.");
}
else
{
ImGui.SetTooltip("No deliveries remaining for this NPC this week.");
}
}
uint rowId2 = subrow.Reward.RowId;
bool isBonus = subrow.IsBonus;
List<DeliveryRewardCalculator.CurrencyReward> list = _rewardCalculator.CalculateRewards(rowId2, isBonus, _configuration.CustomDeliveries.CollectabilityTier);
if (list.Count <= 0)
{
continue;
}
string text4 = string.Join(", ", list.ConvertAll((DeliveryRewardCalculator.CurrencyReward r) => $"{r.AmountPerDelivery} {r.CurrencyName}"));
using (ImRaii.PushIndent())
{
UiThemeUtils.WrappedTextColored(UiThemeUtils.DimTextColor, "Rewards: " + text4);
foreach (DeliveryRewardCalculator.CurrencyReward item in list)
{
if (!DeliveryRewardCalculator.WouldOvercap(item.CurrencyItemId, item.AmountPerDelivery, deliveriesRemaining))
{
continue;
}
using (ImRaii.PushColor(ImGuiCol.Text, UiThemeUtils.StatusActive))
{
using (ImRaii.PushFont(UiBuilder.IconFont))
{
ImGui.Text(FontAwesomeIcon.ExclamationTriangle.ToIconString());
}
ImGui.SameLine(0f, 4f);
int itemCount = InventoryHelper.GetItemCount(item.CurrencyItemId);
int value2 = item.AmountPerDelivery * deliveriesRemaining;
UiThemeUtils.WrappedText($"{item.CurrencyName} would overcap ({itemCount} + {value2})");
}
}
}
}
}
List<int> deliveryQueue = _configuration.CustomDeliveries.DeliveryQueue;
int num3 = deliveryQueue.IndexOf(npcIndex);
if (num3 >= 0)
{
using (ImRaii.Disabled(num3 == 0))
{
if (UiThemeUtils.IconButton(FontAwesomeIcon.ArrowUp, ImGui.GetFrameHeight()))
{
deliveryQueue.RemoveAt(num3);
deliveryQueue.Insert(num3 - 1, npcIndex);
_pluginInterface.SavePluginConfig(_configuration);
}
}
if (ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled))
{
ImU8String tooltip = new ImU8String(19, 2);
tooltip.AppendLiteral("Queue position: ");
tooltip.AppendFormatted(num3 + 1);
tooltip.AppendLiteral(" / ");
tooltip.AppendFormatted(deliveryQueue.Count);
ImGui.SetTooltip(tooltip);
}
ImGui.SameLine();
using (ImRaii.Disabled(num3 == deliveryQueue.Count - 1))
{
if (UiThemeUtils.IconButton(FontAwesomeIcon.ArrowDown, ImGui.GetFrameHeight()))
{
deliveryQueue.RemoveAt(num3);
deliveryQueue.Insert(num3 + 1, npcIndex);
_pluginInterface.SavePluginConfig(_configuration);
}
}
ImGui.SameLine();
if (UiThemeUtils.IconButton(FontAwesomeIcon.Minus, ImGui.GetFrameHeight()))
{
deliveryQueue.Remove(npcIndex);
_pluginInterface.SavePluginConfig(_configuration);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Remove from delivery queue");
}
}
else
{
if (UiThemeUtils.IconButton(FontAwesomeIcon.Plus, ImGui.GetFrameHeight()))
{
deliveryQueue.Add(npcIndex);
_pluginInterface.SavePluginConfig(_configuration);
}
if (ImGui.IsItemHovered())
{
ImGui.SetTooltip("Add to delivery queue");
}
}
if (flag)
{
ImGui.Spacing();
DeliveryPlan currentPlan2 = _customDeliveryController.CurrentPlan;
ImGui.TextColored(in UiThemeUtils.StatusActive, _customDeliveryController.State switch
{
CustomDeliveryController.EDeliveryState.WaitingForCraft => "Waiting for craft...",
CustomDeliveryController.EDeliveryState.WaitingForGather => "Waiting for gather...",
CustomDeliveryController.EDeliveryState.WaitingForFish => "Waiting for fish...",
CustomDeliveryController.EDeliveryState.TurningIn => "Turning in...",
CustomDeliveryController.EDeliveryState.Executing => "Executing...",
CustomDeliveryController.EDeliveryState.Complete => "Complete.",
_ => "Running...",
});
if (currentPlan2 != null)
{
string itemName2 = GetItemName(currentPlan2.ItemId);
ImU8String text5 = new ImU8String(6, 1);
text5.AppendLiteral("Item: ");
text5.AppendFormatted(itemName2);
ImGui.TextColored(in UiThemeUtils.DimTextColor, text5);
}
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Stop, "Stop"))
{
_customDeliveryController.Stop("User requested stop");
}
}
ImGui.Spacing();
}
}
private bool HasAnyDoHDoLAtLevel(ushort requiredLevel)
{
ExcelSheet<ClassJob> excelSheet = _dataManager.GetExcelSheet<ClassJob>();
EClassJob[] array = new EClassJob[11]
{
EClassJob.Carpenter,
EClassJob.Blacksmith,
EClassJob.Armorer,
EClassJob.Goldsmith,
EClassJob.Leatherworker,
EClassJob.Weaver,
EClassJob.Alchemist,
EClassJob.Culinarian,
EClassJob.Miner,
EClassJob.Botanist,
EClassJob.Fisher
};
foreach (EClassJob rowId in array)
{
if (excelSheet.TryGetRow((uint)rowId, out var row) && PlayerStateHelper.GetClassJobLevel(row.ExpArrayIndex) >= requiredLevel)
{
return true;
}
}
return false;
}
private string GetItemName(uint itemId)
{
if (_dataManager.GetExcelSheet<Item>().TryGetRow(itemId, out var row))
{
return row.Name.ToString();
}
return $"Item#{itemId}";
}
private static (DateTime ResetTime, TimeSpan TimeUntilReset) CalculateWeeklyReset()
{
DateTime utcNow = DateTime.UtcNow;
int num = (int)(2 - utcNow.DayOfWeek + 7) % 7;
DateTime dateTime = utcNow.Date.AddDays(num).AddHours(8.0);
if (dateTime <= utcNow)
{
dateTime = dateTime.AddDays(7.0);
}
TimeSpan item = dateTime - utcNow;
return (ResetTime: dateTime.ToLocalTime(), TimeUntilReset: item);
}
private static string GetExpansionName(EExpansionVersion expansion)
{
return expansion switch
{
EExpansionVersion.ARealmReborn => "A Realm Reborn",
EExpansionVersion.Heavensward => "Heavensward",
EExpansionVersion.Stormblood => "Stormblood",
EExpansionVersion.Shadowbringers => "Shadowbringers",
EExpansionVersion.Endwalker => "Endwalker",
EExpansionVersion.Dawntrail => "Dawntrail",
_ => expansion.ToString(),
};
}
}