Show rank requirements when expert delivery is locked

This commit is contained in:
Liza 2024-04-26 10:01:23 +02:00
parent 33ad4617c9
commit 79f8959852
Signed by: liza
GPG Key ID: 7199F8D727D55F67
4 changed files with 121 additions and 6 deletions

View File

@ -28,7 +28,7 @@ partial class DeliverooPlugin
(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)obj.Address, false);
}
private unsafe int GetCurrentSealCount()
internal unsafe int GetCurrentSealCount()
{
InventoryManager* inventoryManager = InventoryManager.Instance();
switch ((GrandCompany)PlayerState.Instance()->GrandCompany)
@ -93,9 +93,22 @@ partial class DeliverooPlugin
};
}
private uint GetSealCap() => _sealCaps.TryGetValue(GetGrandCompanyRank(), out var cap) ? cap : 0;
private uint GetSealCap() => _gcRankInfo.TryGetValue(GetGrandCompanyRank(), out var rank) ? rank.MaxSeals : 0;
public uint MaxSealCap => _sealCaps[11];
public uint MaxSealCap => _gcRankInfo[11].MaxSeals;
internal uint GetSealsRequiredForNextRank()
=> _gcRankInfo.GetValueOrDefault(GetGrandCompanyRank())?.RequiredSeals ?? 0;
internal byte GetRequiredHuntingLogForNextRank()
=> _gcRankInfo.GetValueOrDefault(GetGrandCompanyRank() + 1u)?.RequiredHuntingLog ?? 0;
internal string? GetNextGrandCompanyRankName()
{
bool female = _clientState.LocalPlayer!.Customize[(int)CustomizeIndex.Gender] == 1;
GrandCompany grandCompany = GetGrandCompany();
return _gcRankInfo.GetValueOrDefault(GetGrandCompanyRank() + 1u)?.GetName(grandCompany, female);
}
public unsafe int GetItemCount(uint itemId, bool checkRetainerInventory)
{

View File

@ -19,6 +19,7 @@ using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Component.GUI;
using LLib;
using LLib.GameUI;
using Lumina.Excel;
using Lumina.Excel.GeneratedSheets;
namespace Deliveroo;
@ -52,7 +53,7 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
private readonly ItemCache _itemCache;
private readonly ConfigWindow _configWindow;
private readonly TurnInWindow _turnInWindow;
private readonly ReadOnlyDictionary<uint, uint> _sealCaps;
private readonly ReadOnlyDictionary<uint, GcRankInfo> _gcRankInfo;
private readonly Dictionary<uint, int> _retainerItemCache = new();
private Stage _currentStageInternal = Stage.Stopped;
@ -90,8 +91,20 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_windowSystem.AddWindow(_configWindow);
_turnInWindow = new TurnInWindow(this, _pluginInterface, _configuration, _condition, _clientState, _gcRewardsCache, _configWindow, _iconCache);
_windowSystem.AddWindow(_turnInWindow);
_sealCaps = dataManager.GetExcelSheet<GrandCompanyRank>()!.Where(x => x.RowId > 0)
.ToDictionary(x => x.RowId, x => x.MaxSeals)
_gcRankInfo = dataManager.GetExcelSheet<GrandCompanyRank>()!.Where(x => x.RowId > 0)
.ToDictionary(x => x.RowId, x => new GcRankInfo
{
NameTwinAddersMale = ExtractRankName<GCRankGridaniaMaleText>(dataManager, x.RowId, r => r.Singular),
NameTwinAddersFemale = ExtractRankName<GCRankGridaniaFemaleText>(dataManager, x.RowId, r => r.Singular),
NameMaelstromMale = ExtractRankName<GCRankLimsaMaleText>(dataManager, x.RowId, r => r.Singular),
NameMaelstromFemale = ExtractRankName<GCRankLimsaFemaleText>(dataManager, x.RowId, r => r.Singular),
NameImmortalFlamesMale = ExtractRankName<GCRankUldahMaleText>(dataManager, x.RowId, r => r.Singular),
NameImmortalFlamesFemale = ExtractRankName<GCRankUldahFemaleText>(dataManager, x.RowId, r => r.Singular),
MaxSeals = x.MaxSeals,
RequiredSeals = x.RequiredSeals,
RequiredHuntingLog = x.Unknown10,
})
.AsReadOnly();
_framework.Update += FrameworkUpdate;
@ -116,6 +129,12 @@ public sealed partial class DeliverooPlugin : IDalamudPlugin
_addonLifecycle.RegisterListener(AddonEvent.PostSetup, "SelectYesno", SelectYesNoPostSetup);
}
private static string ExtractRankName<T>(IDataManager dataManager, uint rankId, Func<T, Lumina.Text.SeString> func)
where T : ExcelRow
{
return func(dataManager.GetExcelSheet<T>()!.GetRow(rankId)!).ToString();
}
private void ChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
{
if (_configuration.PauseAtRank <= 0)

View File

@ -0,0 +1,33 @@
using System;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
namespace Deliveroo.GameData
{
internal sealed class GcRankInfo
{
public required string NameTwinAddersMale { private get; init; }
public required string NameTwinAddersFemale { private get; init; }
public required string NameMaelstromMale { private get; init; }
public required string NameMaelstromFemale { private get; init; }
public required string NameImmortalFlamesMale { private get; init; }
public required string NameImmortalFlamesFemale { private get; init; }
public required uint MaxSeals { get; init; }
public required uint RequiredSeals { get; init; }
public required byte RequiredHuntingLog { get; init; }
public string GetName(GrandCompany grandCompany, bool female)
{
return (grandCompany, female) switch
{
(GrandCompany.TwinAdder, false) => NameTwinAddersMale,
(GrandCompany.TwinAdder, true) => NameTwinAddersFemale,
(GrandCompany.Maelstrom, false) => NameMaelstromMale,
(GrandCompany.Maelstrom, true) => NameMaelstromFemale,
(GrandCompany.ImmortalFlames, false) => NameImmortalFlamesMale,
(GrandCompany.ImmortalFlames, true) => NameImmortalFlamesFemale,
_ => throw new ArgumentOutOfRangeException(nameof(grandCompany) + "," + nameof(female)),
};
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Components;
@ -108,6 +109,7 @@ internal sealed class TurnInWindow : LWindow
Flags = ImGuiWindowFlags.AlwaysAutoResize;
}
}
public decimal Multiplier { private get; set; }
public string Error { private get; set; } = string.Empty;
@ -186,6 +188,8 @@ internal sealed class TurnInWindow : LWindow
{
State = false;
ImGui.TextColored(ImGuiColors.DalamudRed, "You do not have the required rank for Expert Delivery.");
DrawNextRankPrequesites();
return;
}
else if (_configuration.BehaviorOnOtherWorld == Configuration.EBehaviorOnOtherWorld.DisableTurnIn &&
@ -256,6 +260,52 @@ internal sealed class TurnInWindow : LWindow
ImGui.Text($"Debug (State): {_plugin.CurrentStage}");
}
private unsafe void DrawNextRankPrequesites()
{
string? rankName = _plugin.GetNextGrandCompanyRankName();
if (rankName != null)
{
int currentSeals = _plugin.GetCurrentSealCount();
uint requiredSeals = _plugin.GetSealsRequiredForNextRank();
int currentHuntingLog = MonsterNoteManager.Instance()->RankDataArraySpan[(int)_plugin.GetGrandCompany() + 7]
.Rank;
byte requiredHuntingLog = _plugin.GetRequiredHuntingLogForNextRank();
bool enoughSeals = currentSeals >= requiredSeals;
bool enoughHuntingLog = requiredHuntingLog >= currentHuntingLog;
if (enoughSeals && enoughHuntingLog)
ImGui.TextColored(ImGuiColors.HealerGreen, $"You meet all requirements to rank up to {rankName}.");
else
ImGui.Text($"Ranking up to {rankName} requires:");
ImGui.Indent();
if (enoughSeals)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
ImGui.BulletText($"{currentSeals:N0} / {requiredSeals:N0} GC seals");
ImGui.PopStyleColor();
}
else
ImGui.BulletText($"{currentSeals:N0} / {requiredSeals:N0} GC seals");
if (requiredHuntingLog > 0)
{
if (enoughHuntingLog)
{
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.HealerGreen);
ImGui.BulletText($"Complete Hunting Log #{requiredHuntingLog}");
ImGui.PopStyleColor();
}
else
ImGui.BulletText($"Complete Hunting Log #{requiredHuntingLog}");
}
ImGui.Unindent();
}
}
private void DrawItemsToBuy(GrandCompany grandCompany)
{
var itemsWrapper = ItemsWrapper;