mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
Update to Lumina 5 (new Excel parsing) (#2022)
* Refactor and upgrade to new excel design * Obsolete ExcelResolver<T> and use only RowRef<T> * Better benchmarking for Lumina * Add custom game-supported RSV provider * Refactor and move Lazy<T> and nullable/cached row objects to RowRefs * Convert IRSVProvider to delegate, resolve strings by default * Split IExcelRow into IExcelSubrow * Extra lumina documentation * Minor RSV CS fixes * Fix UIGlowPayload warning * Fix rebase * Update to Lumina 5
This commit is contained in:
parent
08d8605871
commit
0b9af0e3f4
49 changed files with 460 additions and 403 deletions
|
|
@ -27,8 +27,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Lumina" Version="4.2.1" />
|
<PackageReference Include="Lumina" Version="5.0.0" />
|
||||||
<PackageReference Include="Lumina.Excel" Version="7.0.1" />
|
<PackageReference Include="Lumina.Excel" Version="7.0.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.333">
|
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.333">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
<PackageReference Include="goaaats.Reloaded.Hooks" Version="4.2.0-goat.4" />
|
<PackageReference Include="goaaats.Reloaded.Hooks" Version="4.2.0-goat.4" />
|
||||||
<PackageReference Include="goaaats.Reloaded.Assembler" Version="1.0.14-goat.2" />
|
<PackageReference Include="goaaats.Reloaded.Assembler" Version="1.0.14-goat.2" />
|
||||||
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2024.2.0" />
|
||||||
<PackageReference Include="Lumina" Version="4.2.1" />
|
<PackageReference Include="Lumina" Version="5.0.0" />
|
||||||
<PackageReference Include="Lumina.Excel" Version="7.0.1" />
|
<PackageReference Include="Lumina.Excel" Version="7.0.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="9.0.0-preview.1.24081.5" />
|
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="9.0.0-preview.1.24081.5" />
|
||||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.46-beta">
|
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.46-beta">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using Dalamud.Utility.Timing;
|
||||||
using Lumina;
|
using Lumina;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|
@ -28,12 +29,15 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
|
||||||
{
|
{
|
||||||
private readonly Thread luminaResourceThread;
|
private readonly Thread luminaResourceThread;
|
||||||
private readonly CancellationTokenSource luminaCancellationTokenSource;
|
private readonly CancellationTokenSource luminaCancellationTokenSource;
|
||||||
|
private readonly RsvResolver rsvResolver;
|
||||||
|
|
||||||
[ServiceManager.ServiceConstructor]
|
[ServiceManager.ServiceConstructor]
|
||||||
private DataManager(Dalamud dalamud)
|
private DataManager(Dalamud dalamud)
|
||||||
{
|
{
|
||||||
this.Language = (ClientLanguage)dalamud.StartInfo.Language;
|
this.Language = (ClientLanguage)dalamud.StartInfo.Language;
|
||||||
|
|
||||||
|
this.rsvResolver = new();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Verbose("Starting data load...");
|
Log.Verbose("Starting data load...");
|
||||||
|
|
@ -44,11 +48,8 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
|
||||||
{
|
{
|
||||||
LoadMultithreaded = true,
|
LoadMultithreaded = true,
|
||||||
CacheFileResources = true,
|
CacheFileResources = true,
|
||||||
#if NEVER // Lumina bug
|
|
||||||
PanicOnSheetChecksumMismatch = true,
|
PanicOnSheetChecksumMismatch = true,
|
||||||
#else
|
RsvResolver = this.rsvResolver.TryResolve,
|
||||||
PanicOnSheetChecksumMismatch = false,
|
|
||||||
#endif
|
|
||||||
DefaultExcelLanguage = this.Language.ToLumina(),
|
DefaultExcelLanguage = this.Language.ToLumina(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -129,12 +130,12 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
|
||||||
#region Lumina Wrappers
|
#region Lumina Wrappers
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelSheet<T>? GetExcelSheet<T>() where T : ExcelRow
|
public ExcelSheet<T> GetExcelSheet<T>(ClientLanguage? language = null, string? name = null) where T : struct, IExcelRow<T>
|
||||||
=> this.Excel.GetSheet<T>();
|
=> this.Excel.GetSheet<T>(language?.ToLumina(), name);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelSheet<T>? GetExcelSheet<T>(ClientLanguage language) where T : ExcelRow
|
public SubrowExcelSheet<T> GetSubrowExcelSheet<T>(ClientLanguage? language = null, string? name = null) where T : struct, IExcelSubrow<T>
|
||||||
=> this.Excel.GetSheet<T>(language.ToLumina());
|
=> this.Excel.GetSubrowSheet<T>(language?.ToLumina(), name);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public FileResource? GetFile(string path)
|
public FileResource? GetFile(string path)
|
||||||
|
|
@ -170,6 +171,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
|
||||||
{
|
{
|
||||||
this.luminaCancellationTokenSource.Cancel();
|
this.luminaCancellationTokenSource.Cancel();
|
||||||
this.GameData.Dispose();
|
this.GameData.Dispose();
|
||||||
|
this.rsvResolver.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LauncherTroubleshootingInfo
|
private class LauncherTroubleshootingInfo
|
||||||
|
|
|
||||||
22
Dalamud/Data/LuminaUtils.cs
Normal file
22
Dalamud/Data/LuminaUtils.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
|
namespace Dalamud.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A helper class to easily resolve Lumina data within Dalamud.
|
||||||
|
/// </summary>
|
||||||
|
internal static class LuminaUtils
|
||||||
|
{
|
||||||
|
private static ExcelModule Module => Service<DataManager>.Get().Excel;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RowRef{T}"/> class using the default <see cref="ExcelModule"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of Lumina sheet to resolve.</typeparam>
|
||||||
|
/// <param name="rowId">The id of the row to resolve.</param>
|
||||||
|
/// <returns>A new <see cref="RowRef{T}"/> object.</returns>
|
||||||
|
public static RowRef<T> CreateRef<T>(uint rowId) where T : struct, IExcelRow<T>
|
||||||
|
{
|
||||||
|
return new(Module, rowId);
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Dalamud/Data/RsvResolver.cs
Normal file
51
Dalamud/Data/RsvResolver.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Dalamud.Hooking;
|
||||||
|
using Dalamud.Logging.Internal;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
|
||||||
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
||||||
|
namespace Dalamud.Data;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides functionality for resolving RSV strings.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed unsafe class RsvResolver : IDisposable
|
||||||
|
{
|
||||||
|
private static readonly ModuleLog Log = new("RsvProvider");
|
||||||
|
|
||||||
|
private readonly Hook<LayoutWorld.Delegates.AddRsvString> addRsvStringHook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RsvResolver"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public RsvResolver()
|
||||||
|
{
|
||||||
|
this.addRsvStringHook = Hook<LayoutWorld.Delegates.AddRsvString>.FromAddress((nint)LayoutWorld.MemberFunctionPointers.AddRsvString, this.AddRsvStringDetour);
|
||||||
|
|
||||||
|
this.addRsvStringHook.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<ReadOnlySeString, ReadOnlySeString> Lookup { get; } = [];
|
||||||
|
|
||||||
|
/// <summary>Attemps to resolve an RSV string.</summary>
|
||||||
|
/// <inheritdoc cref="Lumina.Excel.ExcelModule.ResolveRsvDelegate"/>
|
||||||
|
public bool TryResolve(ReadOnlySeString rsvString, out ReadOnlySeString resolvedString) =>
|
||||||
|
this.Lookup.TryGetValue(rsvString, out resolvedString);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
this.addRsvStringHook.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool AddRsvStringDetour(LayoutWorld* @this, byte* rsvString, byte* resolvedString, nuint resolvedStringSize)
|
||||||
|
{
|
||||||
|
var rsv = new ReadOnlySeString(MemoryHelper.ReadRawNullTerminated((nint)rsvString));
|
||||||
|
var resolved = new ReadOnlySeString(new ReadOnlySpan<byte>(resolvedString, (int)resolvedStringSize).ToArray());
|
||||||
|
Log.Debug($"Resolving RSV \"{rsv}\" to \"{resolved}\".");
|
||||||
|
this.Lookup[rsv] = resolved;
|
||||||
|
return this.addRsvStringHook.Original(@this, rsvString, resolvedString, resolvedStringSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
using Dalamud.Data;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Aetherytes;
|
namespace Dalamud.Game.ClientState.Aetherytes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -56,7 +59,7 @@ public interface IAetheryteEntry
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Aetheryte data related to this aetheryte.
|
/// Gets the Aetheryte data related to this aetheryte.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.Aetheryte> AetheryteData { get; }
|
RowRef<Lumina.Excel.Sheets.Aetheryte> AetheryteData { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -103,5 +106,5 @@ internal sealed class AetheryteEntry : IAetheryteEntry
|
||||||
public bool IsApartment => this.data.IsApartment;
|
public bool IsApartment => this.data.IsApartment;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Aetheryte> AetheryteData => new(this.AetheryteId);
|
public RowRef<Lumina.Excel.Sheets.Aetheryte> AetheryteData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.Aetheryte>(this.AetheryteId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Buddy;
|
namespace Dalamud.Game.ClientState.Buddy;
|
||||||
|
|
||||||
|
|
@ -45,17 +47,17 @@ public interface IBuddyMember
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Mount data related to this buddy. It should only be used with companion buddies.
|
/// Gets the Mount data related to this buddy. It should only be used with companion buddies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.Mount> MountData { get; }
|
RowRef<Lumina.Excel.Sheets.Mount> MountData { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Pet data related to this buddy. It should only be used with pet buddies.
|
/// Gets the Pet data related to this buddy. It should only be used with pet buddies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.Pet> PetData { get; }
|
RowRef<Lumina.Excel.Sheets.Pet> PetData { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Trust data related to this buddy. It should only be used with battle buddies.
|
/// Gets the Trust data related to this buddy. It should only be used with battle buddies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData { get; }
|
RowRef<Lumina.Excel.Sheets.DawnGrowMember> TrustData { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -94,13 +96,13 @@ internal unsafe class BuddyMember : IBuddyMember
|
||||||
public uint DataID => this.Struct->DataId;
|
public uint DataID => this.Struct->DataId;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Mount> MountData => new(this.DataID);
|
public RowRef<Lumina.Excel.Sheets.Mount> MountData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.Mount>(this.DataID);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Pet> PetData => new(this.DataID);
|
public RowRef<Lumina.Excel.Sheets.Pet> PetData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.Pet>(this.DataID);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData => new(this.DataID);
|
public RowRef<Lumina.Excel.Sheets.DawnGrowMember> TrustData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.DawnGrowMember>(this.DataID);
|
||||||
|
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
|
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Event;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
using Action = System.Action;
|
using Action = System.Action;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Fates;
|
namespace Dalamud.Game.ClientState.Fates;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -20,7 +21,7 @@ public interface IFate : IEquatable<IFate>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets game data linked to this Fate.
|
/// Gets game data linked to this Fate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Lumina.Excel.GeneratedSheets.Fate GameData { get; }
|
RowRef<Lumina.Excel.Sheets.Fate> GameData { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time this <see cref="Fate"/> started.
|
/// Gets the time this <see cref="Fate"/> started.
|
||||||
|
|
@ -105,7 +106,7 @@ public interface IFate : IEquatable<IFate>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the territory this <see cref="Fate"/> is located in.
|
/// Gets the territory this <see cref="Fate"/> is located in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> TerritoryType { get; }
|
RowRef<Lumina.Excel.Sheets.TerritoryType> TerritoryType { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of this Fate in memory.
|
/// Gets the address of this Fate in memory.
|
||||||
|
|
@ -185,7 +186,7 @@ internal unsafe partial class Fate : IFate
|
||||||
public ushort FateId => this.Struct->FateId;
|
public ushort FateId => this.Struct->FateId;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Lumina.Excel.GeneratedSheets.Fate GameData => Service<DataManager>.Get().GetExcelSheet<Lumina.Excel.GeneratedSheets.Fate>().GetRow(this.FateId);
|
public RowRef<Lumina.Excel.Sheets.Fate> GameData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.Fate>(this.FateId);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int StartTimeEpoch => this.Struct->StartTimeEpoch;
|
public int StartTimeEpoch => this.Struct->StartTimeEpoch;
|
||||||
|
|
@ -238,5 +239,5 @@ internal unsafe partial class Fate : IFate
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the territory this <see cref="Fate"/> is located in.
|
/// Gets the territory this <see cref="Fate"/> is located in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> TerritoryType => new(this.Struct->TerritoryId);
|
public RowRef<Lumina.Excel.Sheets.TerritoryType> TerritoryType => LuminaUtils.CreateRef<Lumina.Excel.Sheets.TerritoryType>(this.Struct->TerritoryId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,13 @@ public unsafe class SMNGauge : JobGaugeBase<SummonerGauge>
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the summon that will return after the current summon expires.
|
/// Gets the summon that will return after the current summon expires.
|
||||||
/// This maps to the <see cref="Lumina.Excel.GeneratedSheets.Pet"/> sheet.
|
/// This maps to the <see cref="Lumina.Excel.Sheets.Pet"/> sheet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public SummonPet ReturnSummon => (SummonPet)this.Struct->ReturnSummon;
|
public SummonPet ReturnSummon => (SummonPet)this.Struct->ReturnSummon;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
||||||
/// This maps to the <see cref="Lumina.Excel.GeneratedSheets.PetMirage"/> sheet.
|
/// This maps to the <see cref="Lumina.Excel.Sheets.PetMirage"/> sheet.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PetGlam ReturnSummonGlam => (PetGlam)this.Struct->ReturnSummonGlam;
|
public PetGlam ReturnSummonGlam => (PetGlam)this.Struct->ReturnSummonGlam;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,8 @@
|
||||||
using System.Numerics;
|
using Dalamud.Data;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.ClientState.Statuses;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
|
||||||
|
|
@ -16,14 +12,14 @@ namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
public interface IPlayerCharacter : IBattleChara
|
public interface IPlayerCharacter : IBattleChara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
|
/// Gets the current <see cref="RowRef{T}">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<World> CurrentWorld { get; }
|
RowRef<World> CurrentWorld { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
|
/// Gets the home <see cref="RowRef{T}">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<World> HomeWorld { get; }
|
RowRef<World> HomeWorld { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -42,10 +38,10 @@ internal unsafe class PlayerCharacter : BattleChara, IPlayerCharacter
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelResolver<World> CurrentWorld => new(this.Struct->CurrentWorld);
|
public RowRef<World> CurrentWorld => LuminaUtils.CreateRef<World>(this.Struct->CurrentWorld);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelResolver<World> HomeWorld => new(this.Struct->HomeWorld);
|
public RowRef<World> HomeWorld => LuminaUtils.CreateRef<World>(this.Struct->HomeWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target actor ID of the PlayerCharacter.
|
/// Gets the target actor ID of the PlayerCharacter.
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Objects.Types;
|
namespace Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
|
||||||
|
|
@ -61,7 +63,7 @@ public interface ICharacter : IGameObject
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ClassJob of this Chara.
|
/// Gets the ClassJob of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<ClassJob> ClassJob { get; }
|
public RowRef<ClassJob> ClassJob { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of this Chara.
|
/// Gets the level of this Chara.
|
||||||
|
|
@ -87,7 +89,7 @@ public interface ICharacter : IGameObject
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current online status of the character.
|
/// Gets the current online status of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<OnlineStatus> OnlineStatus { get; }
|
public RowRef<OnlineStatus> OnlineStatus { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the status flags.
|
/// Gets the status flags.
|
||||||
|
|
@ -97,14 +99,14 @@ public interface ICharacter : IGameObject
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current mount for this character. Will be <c>null</c> if the character doesn't have a mount.
|
/// Gets the current mount for this character. Will be <c>null</c> if the character doesn't have a mount.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Mount>? CurrentMount { get; }
|
public RowRef<Mount>? CurrentMount { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current minion summoned for this character. Will be <c>null</c> if the character doesn't have a minion.
|
/// Gets the current minion summoned for this character. Will be <c>null</c> if the character doesn't have a minion.
|
||||||
/// This method *will* return information about a spawned (but invisible) minion, e.g. if the character is riding a
|
/// This method *will* return information about a spawned (but invisible) minion, e.g. if the character is riding a
|
||||||
/// mount.
|
/// mount.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Companion>? CurrentMinion { get; }
|
public RowRef<Companion>? CurrentMinion { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -150,7 +152,7 @@ internal unsafe class Character : GameObject, ICharacter
|
||||||
public byte ShieldPercentage => this.Struct->CharacterData.ShieldValue;
|
public byte ShieldPercentage => this.Struct->CharacterData.ShieldValue;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelResolver<ClassJob> ClassJob => new(this.Struct->CharacterData.ClassJob);
|
public RowRef<ClassJob> ClassJob => LuminaUtils.CreateRef<ClassJob>(this.Struct->CharacterData.ClassJob);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public byte Level => this.Struct->CharacterData.Level;
|
public byte Level => this.Struct->CharacterData.Level;
|
||||||
|
|
@ -170,7 +172,7 @@ internal unsafe class Character : GameObject, ICharacter
|
||||||
public uint NameId => this.Struct->NameId;
|
public uint NameId => this.Struct->NameId;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ExcelResolver<OnlineStatus> OnlineStatus => new(this.Struct->CharacterData.OnlineStatus);
|
public RowRef<OnlineStatus> OnlineStatus => LuminaUtils.CreateRef<OnlineStatus>(this.Struct->CharacterData.OnlineStatus);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the status flags.
|
/// Gets the status flags.
|
||||||
|
|
@ -186,28 +188,28 @@ internal unsafe class Character : GameObject, ICharacter
|
||||||
(this.Struct->IsCasting ? StatusFlags.IsCasting : StatusFlags.None);
|
(this.Struct->IsCasting ? StatusFlags.IsCasting : StatusFlags.None);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Mount>? CurrentMount
|
public RowRef<Mount>? CurrentMount
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (this.Struct->IsNotMounted()) return null; // just for safety.
|
if (this.Struct->IsNotMounted()) return null; // just for safety.
|
||||||
|
|
||||||
var mountId = this.Struct->Mount.MountId;
|
var mountId = this.Struct->Mount.MountId;
|
||||||
return mountId == 0 ? null : new ExcelResolver<Mount>(mountId);
|
return mountId == 0 ? null : LuminaUtils.CreateRef<Mount>(mountId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ExcelResolver<Companion>? CurrentMinion
|
public RowRef<Companion>? CurrentMinion
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (this.Struct->CompanionObject != null)
|
if (this.Struct->CompanionObject != null)
|
||||||
return new ExcelResolver<Companion>(this.Struct->CompanionObject->BaseId);
|
return LuminaUtils.CreateRef<Companion>(this.Struct->CompanionObject->BaseId);
|
||||||
|
|
||||||
// this is only present if a minion is summoned but hidden (e.g. the player's on a mount).
|
// this is only present if a minion is summoned but hidden (e.g. the player's on a mount).
|
||||||
var hiddenCompanionId = this.Struct->CompanionData.CompanionId;
|
var hiddenCompanionId = this.Struct->CompanionData.CompanionId;
|
||||||
return hiddenCompanionId == 0 ? null : new ExcelResolver<Companion>(hiddenCompanionId);
|
return hiddenCompanionId == 0 ? null : LuminaUtils.CreateRef<Companion>(hiddenCompanionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.ClientState.Statuses;
|
using Dalamud.Game.ClientState.Statuses;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Memory;
|
using Dalamud.Memory;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Party;
|
namespace Dalamud.Game.ClientState.Party;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -71,12 +73,12 @@ public interface IPartyMember
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the territory this party member is located in.
|
/// Gets the territory this party member is located in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> Territory { get; }
|
RowRef<Lumina.Excel.Sheets.TerritoryType> Territory { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the World this party member resides in.
|
/// Gets the World this party member resides in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.World> World { get; }
|
RowRef<Lumina.Excel.Sheets.World> World { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the displayname of this party member.
|
/// Gets the displayname of this party member.
|
||||||
|
|
@ -91,7 +93,7 @@ public interface IPartyMember
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the classjob of this party member.
|
/// Gets the classjob of this party member.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> ClassJob { get; }
|
RowRef<Lumina.Excel.Sheets.ClassJob> ClassJob { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of this party member.
|
/// Gets the level of this party member.
|
||||||
|
|
@ -169,12 +171,12 @@ internal unsafe class PartyMember : IPartyMember
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the territory this party member is located in.
|
/// Gets the territory this party member is located in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> Territory => new(this.Struct->TerritoryType);
|
public RowRef<Lumina.Excel.Sheets.TerritoryType> Territory => LuminaUtils.CreateRef<Lumina.Excel.Sheets.TerritoryType>(this.Struct->TerritoryType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the World this party member resides in.
|
/// Gets the World this party member resides in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> World => new(this.Struct->HomeWorld);
|
public RowRef<Lumina.Excel.Sheets.World> World => LuminaUtils.CreateRef<Lumina.Excel.Sheets.World>(this.Struct->HomeWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the displayname of this party member.
|
/// Gets the displayname of this party member.
|
||||||
|
|
@ -189,7 +191,7 @@ internal unsafe class PartyMember : IPartyMember
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the classjob of this party member.
|
/// Gets the classjob of this party member.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> ClassJob => new(this.Struct->ClassJob);
|
public RowRef<Lumina.Excel.Sheets.ClassJob> ClassJob => LuminaUtils.CreateRef<Lumina.Excel.Sheets.ClassJob>(this.Struct->ClassJob);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of this party member.
|
/// Gets the level of this party member.
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
using Dalamud.Data;
|
|
||||||
|
|
||||||
using Lumina.Excel;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Resolvers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// This object resolves a rowID within an Excel sheet.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">The type of Lumina sheet to resolve.</typeparam>
|
|
||||||
public class ExcelResolver<T> where T : ExcelRow
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ExcelResolver{T}"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The ID of the classJob.</param>
|
|
||||||
internal ExcelResolver(uint id)
|
|
||||||
{
|
|
||||||
this.Id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ID to be resolved.
|
|
||||||
/// </summary>
|
|
||||||
public uint Id { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets GameData linked to this excel row.
|
|
||||||
/// </summary>
|
|
||||||
public T? GameData => Service<DataManager>.Get().GetExcelSheet<T>()?.GetRow(this.Id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets GameData linked to this excel row with the specified language.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="language">The language.</param>
|
|
||||||
/// <returns>The ExcelRow in the specified language.</returns>
|
|
||||||
public T? GetWithLanguage(ClientLanguage language) => Service<DataManager>.Get().GetExcelSheet<T>(language)?.GetRow(this.Id);
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Statuses;
|
namespace Dalamud.Game.ClientState.Statuses;
|
||||||
|
|
||||||
|
|
@ -31,7 +33,7 @@ public unsafe class Status
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the GameData associated with this status.
|
/// Gets the GameData associated with this status.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver<Lumina.Excel.GeneratedSheets.Status>(this.Struct->StatusId).GameData;
|
public RowRef<Lumina.Excel.Sheets.Status> GameData => LuminaUtils.CreateRef<Lumina.Excel.Sheets.Status>(this.Struct->StatusId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the parameter value of the status.
|
/// Gets the parameter value of the status.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Dalamud.Game.Text;
|
using Dalamud.Game.Text;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui.ContextMenu;
|
namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.Network.Structures.InfoProxy;
|
using Dalamud.Game.Network.Structures.InfoProxy;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui.ContextMenu;
|
namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
|
|
||||||
|
|
@ -46,7 +47,7 @@ public sealed unsafe class MenuTargetDefault : MenuTarget
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home world id of the target.
|
/// Gets the home world id of the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<World> TargetHomeWorld => new((uint)this.Context->TargetHomeWorldId);
|
public RowRef<World> TargetHomeWorld => LuminaUtils.CreateRef<World>((uint)this.Context->TargetHomeWorldId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently targeted character. Only shows up for specific targets, like friends, party finder listings, or party members.
|
/// Gets the currently targeted character. Only shows up for specific targets, like friends, party finder listings, or party members.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui.PartyFinder.Types;
|
namespace Dalamud.Game.Gui.PartyFinder.Types;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ using Dalamud.Data;
|
||||||
using Dalamud.Game.Gui.PartyFinder.Internal;
|
using Dalamud.Game.Gui.PartyFinder.Internal;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui.PartyFinder.Types;
|
namespace Dalamud.Game.Gui.PartyFinder.Types;
|
||||||
|
|
||||||
|
|
@ -48,7 +49,7 @@ public interface IPartyFinderListing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of the classes/jobs that are currently present in the party.
|
/// Gets a list of the classes/jobs that are currently present in the party.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IReadOnlyCollection<Lazy<ClassJob>> JobsPresent { get; }
|
IReadOnlyCollection<RowRef<ClassJob>> JobsPresent { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID assigned to this listing by the game's server.
|
/// Gets the ID assigned to this listing by the game's server.
|
||||||
|
|
@ -73,17 +74,17 @@ public interface IPartyFinderListing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the world that this listing was created on.
|
/// Gets the world that this listing was created on.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Lazy<World> World { get; }
|
RowRef<World> World { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home world of the listing's host.
|
/// Gets the home world of the listing's host.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Lazy<World> HomeWorld { get; }
|
RowRef<World> HomeWorld { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current world of the listing's host.
|
/// Gets the current world of the listing's host.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Lazy<World> CurrentWorld { get; }
|
RowRef<World> CurrentWorld { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Party Finder category this listing is listed under.
|
/// Gets the Party Finder category this listing is listed under.
|
||||||
|
|
@ -98,7 +99,7 @@ public interface IPartyFinderListing
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the duty this listing is for. May be null for non-duty listings.
|
/// Gets the duty this listing is for. May be null for non-duty listings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Lazy<ContentFinderCondition> Duty { get; }
|
RowRef<ContentFinderCondition> Duty { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of duty this listing is for.
|
/// Gets the type of duty this listing is for.
|
||||||
|
|
@ -216,12 +217,12 @@ internal class PartyFinderListing : IPartyFinderListing
|
||||||
this.ContentId = listing.ContentId;
|
this.ContentId = listing.ContentId;
|
||||||
this.Name = SeString.Parse(listing.Name.TakeWhile(b => b != 0).ToArray());
|
this.Name = SeString.Parse(listing.Name.TakeWhile(b => b != 0).ToArray());
|
||||||
this.Description = SeString.Parse(listing.Description.TakeWhile(b => b != 0).ToArray());
|
this.Description = SeString.Parse(listing.Description.TakeWhile(b => b != 0).ToArray());
|
||||||
this.World = new Lazy<World>(() => dataManager.GetExcelSheet<World>().GetRow(listing.World));
|
this.World = LuminaUtils.CreateRef<World>(listing.World);
|
||||||
this.HomeWorld = new Lazy<World>(() => dataManager.GetExcelSheet<World>().GetRow(listing.HomeWorld));
|
this.HomeWorld = LuminaUtils.CreateRef<World>(listing.HomeWorld);
|
||||||
this.CurrentWorld = new Lazy<World>(() => dataManager.GetExcelSheet<World>().GetRow(listing.CurrentWorld));
|
this.CurrentWorld = LuminaUtils.CreateRef<World>(listing.CurrentWorld);
|
||||||
this.Category = (DutyCategory)listing.Category;
|
this.Category = (DutyCategory)listing.Category;
|
||||||
this.RawDuty = listing.Duty;
|
this.RawDuty = listing.Duty;
|
||||||
this.Duty = new Lazy<ContentFinderCondition>(() => dataManager.GetExcelSheet<ContentFinderCondition>().GetRow(listing.Duty));
|
this.Duty = LuminaUtils.CreateRef<ContentFinderCondition>(listing.Duty);
|
||||||
this.DutyType = (DutyType)listing.DutyType;
|
this.DutyType = (DutyType)listing.DutyType;
|
||||||
this.BeginnersWelcome = listing.BeginnersWelcome == 1;
|
this.BeginnersWelcome = listing.BeginnersWelcome == 1;
|
||||||
this.SecondsRemaining = listing.SecondsRemaining;
|
this.SecondsRemaining = listing.SecondsRemaining;
|
||||||
|
|
@ -231,10 +232,7 @@ internal class PartyFinderListing : IPartyFinderListing
|
||||||
this.SlotsFilled = listing.NumSlotsFilled;
|
this.SlotsFilled = listing.NumSlotsFilled;
|
||||||
this.LastPatchHotfixTimestamp = listing.LastPatchHotfixTimestamp;
|
this.LastPatchHotfixTimestamp = listing.LastPatchHotfixTimestamp;
|
||||||
this.JobsPresent = listing.JobsPresent
|
this.JobsPresent = listing.JobsPresent
|
||||||
.Select(id => new Lazy<ClassJob>(
|
.Select(id => LuminaUtils.CreateRef<ClassJob>(id))
|
||||||
() => id == 0
|
|
||||||
? null
|
|
||||||
: dataManager.GetExcelSheet<ClassJob>().GetRow(id)))
|
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,13 +249,13 @@ internal class PartyFinderListing : IPartyFinderListing
|
||||||
public SeString Description { get; }
|
public SeString Description { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Lazy<World> World { get; }
|
public RowRef<World> World { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Lazy<World> HomeWorld { get; }
|
public RowRef<World> HomeWorld { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Lazy<World> CurrentWorld { get; }
|
public RowRef<World> CurrentWorld { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DutyCategory Category { get; }
|
public DutyCategory Category { get; }
|
||||||
|
|
@ -266,7 +264,7 @@ internal class PartyFinderListing : IPartyFinderListing
|
||||||
public ushort RawDuty { get; }
|
public ushort RawDuty { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Lazy<ContentFinderCondition> Duty { get; }
|
public RowRef<ContentFinderCondition> Duty { get; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DutyType DutyType { get; }
|
public DutyType DutyType { get; }
|
||||||
|
|
@ -314,7 +312,7 @@ internal class PartyFinderListing : IPartyFinderListing
|
||||||
public IReadOnlyCollection<byte> RawJobsPresent => this.jobsPresent;
|
public IReadOnlyCollection<byte> RawJobsPresent => this.jobsPresent;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlyCollection<Lazy<ClassJob>> JobsPresent { get; }
|
public IReadOnlyCollection<RowRef<ClassJob>> JobsPresent { get; }
|
||||||
|
|
||||||
#region Indexers
|
#region Indexers
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
|
||||||
|
|
||||||
var uploadObject = new UniversalisItemUploadRequest
|
var uploadObject = new UniversalisItemUploadRequest
|
||||||
{
|
{
|
||||||
WorldId = clientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
WorldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0,
|
||||||
UploaderId = uploader.ToString(),
|
UploaderId = uploader.ToString(),
|
||||||
ItemId = request.Listings.FirstOrDefault()?.CatalogId ?? 0,
|
ItemId = request.Listings.FirstOrDefault()?.CatalogId ?? 0,
|
||||||
Listings = [],
|
Listings = [],
|
||||||
|
|
@ -120,7 +120,7 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
|
||||||
|
|
||||||
var taxUploadObject = new UniversalisTaxUploadRequest
|
var taxUploadObject = new UniversalisTaxUploadRequest
|
||||||
{
|
{
|
||||||
WorldId = clientState.LocalPlayer?.CurrentWorld.Id ?? 0,
|
WorldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0,
|
||||||
UploaderId = clientState.LocalContentId.ToString(),
|
UploaderId = clientState.LocalContentId.ToString(),
|
||||||
TaxData = new UniversalisTaxData
|
TaxData = new UniversalisTaxData
|
||||||
{
|
{
|
||||||
|
|
@ -158,7 +158,7 @@ internal class UniversalisMarketBoardUploader : IMarketBoardUploader
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var itemId = purchaseHandler.CatalogId;
|
var itemId = purchaseHandler.CatalogId;
|
||||||
var worldId = clientState.LocalPlayer?.CurrentWorld.Id ?? 0;
|
var worldId = clientState.LocalPlayer?.CurrentWorld.RowId ?? 0;
|
||||||
|
|
||||||
// ====================================================================================
|
// ====================================================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ using Dalamud.Hooking;
|
||||||
using Dalamud.Networking.Http;
|
using Dalamud.Networking.Http;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Internal;
|
namespace Dalamud.Game.Network.Internal;
|
||||||
|
|
@ -282,21 +282,17 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
|
||||||
if (this.configuration.DutyFinderTaskbarFlash)
|
if (this.configuration.DutyFinderTaskbarFlash)
|
||||||
Util.FlashWindow();
|
Util.FlashWindow();
|
||||||
|
|
||||||
var cfConditionSheet = Service<DataManager>.Get().GetExcelSheet<ContentFinderCondition>()!;
|
var cfCondition = LuminaUtils.CreateRef<ContentFinderCondition>(conditionId);
|
||||||
var cfCondition = cfConditionSheet.GetRow(conditionId);
|
|
||||||
|
|
||||||
if (cfCondition == null)
|
if (!cfCondition.IsValid)
|
||||||
{
|
{
|
||||||
Log.Error("CFC key {ConditionId} not in Lumina data", conditionId);
|
Log.Error("CFC key {ConditionId} not in Lumina data", conditionId);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cfcName = cfCondition.Name.ToDalamudString();
|
var cfcName = cfCondition.Value.Name.ToDalamudString();
|
||||||
if (cfcName.Payloads.Count == 0)
|
if (cfcName.Payloads.Count == 0)
|
||||||
{
|
|
||||||
cfcName = "Duty Roulette";
|
cfcName = "Duty Roulette";
|
||||||
cfCondition.Image = 112324;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
|
@ -308,7 +304,7 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
|
||||||
Service<ChatGui>.GetNullable()?.Print(b.Build());
|
Service<ChatGui>.GetNullable()?.Print(b.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.CfPop.InvokeSafely(cfCondition);
|
this.CfPop.InvokeSafely(cfCondition.Value);
|
||||||
}).ContinueWith(
|
}).ContinueWith(
|
||||||
task => Log.Error(task.Exception, "CfPop.Invoke failed"),
|
task => Log.Error(task.Exception, "CfPop.Invoke failed"),
|
||||||
TaskContinuationOptions.OnlyOnFaulted);
|
TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
using Dalamud.Data;
|
||||||
using Dalamud.Memory;
|
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.Network.Structures.InfoProxy;
|
namespace Dalamud.Game.Network.Structures.InfoProxy;
|
||||||
|
|
||||||
|
|
@ -92,15 +92,15 @@ public unsafe class CharacterData
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the applicable statues of the character.
|
/// Gets the applicable statues of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<ExcelResolver<OnlineStatus>> Statuses
|
public IReadOnlyList<RowRef<OnlineStatus>> Statuses
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var statuses = new List<ExcelResolver<OnlineStatus>>();
|
var statuses = new List<RowRef<OnlineStatus>>();
|
||||||
for (var i = 0; i < 64; i++)
|
for (var i = 0; i < 64; i++)
|
||||||
{
|
{
|
||||||
if ((this.StatusMask & (1UL << i)) != 0)
|
if ((this.StatusMask & (1UL << i)) != 0)
|
||||||
statuses.Add(new((uint)i));
|
statuses.Add(LuminaUtils.CreateRef<OnlineStatus>((uint)i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return statuses;
|
return statuses;
|
||||||
|
|
@ -125,22 +125,22 @@ public unsafe class CharacterData
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current world of the character.
|
/// Gets the current world of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<World> CurrentWorld => new(this.Struct->CurrentWorld);
|
public RowRef<World> CurrentWorld => LuminaUtils.CreateRef<World>(this.Struct->CurrentWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home world of the character.
|
/// Gets the home world of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<World> HomeWorld => new(this.Struct->HomeWorld);
|
public RowRef<World> HomeWorld => LuminaUtils.CreateRef<World>(this.Struct->HomeWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the location of the character.
|
/// Gets the location of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<TerritoryType> Location => new(this.Struct->Location);
|
public RowRef<TerritoryType> Location => LuminaUtils.CreateRef<TerritoryType>(this.Struct->Location);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the grand company of the character.
|
/// Gets the grand company of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<GrandCompany> GrandCompany => new((uint)this.Struct->GrandCompany);
|
public RowRef<GrandCompany> GrandCompany => LuminaUtils.CreateRef<GrandCompany>((uint)this.Struct->GrandCompany);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the primary client language of the character.
|
/// Gets the primary client language of the character.
|
||||||
|
|
@ -178,7 +178,7 @@ public unsafe class CharacterData
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the job of the character.
|
/// Gets the job of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<ClassJob> ClassJob => new(this.Struct->Job);
|
public RowRef<ClassJob> ClassJob => LuminaUtils.CreateRef<ClassJob>(this.Struct->Job);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the character.
|
/// Gets the name of the character.
|
||||||
|
|
|
||||||
|
|
@ -38,13 +38,6 @@ public abstract partial class Payload
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Dirty { get; protected set; } = true;
|
public bool Dirty { get; protected set; } = true;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Lumina instance to use for any necessary data lookups.
|
|
||||||
/// </summary>
|
|
||||||
[JsonIgnore]
|
|
||||||
// TODO: We should refactor this. It should not be possible to get IDataManager through here.
|
|
||||||
protected IDataManager DataResolver => Service<DataManager>.Get();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decodes a binary representation of a payload into its corresponding nice object payload.
|
/// Decodes a binary representation of a payload into its corresponding nice object payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,11 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|
@ -106,28 +110,28 @@ public class AutoTranslatePayload : Payload, ITextProvider
|
||||||
this.Key = GetInteger(reader);
|
this.Key = GetInteger(reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ReadOnlySeString ResolveTextCommand(TextCommand command)
|
||||||
|
{
|
||||||
|
// TextCommands prioritize the `Alias` field, if it not empty
|
||||||
|
// Example for this is /rangerpose2l which becomes /blackrangerposeb in chat
|
||||||
|
return !command.Alias.IsEmpty ? command.Alias : command.Command;
|
||||||
|
}
|
||||||
|
|
||||||
private string Resolve()
|
private string Resolve()
|
||||||
{
|
{
|
||||||
string value = null;
|
string value = null;
|
||||||
|
|
||||||
var sheet = this.DataResolver.GetExcelSheet<Completion>();
|
var excelModule = Service<DataManager>.Get().Excel;
|
||||||
|
var completionSheet = excelModule.GetSheet<Completion>();
|
||||||
|
|
||||||
Completion row = null;
|
// try to get the row in the Completion table itself, because this is 'easiest'
|
||||||
try
|
// The row may not exist at all (if the Key is for another table), or it could be the wrong row
|
||||||
{
|
// (again, if it's meant for another table)
|
||||||
// try to get the row in the Completion table itself, because this is 'easiest'
|
|
||||||
// The row may not exist at all (if the Key is for another table), or it could be the wrong row
|
|
||||||
// (again, if it's meant for another table)
|
|
||||||
row = sheet.GetRow(this.Key);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
} // don't care, row will be null
|
|
||||||
|
|
||||||
if (row?.Group == this.Group)
|
if (completionSheet.GetRowOrDefault(this.Key) is { } completion && completion.Group == this.Group)
|
||||||
{
|
{
|
||||||
// if the row exists in this table and the group matches, this is actually the correct data
|
// if the row exists in this table and the group matches, this is actually the correct data
|
||||||
value = row.Text;
|
value = completion.Text.ExtractText();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -135,34 +139,34 @@ public class AutoTranslatePayload : Payload, ITextProvider
|
||||||
{
|
{
|
||||||
// we need to get the linked table and do the lookup there instead
|
// we need to get the linked table and do the lookup there instead
|
||||||
// in this case, there will only be one entry for this group id
|
// in this case, there will only be one entry for this group id
|
||||||
row = sheet.First(r => r.Group == this.Group);
|
var row = completionSheet.First(r => r.Group == this.Group);
|
||||||
// many of the names contain valid id ranges after the table name, but we don't need those
|
// many of the names contain valid id ranges after the table name, but we don't need those
|
||||||
var actualTableName = row.LookupTable.RawString.Split('[')[0];
|
var actualTableName = row.LookupTable.ExtractText().Split('[')[0];
|
||||||
|
|
||||||
var name = actualTableName switch
|
var name = actualTableName switch
|
||||||
{
|
{
|
||||||
"Action" => this.DataResolver.GetExcelSheet<Lumina.Excel.GeneratedSheets.Action>().GetRow(this.Key).Name,
|
"Action" => excelModule.GetSheet<Lumina.Excel.Sheets.Action>().GetRow(this.Key).Name,
|
||||||
"ActionComboRoute" => this.DataResolver.GetExcelSheet<ActionComboRoute>().GetRow(this.Key).Name,
|
"ActionComboRoute" => excelModule.GetSheet<ActionComboRoute>().GetRow(this.Key).Name,
|
||||||
"BuddyAction" => this.DataResolver.GetExcelSheet<BuddyAction>().GetRow(this.Key).Name,
|
"BuddyAction" => excelModule.GetSheet<BuddyAction>().GetRow(this.Key).Name,
|
||||||
"ClassJob" => this.DataResolver.GetExcelSheet<ClassJob>().GetRow(this.Key).Name,
|
"ClassJob" => excelModule.GetSheet<ClassJob>().GetRow(this.Key).Name,
|
||||||
"Companion" => this.DataResolver.GetExcelSheet<Companion>().GetRow(this.Key).Singular,
|
"Companion" => excelModule.GetSheet<Companion>().GetRow(this.Key).Singular,
|
||||||
"CraftAction" => this.DataResolver.GetExcelSheet<CraftAction>().GetRow(this.Key).Name,
|
"CraftAction" => excelModule.GetSheet<CraftAction>().GetRow(this.Key).Name,
|
||||||
"GeneralAction" => this.DataResolver.GetExcelSheet<GeneralAction>().GetRow(this.Key).Name,
|
"GeneralAction" => excelModule.GetSheet<GeneralAction>().GetRow(this.Key).Name,
|
||||||
"GuardianDeity" => this.DataResolver.GetExcelSheet<GuardianDeity>().GetRow(this.Key).Name,
|
"GuardianDeity" => excelModule.GetSheet<GuardianDeity>().GetRow(this.Key).Name,
|
||||||
"MainCommand" => this.DataResolver.GetExcelSheet<MainCommand>().GetRow(this.Key).Name,
|
"MainCommand" => excelModule.GetSheet<MainCommand>().GetRow(this.Key).Name,
|
||||||
"Mount" => this.DataResolver.GetExcelSheet<Mount>().GetRow(this.Key).Singular,
|
"Mount" => excelModule.GetSheet<Mount>().GetRow(this.Key).Singular,
|
||||||
"Pet" => this.DataResolver.GetExcelSheet<Pet>().GetRow(this.Key).Name,
|
"Pet" => excelModule.GetSheet<Pet>().GetRow(this.Key).Name,
|
||||||
"PetAction" => this.DataResolver.GetExcelSheet<PetAction>().GetRow(this.Key).Name,
|
"PetAction" => excelModule.GetSheet<PetAction>().GetRow(this.Key).Name,
|
||||||
"PetMirage" => this.DataResolver.GetExcelSheet<PetMirage>().GetRow(this.Key).Name,
|
"PetMirage" => excelModule.GetSheet<PetMirage>().GetRow(this.Key).Name,
|
||||||
"PlaceName" => this.DataResolver.GetExcelSheet<PlaceName>().GetRow(this.Key).Name,
|
"PlaceName" => excelModule.GetSheet<PlaceName>().GetRow(this.Key).Name,
|
||||||
"Race" => this.DataResolver.GetExcelSheet<Race>().GetRow(this.Key).Masculine,
|
"Race" => excelModule.GetSheet<Race>().GetRow(this.Key).Masculine,
|
||||||
"TextCommand" => this.ResolveTextCommand(),
|
"TextCommand" => AutoTranslatePayload.ResolveTextCommand(excelModule.GetSheet<TextCommand>().GetRow(this.Key)),
|
||||||
"Tribe" => this.DataResolver.GetExcelSheet<Tribe>().GetRow(this.Key).Masculine,
|
"Tribe" => excelModule.GetSheet<Tribe>().GetRow(this.Key).Masculine,
|
||||||
"Weather" => this.DataResolver.GetExcelSheet<Weather>().GetRow(this.Key).Name,
|
"Weather" => excelModule.GetSheet<Weather>().GetRow(this.Key).Name,
|
||||||
_ => throw new Exception(actualTableName),
|
_ => throw new Exception(actualTableName),
|
||||||
};
|
};
|
||||||
|
|
||||||
value = name;
|
value = name.ExtractText();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -172,12 +176,4 @@ public class AutoTranslatePayload : Payload, ITextProvider
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lumina.Text.SeString ResolveTextCommand()
|
|
||||||
{
|
|
||||||
// TextCommands prioritize the `Alias` field, if it not empty
|
|
||||||
// Example for this is /rangerpose2l which becomes /blackrangerposeb in chat
|
|
||||||
var result = this.DataResolver.GetExcelSheet<TextCommand>().GetRow(this.Key);
|
|
||||||
return result.Alias.Payloads.Count > 0 ? result.Alias : result.Command;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
||||||
|
|
@ -14,8 +15,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ItemPayload : Payload
|
public class ItemPayload : Payload
|
||||||
{
|
{
|
||||||
private Item? item;
|
|
||||||
|
|
||||||
// mainly to allow overriding the name (for things like owo)
|
// mainly to allow overriding the name (for things like owo)
|
||||||
// TODO: even though this is present in some item links, it may not really have a use at all
|
// TODO: even though this is present in some item links, it may not really have a use at all
|
||||||
// For things like owo, changing the text payload is probably correct, whereas changing the
|
// For things like owo, changing the text payload is probably correct, whereas changing the
|
||||||
|
|
@ -131,27 +130,13 @@ public class ItemPayload : Payload
|
||||||
public uint RawItemId => this.rawItemId;
|
public uint RawItemId => this.rawItemId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying Lumina Item represented by this payload.
|
/// Gets the underlying Lumina data represented by this payload. This is either a Item or EventItem <see cref="RowRef{T}"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Item? Item
|
public RowRef Item =>
|
||||||
{
|
this.Kind == ItemKind.EventItem
|
||||||
get
|
? (RowRef)LuminaUtils.CreateRef<EventItem>(this.ItemId)
|
||||||
{
|
: (RowRef)LuminaUtils.CreateRef<Item>(this.ItemId);
|
||||||
// TODO(goat): This should be revamped/removed on an API level change.
|
|
||||||
if (this.Kind == ItemKind.EventItem)
|
|
||||||
{
|
|
||||||
Log.Warning("Event items cannot be fetched from the ItemPayload");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.item ??= this.DataResolver.GetExcelSheet<Item>()!.GetRow(this.ItemId);
|
|
||||||
return this.item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether or not this item link is for a high-quality version of the item.
|
/// Gets a value indicating whether or not this item link is for a high-quality version of the item.
|
||||||
|
|
@ -183,7 +168,8 @@ public class ItemPayload : Payload
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{this.Type} - ItemId: {this.ItemId}, Kind: {this.Kind}, Name: {this.displayName ?? this.Item?.Name}";
|
var name = this.displayName ?? (this.Item.GetValueOrDefault<Item>()?.Name ?? this.Item.GetValueOrDefault<EventItem>()?.Name)?.ExtractText();
|
||||||
|
return $"{this.Type} - ItemId: {this.ItemId}, Kind: {this.Kind}, Name: {name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -11,11 +14,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MapLinkPayload : Payload
|
public class MapLinkPayload : Payload
|
||||||
{
|
{
|
||||||
private Map map;
|
|
||||||
private TerritoryType territoryType;
|
|
||||||
private string placeNameRegion;
|
|
||||||
private string placeName;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private uint territoryTypeId;
|
private uint territoryTypeId;
|
||||||
|
|
||||||
|
|
@ -38,8 +36,8 @@ public class MapLinkPayload : Payload
|
||||||
// this fudge is necessary basically to ensure we don't shift down a full tenth
|
// this fudge is necessary basically to ensure we don't shift down a full tenth
|
||||||
// because essentially values are truncated instead of rounded, so 3.09999f will become
|
// because essentially values are truncated instead of rounded, so 3.09999f will become
|
||||||
// 3.0f and not 3.1f
|
// 3.0f and not 3.1f
|
||||||
this.RawX = this.ConvertMapCoordinateToRawPosition(niceXCoord + fudgeFactor, this.Map.SizeFactor, this.Map.OffsetX);
|
this.RawX = this.ConvertMapCoordinateToRawPosition(niceXCoord + fudgeFactor, this.Map.Value.SizeFactor, this.Map.Value.OffsetX);
|
||||||
this.RawY = this.ConvertMapCoordinateToRawPosition(niceYCoord + fudgeFactor, this.Map.SizeFactor, this.Map.OffsetY);
|
this.RawY = this.ConvertMapCoordinateToRawPosition(niceYCoord + fudgeFactor, this.Map.Value.SizeFactor, this.Map.Value.OffsetY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -72,20 +70,14 @@ public class MapLinkPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Map specified for this map link.
|
/// Gets the Map specified for this map link.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Map Map => this.map ??= this.DataResolver.GetExcelSheet<Map>().GetRow(this.mapId);
|
public RowRef<Map> Map => LuminaUtils.CreateRef<Map>(this.mapId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the TerritoryType specified for this map link.
|
/// Gets the TerritoryType specified for this map link.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public TerritoryType TerritoryType => this.territoryType ??= this.DataResolver.GetExcelSheet<TerritoryType>().GetRow(this.territoryTypeId);
|
public RowRef<TerritoryType> TerritoryType => LuminaUtils.CreateRef<TerritoryType>(this.territoryTypeId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the internal x-coordinate for this map position.
|
/// Gets the internal x-coordinate for this map position.
|
||||||
|
|
@ -102,13 +94,13 @@ public class MapLinkPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the readable x-coordinate position for this map link. This value is approximate and unrounded.
|
/// Gets the readable x-coordinate position for this map link. This value is approximate and unrounded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float XCoord => this.ConvertRawPositionToMapCoordinate(this.RawX, this.Map.SizeFactor, this.Map.OffsetX);
|
public float XCoord => this.ConvertRawPositionToMapCoordinate(this.RawX, this.Map.Value.SizeFactor, this.Map.Value.OffsetX);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the readable y-coordinate position for this map link. This value is approximate and unrounded.
|
/// Gets the readable y-coordinate position for this map link. This value is approximate and unrounded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public float YCoord => this.ConvertRawPositionToMapCoordinate(this.RawY, this.Map.SizeFactor, this.Map.OffsetY);
|
public float YCoord => this.ConvertRawPositionToMapCoordinate(this.RawY, this.Map.Value.SizeFactor, this.Map.Value.OffsetY);
|
||||||
|
|
||||||
// there is no Z; it's purely in the text payload where applicable
|
// there is no Z; it's purely in the text payload where applicable
|
||||||
|
|
||||||
|
|
@ -143,18 +135,18 @@ public class MapLinkPayload : Payload
|
||||||
/// Gets the region name for this map link. This corresponds to the upper zone name found in the actual in-game map UI. eg, "La Noscea".
|
/// Gets the region name for this map link. This corresponds to the upper zone name found in the actual in-game map UI. eg, "La Noscea".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string PlaceNameRegion => this.placeNameRegion ??= this.TerritoryType.PlaceNameRegion.Value?.Name;
|
public string PlaceNameRegion => this.TerritoryType.Value.PlaceNameRegion.Value.Name.ExtractText();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the place name for this map link. This corresponds to the lower zone name found in the actual in-game map UI. eg, "Limsa Lominsa Upper Decks".
|
/// Gets the place name for this map link. This corresponds to the lower zone name found in the actual in-game map UI. eg, "Limsa Lominsa Upper Decks".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string PlaceName => this.placeName ??= this.TerritoryType.PlaceName.Value?.Name;
|
public string PlaceName => this.TerritoryType.Value.PlaceName.Value.Name.ExtractText();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data string for this map link, for use by internal game functions that take a string variant and not a binary payload.
|
/// Gets the data string for this map link, for use by internal game functions that take a string variant and not a binary payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string DataString => $"m:{this.TerritoryType.RowId},{this.Map.RowId},{this.RawX},{this.RawY}";
|
public string DataString => $"m:{this.territoryTypeId},{this.mapId},{this.RawX},{this.RawY}";
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -12,8 +15,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PlayerPayload : Payload
|
public class PlayerPayload : Payload
|
||||||
{
|
{
|
||||||
private World world;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private uint serverId;
|
private uint serverId;
|
||||||
|
|
||||||
|
|
@ -43,11 +44,8 @@ public class PlayerPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Lumina object representing the player's home server.
|
/// Gets the Lumina object representing the player's home server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public World World => this.world ??= this.DataResolver.GetExcelSheet<World>().GetRow(this.serverId);
|
public RowRef<World> World => LuminaUtils.CreateRef<World>(this.serverId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the player's displayed name. This does not contain the server name.
|
/// Gets or sets the player's displayed name. This does not contain the server name.
|
||||||
|
|
@ -72,7 +70,7 @@ public class PlayerPayload : Payload
|
||||||
/// The world name will always be present.
|
/// The world name will always be present.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public string DisplayedName => $"{this.PlayerName}{(char)SeIconChar.CrossWorld}{this.World.Name}";
|
public string DisplayedName => $"{this.PlayerName}{(char)SeIconChar.CrossWorld}{this.World.ValueNullable?.Name}";
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override PayloadType Type => PayloadType.Player;
|
public override PayloadType Type => PayloadType.Player;
|
||||||
|
|
@ -80,7 +78,7 @@ public class PlayerPayload : Payload
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{this.Type} - PlayerName: {this.PlayerName}, ServerId: {this.serverId}, ServerName: {this.World.Name}";
|
return $"{this.Type} - PlayerName: {this.PlayerName}, ServerId: {this.serverId}, ServerName: {this.World.ValueNullable?.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -11,8 +14,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class QuestPayload : Payload
|
public class QuestPayload : Payload
|
||||||
{
|
{
|
||||||
private Quest quest;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private uint questId;
|
private uint questId;
|
||||||
|
|
||||||
|
|
@ -40,16 +41,13 @@ public class QuestPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying Lumina Quest represented by this payload.
|
/// Gets the underlying Lumina Quest represented by this payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Quest Quest => this.quest ??= this.DataResolver.GetExcelSheet<Quest>().GetRow(this.questId);
|
public RowRef<Quest> Quest => LuminaUtils.CreateRef<Quest>(this.questId);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{this.Type} - QuestId: {this.questId}, Name: {this.Quest?.Name ?? "QUEST NOT FOUND"}";
|
return $"{this.Type} - QuestId: {this.questId}, Name: {this.Quest.ValueNullable?.Name.ExtractText() ?? "QUEST NOT FOUND"}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -11,8 +14,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StatusPayload : Payload
|
public class StatusPayload : Payload
|
||||||
{
|
{
|
||||||
private Status status;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private uint statusId;
|
private uint statusId;
|
||||||
|
|
||||||
|
|
@ -40,16 +41,13 @@ public class StatusPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Lumina Status object represented by this payload.
|
/// Gets the Lumina Status object represented by this payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Status Status => this.status ??= this.DataResolver.GetExcelSheet<Status>().GetRow(this.statusId);
|
public RowRef<Status> Status => LuminaUtils.CreateRef<Status>(this.statusId);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return $"{this.Type} - StatusId: {this.statusId}, Name: {this.Status.Name}";
|
return $"{this.Type} - StatusId: {this.statusId}, Name: {this.Status.ValueNullable?.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -11,8 +14,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UIForegroundPayload : Payload
|
public class UIForegroundPayload : Payload
|
||||||
{
|
{
|
||||||
private UIColor color;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private ushort colorKey;
|
private ushort colorKey;
|
||||||
|
|
||||||
|
|
@ -51,11 +52,8 @@ public class UIForegroundPayload : Payload
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIForeground.
|
/// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIForeground.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public UIColor UIColor => this.color ??= this.DataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
public RowRef<UIColor> UIColor => LuminaUtils.CreateRef<UIColor>(this.colorKey);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the color key used as a lookup in the UIColor table for this foreground color.
|
/// Gets or sets the color key used as a lookup in the UIColor table for this foreground color.
|
||||||
|
|
@ -63,15 +61,11 @@ public class UIForegroundPayload : Payload
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public ushort ColorKey
|
public ushort ColorKey
|
||||||
{
|
{
|
||||||
get
|
get => this.colorKey;
|
||||||
{
|
|
||||||
return this.colorKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.colorKey = value;
|
this.colorKey = value;
|
||||||
this.color = null;
|
|
||||||
this.Dirty = true;
|
this.Dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -80,13 +74,13 @@ public class UIForegroundPayload : Payload
|
||||||
/// Gets the Red/Green/Blue/Alpha values for this foreground color, encoded as a typical hex color.
|
/// Gets the Red/Green/Blue/Alpha values for this foreground color, encoded as a typical hex color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint RGBA => this.UIColor.UIForeground;
|
public uint RGBA => this.UIColor.Value.UIForeground;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ABGR value for this foreground color, as ImGui requires it in PushColor.
|
/// Gets the ABGR value for this foreground color, as ImGui requires it in PushColor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIForeground);
|
public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.Value.UIForeground);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Dalamud.Data;
|
||||||
|
|
||||||
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
|
|
@ -11,8 +14,6 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class UIGlowPayload : Payload
|
public class UIGlowPayload : Payload
|
||||||
{
|
{
|
||||||
private UIColor color;
|
|
||||||
|
|
||||||
[JsonProperty]
|
[JsonProperty]
|
||||||
private ushort colorKey;
|
private ushort colorKey;
|
||||||
|
|
||||||
|
|
@ -57,7 +58,6 @@ public class UIGlowPayload : Payload
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
this.colorKey = value;
|
this.colorKey = value;
|
||||||
this.color = null;
|
|
||||||
this.Dirty = true;
|
this.Dirty = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,22 +71,19 @@ public class UIGlowPayload : Payload
|
||||||
/// Gets the Red/Green/Blue/Alpha values for this glow color, encoded as a typical hex color.
|
/// Gets the Red/Green/Blue/Alpha values for this glow color, encoded as a typical hex color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint RGBA => this.UIColor.UIGlow;
|
public uint RGBA => this.UIColor.Value.UIGlow;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ABGR value for this glow color, as ImGui requires it in PushColor.
|
/// Gets the ABGR value for this glow color, as ImGui requires it in PushColor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.UIGlow);
|
public uint ABGR => Interface.ColorHelpers.SwapEndianness(this.UIColor.Value.UIGlow);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIGlow.
|
/// Gets a Lumina UIColor object representing this payload. The actual color data is at UIColor.UIGlow.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// The value is evaluated lazily and cached.
|
|
||||||
/// </remarks>
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public UIColor UIColor => this.color ??= this.DataResolver.GetExcelSheet<UIColor>().GetRow(this.colorKey);
|
public RowRef<UIColor> UIColor => LuminaUtils.CreateRef<UIColor>(this.colorKey);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using System.Text;
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Dalamud.Game.Text.SeStringHandling;
|
namespace Dalamud.Game.Text.SeStringHandling;
|
||||||
|
|
@ -200,12 +200,12 @@ public class SeString
|
||||||
case ItemPayload.ItemKind.Normal:
|
case ItemPayload.ItemKind.Normal:
|
||||||
case ItemPayload.ItemKind.Collectible:
|
case ItemPayload.ItemKind.Collectible:
|
||||||
case ItemPayload.ItemKind.Hq:
|
case ItemPayload.ItemKind.Hq:
|
||||||
var item = data.GetExcelSheet<Item>()?.GetRow(itemId);
|
var item = data.GetExcelSheet<Item>()?.GetRowOrDefault(itemId);
|
||||||
displayName = item?.Name;
|
displayName = item?.Name.ExtractText();
|
||||||
rarity = item?.Rarity ?? 1;
|
rarity = item?.Rarity ?? 1;
|
||||||
break;
|
break;
|
||||||
case ItemPayload.ItemKind.EventItem:
|
case ItemPayload.ItemKind.EventItem:
|
||||||
displayName = data.GetExcelSheet<EventItem>()?.GetRow(itemId)?.Name;
|
displayName = data.GetExcelSheet<EventItem>()?.GetRowOrDefault(itemId)?.Name.ExtractText();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
|
throw new ArgumentOutOfRangeException(nameof(kind), kind, null);
|
||||||
|
|
@ -251,7 +251,7 @@ public class SeString
|
||||||
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
/// <returns>An SeString containing all the payloads necessary to display an item link in the chat log.</returns>
|
||||||
public static SeString CreateItemLink(Item item, bool isHq, string? displayNameOverride = null)
|
public static SeString CreateItemLink(Item item, bool isHq, string? displayNameOverride = null)
|
||||||
{
|
{
|
||||||
return CreateItemLink(item.RowId, isHq, displayNameOverride ?? item.Name);
|
return CreateItemLink(item.RowId, isHq, displayNameOverride ?? item.Name.ExtractText());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -360,15 +360,14 @@ public class SeString
|
||||||
var mapSheet = data.GetExcelSheet<Map>();
|
var mapSheet = data.GetExcelSheet<Map>();
|
||||||
|
|
||||||
var matches = data.GetExcelSheet<PlaceName>()
|
var matches = data.GetExcelSheet<PlaceName>()
|
||||||
.Where(row => row.Name.ToString().ToLowerInvariant() == placeName.ToLowerInvariant())
|
.Where(row => row.Name.ExtractText().Equals(placeName, StringComparison.InvariantCultureIgnoreCase));
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
foreach (var place in matches)
|
foreach (var place in matches)
|
||||||
{
|
{
|
||||||
var map = mapSheet.FirstOrDefault(row => row.PlaceName.Row == place.RowId);
|
var map = mapSheet.Cast<Map?>().FirstOrDefault(row => row!.Value.PlaceName.RowId == place.RowId);
|
||||||
if (map != null && map.TerritoryType.Row != 0)
|
if (map.HasValue && map.Value.TerritoryType.RowId != 0)
|
||||||
{
|
{
|
||||||
return CreateMapLinkWithInstance(map.TerritoryType.Row, map.RowId, instance, xCoord, yCoord, fudgeFactor);
|
return CreateMapLinkWithInstance(map.Value.TerritoryType.RowId, map.Value.RowId, instance, xCoord, yCoord, fudgeFactor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.UI.Misc;
|
||||||
using FFXIVClientStructs.FFXIV.Component.Text;
|
using FFXIVClientStructs.FFXIV.Component.Text;
|
||||||
|
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
using Lumina.Excel.GeneratedSheets2;
|
using Lumina.Excel.Sheets;
|
||||||
using Lumina.Text.Expressions;
|
using Lumina.Text.Expressions;
|
||||||
using Lumina.Text.Payloads;
|
using Lumina.Text.Payloads;
|
||||||
using Lumina.Text.ReadOnly;
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets2;
|
using Lumina.Excel.Sheets;
|
||||||
using Lumina.Text.Parse;
|
using Lumina.Text.Parse;
|
||||||
using Lumina.Text.Payloads;
|
using Lumina.Text.Payloads;
|
||||||
using Lumina.Text.ReadOnly;
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Game.ClientState.Aetherytes;
|
using Dalamud.Game.ClientState.Aetherytes;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ internal class AetherytesWidget : IDataWindowWidget
|
||||||
ImGui.TextUnformatted($"{i}");
|
ImGui.TextUnformatted($"{i}");
|
||||||
|
|
||||||
ImGui.TableNextColumn(); // Name
|
ImGui.TableNextColumn(); // Name
|
||||||
ImGui.TextUnformatted($"{info.AetheryteData.GameData?.PlaceName.Value?.Name}");
|
ImGui.TextUnformatted($"{info.AetheryteData.ValueNullable?.PlaceName.ValueNullable?.Name}");
|
||||||
|
|
||||||
ImGui.TableNextColumn(); // ID
|
ImGui.TableNextColumn(); // ID
|
||||||
ImGui.TextUnformatted($"{info.AetheryteId}");
|
ImGui.TextUnformatted($"{info.AetheryteId}");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.ClientState.JobGauge;
|
using Dalamud.Game.ClientState.JobGauge;
|
||||||
using Dalamud.Game.ClientState.JobGauge.Types;
|
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
|
|
@ -39,7 +39,7 @@ internal class GaugeWidget : IDataWindowWidget
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jobID = player.ClassJob.Id;
|
var jobID = player.ClassJob.RowId;
|
||||||
JobGaugeBase? gauge = jobID switch
|
JobGaugeBase? gauge = jobID switch
|
||||||
{
|
{
|
||||||
19 => jobGauges.Get<PLDGauge>(),
|
19 => jobGauges.Get<PLDGauge>(),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
|
@ -56,8 +56,8 @@ internal class ObjectTableWidget : IDataWindowWidget
|
||||||
{
|
{
|
||||||
stateString += $"ObjectTableLen: {objectTable.Length}\n";
|
stateString += $"ObjectTableLen: {objectTable.Length}\n";
|
||||||
stateString += $"LocalPlayerName: {clientState.LocalPlayer.Name}\n";
|
stateString += $"LocalPlayerName: {clientState.LocalPlayer.Name}\n";
|
||||||
stateString += $"CurrentWorldName: {(this.resolveGameData ? clientState.LocalPlayer.CurrentWorld.GameData?.Name : clientState.LocalPlayer.CurrentWorld.Id.ToString())}\n";
|
stateString += $"CurrentWorldName: {(this.resolveGameData ? clientState.LocalPlayer.CurrentWorld.ValueNullable?.Name : clientState.LocalPlayer.CurrentWorld.RowId.ToString())}\n";
|
||||||
stateString += $"HomeWorldName: {(this.resolveGameData ? clientState.LocalPlayer.HomeWorld.GameData?.Name : clientState.LocalPlayer.HomeWorld.Id.ToString())}\n";
|
stateString += $"HomeWorldName: {(this.resolveGameData ? clientState.LocalPlayer.HomeWorld.ValueNullable?.Name : clientState.LocalPlayer.HomeWorld.RowId.ToString())}\n";
|
||||||
stateString += $"LocalCID: {clientState.LocalContentId:X}\n";
|
stateString += $"LocalCID: {clientState.LocalContentId:X}\n";
|
||||||
stateString += $"LastLinkedItem: {chatGui.LastLinkedItemId}\n";
|
stateString += $"LastLinkedItem: {chatGui.LastLinkedItemId}\n";
|
||||||
stateString += $"TerritoryType: {clientState.TerritoryType}\n\n";
|
stateString += $"TerritoryType: {clientState.TerritoryType}\n\n";
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
|
|
@ -16,7 +16,8 @@ using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets2;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
using Lumina.Text;
|
using Lumina.Text;
|
||||||
using Lumina.Text.Payloads;
|
using Lumina.Text.Payloads;
|
||||||
using Lumina.Text.ReadOnly;
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
@ -33,7 +34,7 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
|
||||||
private static readonly string[] ThemeNames = ["Dark", "Light", "Classic FF", "Clear Blue"];
|
private static readonly string[] ThemeNames = ["Dark", "Light", "Classic FF", "Clear Blue"];
|
||||||
private ImVectorWrapper<byte> testStringBuffer;
|
private ImVectorWrapper<byte> testStringBuffer;
|
||||||
private string testString = string.Empty;
|
private string testString = string.Empty;
|
||||||
private Addon[]? addons;
|
private ExcelSheet<Addon> addons;
|
||||||
private ReadOnlySeString? logkind;
|
private ReadOnlySeString? logkind;
|
||||||
private SeStringDrawParams style;
|
private SeStringDrawParams style;
|
||||||
private bool interactable;
|
private bool interactable;
|
||||||
|
|
@ -53,7 +54,7 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
this.style = new() { GetEntity = this.GetEntity };
|
this.style = new() { GetEntity = this.GetEntity };
|
||||||
this.addons = null;
|
this.addons = Service<DataManager>.Get().GetExcelSheet<Addon>();
|
||||||
this.logkind = null;
|
this.logkind = null;
|
||||||
this.testString = string.Empty;
|
this.testString = string.Empty;
|
||||||
this.interactable = this.useEntity = true;
|
this.interactable = this.useEntity = true;
|
||||||
|
|
@ -155,9 +156,9 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
|
||||||
if (this.logkind is null)
|
if (this.logkind is null)
|
||||||
{
|
{
|
||||||
var tt = new SeStringBuilder();
|
var tt = new SeStringBuilder();
|
||||||
foreach (var uc in Service<DataManager>.Get().GetExcelSheet<LogKind>()!)
|
foreach (var uc in Service<DataManager>.Get().GetExcelSheet<LogKind>())
|
||||||
{
|
{
|
||||||
var ucsp = uc.Format.AsReadOnly().AsSpan();
|
var ucsp = uc.Format.AsSpan();
|
||||||
if (ucsp.IsEmpty)
|
if (ucsp.IsEmpty)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -184,7 +185,6 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Addon Table"))
|
if (ImGui.CollapsingHeader("Addon Table"))
|
||||||
{
|
{
|
||||||
this.addons ??= Service<DataManager>.Get().GetExcelSheet<Addon>()!.ToArray();
|
|
||||||
if (ImGui.BeginTable("Addon Sheet", 3))
|
if (ImGui.BeginTable("Addon Sheet", 3))
|
||||||
{
|
{
|
||||||
ImGui.TableSetupScrollFreeze(0, 1);
|
ImGui.TableSetupScrollFreeze(0, 1);
|
||||||
|
|
@ -197,25 +197,27 @@ internal unsafe class SeStringRendererTestWidget : IDataWindowWidget
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
|
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
|
||||||
clipper.Begin(this.addons.Length);
|
clipper.Begin(this.addons.Count);
|
||||||
while (clipper.Step())
|
while (clipper.Step())
|
||||||
{
|
{
|
||||||
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||||
{
|
{
|
||||||
|
var row = this.addons.GetRowAt(i);
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.PushID(i);
|
ImGui.PushID(i);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextUnformatted($"{this.addons[i].RowId}");
|
ImGui.TextUnformatted($"{row.RowId}");
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGuiHelpers.SeStringWrapped(this.addons[i].Text.AsReadOnly(), this.style);
|
ImGuiHelpers.SeStringWrapped(row.Text, this.style);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGui.Button("Print to Chat"))
|
if (ImGui.Button("Print to Chat"))
|
||||||
Service<ChatGui>.Get().Print(this.addons[i].Text.ToDalamudString());
|
Service<ChatGui>.Get().Print(row.Text.ToDalamudString());
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -12,7 +12,8 @@ using Dalamud.Storage.Assets;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
|
|
||||||
|
|
@ -21,7 +22,7 @@ namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class UiColorWidget : IDataWindowWidget
|
internal class UiColorWidget : IDataWindowWidget
|
||||||
{
|
{
|
||||||
private UIColor[]? colors;
|
private ExcelSheet<UIColor> colors;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string[]? CommandShortcuts { get; init; } = ["uicolor"];
|
public string[]? CommandShortcuts { get; init; } = ["uicolor"];
|
||||||
|
|
@ -36,15 +37,12 @@ internal class UiColorWidget : IDataWindowWidget
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
this.Ready = true;
|
this.Ready = true;
|
||||||
this.colors = null;
|
this.colors = Service<DataManager>.Get().GetExcelSheet<UIColor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public unsafe void Draw()
|
public unsafe void Draw()
|
||||||
{
|
{
|
||||||
this.colors ??= Service<DataManager>.Get().GetExcelSheet<UIColor>()?.ToArray();
|
|
||||||
if (this.colors is null) return;
|
|
||||||
|
|
||||||
Service<SeStringRenderer>.Get().CompileAndDrawWrapped(
|
Service<SeStringRenderer>.Get().CompileAndDrawWrapped(
|
||||||
"· Color notation is #" +
|
"· Color notation is #" +
|
||||||
"<edgecolor(0xFFEEEE)><color(0xFF0000)>RR<color(stackcolor)><edgecolor(stackcolor)>" +
|
"<edgecolor(0xFFEEEE)><color(0xFF0000)>RR<color(stackcolor)><edgecolor(stackcolor)>" +
|
||||||
|
|
@ -73,12 +71,24 @@ internal class UiColorWidget : IDataWindowWidget
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
|
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
|
||||||
clipper.Begin(this.colors.Length, ImGui.GetFrameHeightWithSpacing());
|
clipper.Begin(this.colors.Count, ImGui.GetFrameHeightWithSpacing());
|
||||||
while (clipper.Step())
|
while (clipper.Step())
|
||||||
{
|
{
|
||||||
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++)
|
||||||
{
|
{
|
||||||
var id = this.colors[i].RowId;
|
var row = this.colors.GetRowAt(i);
|
||||||
|
UIColor? adjacentRow = null;
|
||||||
|
if (i + 1 < this.colors.Count)
|
||||||
|
{
|
||||||
|
var adjRow = this.colors.GetRowAt(i + 1);
|
||||||
|
if (adjRow.RowId == row.RowId + 1)
|
||||||
|
{
|
||||||
|
adjacentRow = adjRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var id = row.RowId;
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
@ -88,33 +98,33 @@ internal class UiColorWidget : IDataWindowWidget
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.PushID($"row{id}_col1");
|
ImGui.PushID($"row{id}_col1");
|
||||||
if (this.DrawColorColumn(this.colors[i].UIForeground) &&
|
if (this.DrawColorColumn(row.UIForeground) &&
|
||||||
i + 1 < this.colors.Length && this.colors[i + 1].RowId == id + 1)
|
adjacentRow.HasValue)
|
||||||
DrawEdgePreview(id, this.colors[i].UIForeground, this.colors[i + 1].UIForeground);
|
DrawEdgePreview(id, row.UIForeground, adjacentRow.Value.UIForeground);
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.PushID($"row{id}_col2");
|
ImGui.PushID($"row{id}_col2");
|
||||||
if (this.DrawColorColumn(this.colors[i].UIGlow) &&
|
if (this.DrawColorColumn(row.UIGlow) &&
|
||||||
i + 1 < this.colors.Length && this.colors[i + 1].RowId == id + 1)
|
adjacentRow.HasValue)
|
||||||
DrawEdgePreview(id, this.colors[i].UIGlow, this.colors[i + 1].UIGlow);
|
DrawEdgePreview(id, row.UIGlow, adjacentRow.Value.UIGlow);
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.PushID($"row{id}_col3");
|
ImGui.PushID($"row{id}_col3");
|
||||||
if (this.DrawColorColumn(this.colors[i].Unknown2) &&
|
if (this.DrawColorColumn(row.Unknown0) &&
|
||||||
i + 1 < this.colors.Length && this.colors[i + 1].RowId == id + 1)
|
adjacentRow.HasValue)
|
||||||
DrawEdgePreview(id, this.colors[i].Unknown2, this.colors[i + 1].Unknown2);
|
DrawEdgePreview(id, row.Unknown0, adjacentRow.Value.Unknown0);
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.PushID($"row{id}_col4");
|
ImGui.PushID($"row{id}_col4");
|
||||||
if (this.DrawColorColumn(this.colors[i].Unknown3) &&
|
if (this.DrawColorColumn(row.Unknown1) &&
|
||||||
i + 1 < this.colors.Length && this.colors[i + 1].RowId == id + 1)
|
adjacentRow.HasValue)
|
||||||
DrawEdgePreview(id, this.colors[i].Unknown3, this.colors[i + 1].Unknown3);
|
DrawEdgePreview(id, row.Unknown1, adjacentRow.Value.Unknown1);
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,9 @@ using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Game.Gui.ContextMenu;
|
using Dalamud.Game.Gui.ContextMenu;
|
||||||
using Dalamud.Game.Text;
|
using Dalamud.Game.Text;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Utility;
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps;
|
namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps;
|
||||||
|
|
@ -45,9 +44,9 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
{
|
{
|
||||||
var contextMenu = Service<ContextMenu>.Get();
|
var contextMenu = Service<ContextMenu>.Get();
|
||||||
var dataMgr = Service<DataManager>.Get();
|
var dataMgr = Service<DataManager>.Get();
|
||||||
this.itemSheet = dataMgr.GetExcelSheet<Item>()!;
|
this.itemSheet = dataMgr.GetExcelSheet<Item>();
|
||||||
this.materiaSheet = dataMgr.GetExcelSheet<Materia>()!;
|
this.materiaSheet = dataMgr.GetExcelSheet<Materia>();
|
||||||
this.stainSheet = dataMgr.GetExcelSheet<Stain>()!;
|
this.stainSheet = dataMgr.GetExcelSheet<Stain>();
|
||||||
|
|
||||||
ImGui.Text(this.currentSubStep.ToString());
|
ImGui.Text(this.currentSubStep.ToString());
|
||||||
|
|
||||||
|
|
@ -83,7 +82,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
case SubStep.TestDefault:
|
case SubStep.TestDefault:
|
||||||
if (this.targetCharacter is { } character)
|
if (this.targetCharacter is { } character)
|
||||||
{
|
{
|
||||||
ImGui.Text($"Did you click \"{character.Name}\" ({character.ClassJob.GameData!.Abbreviation.ToDalamudString()})?");
|
ImGui.Text($"Did you click \"{character.Name}\" ({character.ClassJob.Value.Abbreviation.ExtractText()})?");
|
||||||
|
|
||||||
if (ImGui.Button("Yes"))
|
if (ImGui.Button("Yes"))
|
||||||
this.currentSubStep++;
|
this.currentSubStep++;
|
||||||
|
|
@ -146,7 +145,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
var targetItem = (a.Target as MenuTargetInventory)!.TargetItem;
|
var targetItem = (a.Target as MenuTargetInventory)!.TargetItem;
|
||||||
if (targetItem is { } item)
|
if (targetItem is { } item)
|
||||||
{
|
{
|
||||||
name = (this.itemSheet.GetRow(item.ItemId)?.Name.ToDalamudString() ?? $"Unknown ({item.ItemId})") + (item.IsHq ? $" {SeIconChar.HighQuality.ToIconString()}" : string.Empty);
|
name = (this.itemSheet.GetRowOrDefault(item.ItemId)?.Name.ExtractText() ?? $"Unknown ({item.ItemId})") + (item.IsHq ? $" {SeIconChar.HighQuality.ToIconString()}" : string.Empty);
|
||||||
count = item.Quantity;
|
count = item.Quantity;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -194,7 +193,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
{
|
{
|
||||||
var b = new StringBuilder();
|
var b = new StringBuilder();
|
||||||
b.AppendLine($"Target: {targetDefault.TargetName}");
|
b.AppendLine($"Target: {targetDefault.TargetName}");
|
||||||
b.AppendLine($"Home World: {targetDefault.TargetHomeWorld.GameData?.Name.ToDalamudString() ?? "Unknown"} ({targetDefault.TargetHomeWorld.Id})");
|
b.AppendLine($"Home World: {targetDefault.TargetHomeWorld.ValueNullable?.Name.ExtractText() ?? "Unknown"} ({targetDefault.TargetHomeWorld.RowId})");
|
||||||
b.AppendLine($"Content Id: 0x{targetDefault.TargetContentId:X8}");
|
b.AppendLine($"Content Id: 0x{targetDefault.TargetContentId:X8}");
|
||||||
b.AppendLine($"Object Id: 0x{targetDefault.TargetObjectId:X8}");
|
b.AppendLine($"Object Id: 0x{targetDefault.TargetObjectId:X8}");
|
||||||
Log.Verbose(b.ToString());
|
Log.Verbose(b.ToString());
|
||||||
|
|
@ -209,20 +208,20 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
b.AppendLine($"Content Id: 0x{character.ContentId:X8}");
|
b.AppendLine($"Content Id: 0x{character.ContentId:X8}");
|
||||||
b.AppendLine($"FC Tag: {character.FCTag}");
|
b.AppendLine($"FC Tag: {character.FCTag}");
|
||||||
|
|
||||||
b.AppendLine($"Job: {character.ClassJob.GameData?.Abbreviation.ToDalamudString() ?? "Unknown"} ({character.ClassJob.Id})");
|
b.AppendLine($"Job: {character.ClassJob.ValueNullable?.Abbreviation.ExtractText() ?? "Unknown"} ({character.ClassJob.RowId})");
|
||||||
b.AppendLine($"Statuses: {string.Join(", ", character.Statuses.Select(s => s.GameData?.Name.ToDalamudString() ?? s.Id.ToString()))}");
|
b.AppendLine($"Statuses: {string.Join(", ", character.Statuses.Select(s => s.ValueNullable?.Name.ExtractText() ?? s.RowId.ToString()))}");
|
||||||
b.AppendLine($"Home World: {character.HomeWorld.GameData?.Name.ToDalamudString() ?? "Unknown"} ({character.HomeWorld.Id})");
|
b.AppendLine($"Home World: {character.HomeWorld.ValueNullable?.Name.ExtractText() ?? "Unknown"} ({character.HomeWorld.RowId})");
|
||||||
b.AppendLine($"Current World: {character.CurrentWorld.GameData?.Name.ToDalamudString() ?? "Unknown"} ({character.CurrentWorld.Id})");
|
b.AppendLine($"Current World: {character.CurrentWorld.ValueNullable?.Name.ExtractText() ?? "Unknown"} ({character.CurrentWorld.RowId})");
|
||||||
b.AppendLine($"Is From Other Server: {character.IsFromOtherServer}");
|
b.AppendLine($"Is From Other Server: {character.IsFromOtherServer}");
|
||||||
|
|
||||||
b.Append("Location: ");
|
b.Append("Location: ");
|
||||||
if (character.Location.GameData is { } location)
|
if (character.Location.ValueNullable is { } location)
|
||||||
b.Append($"{location.PlaceNameRegion.Value?.Name.ToDalamudString() ?? "Unknown"}/{location.PlaceNameZone.Value?.Name.ToDalamudString() ?? "Unknown"}/{location.PlaceName.Value?.Name.ToDalamudString() ?? "Unknown"}");
|
b.Append($"{location.PlaceNameRegion.ValueNullable?.Name.ExtractText() ?? "Unknown"}/{location.PlaceNameZone.ValueNullable?.Name.ExtractText() ?? "Unknown"}/{location.PlaceName.ValueNullable?.Name.ExtractText() ?? "Unknown"}");
|
||||||
else
|
else
|
||||||
b.Append("Unknown");
|
b.Append("Unknown");
|
||||||
b.AppendLine($" ({character.Location.Id})");
|
b.AppendLine($" ({character.Location.RowId})");
|
||||||
|
|
||||||
b.AppendLine($"Grand Company: {character.GrandCompany.GameData?.Name.ToDalamudString() ?? "Unknown"} ({character.GrandCompany.Id})");
|
b.AppendLine($"Grand Company: {character.GrandCompany.ValueNullable?.Name.ExtractText() ?? "Unknown"} ({character.GrandCompany.RowId})");
|
||||||
b.AppendLine($"Client Language: {character.ClientLanguage}");
|
b.AppendLine($"Client Language: {character.ClientLanguage}");
|
||||||
b.AppendLine($"Languages: {string.Join(", ", character.Languages)}");
|
b.AppendLine($"Languages: {string.Join(", ", character.Languages)}");
|
||||||
b.AppendLine($"Gender: {character.Gender}");
|
b.AppendLine($"Gender: {character.Gender}");
|
||||||
|
|
@ -241,7 +240,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
if (targetInventory.TargetItem is { } item)
|
if (targetInventory.TargetItem is { } item)
|
||||||
{
|
{
|
||||||
var b = new StringBuilder();
|
var b = new StringBuilder();
|
||||||
b.AppendLine($"Item: {(item.IsEmpty ? "None" : this.itemSheet.GetRow(item.ItemId)?.Name.ToDalamudString())} ({item.ItemId})");
|
b.AppendLine($"Item: {(item.IsEmpty ? "None" : this.itemSheet.GetRowOrDefault(item.ItemId)?.Name.ExtractText())} ({item.ItemId})");
|
||||||
b.AppendLine($"Container: {item.ContainerType}");
|
b.AppendLine($"Container: {item.ContainerType}");
|
||||||
b.AppendLine($"Slot: {item.InventorySlot}");
|
b.AppendLine($"Slot: {item.InventorySlot}");
|
||||||
b.AppendLine($"Quantity: {item.Quantity}");
|
b.AppendLine($"Quantity: {item.Quantity}");
|
||||||
|
|
@ -259,7 +258,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
Log.Verbose($"{materiaId} {materiaGrade}");
|
Log.Verbose($"{materiaId} {materiaGrade}");
|
||||||
if (this.materiaSheet.GetRow(materiaId) is { } materia &&
|
if (this.materiaSheet.GetRow(materiaId) is { } materia &&
|
||||||
materia.Item[materiaGrade].Value is { } materiaItem)
|
materia.Item[materiaGrade].Value is { } materiaItem)
|
||||||
materias.Add($"{materiaItem.Name.ToDalamudString()}");
|
materias.Add($"{materiaItem.Name.ExtractText()}");
|
||||||
else
|
else
|
||||||
materias.Add($"Unknown (Id: {materiaId}, Grade: {materiaGrade})");
|
materias.Add($"Unknown (Id: {materiaId}, Grade: {materiaGrade})");
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +274,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
var stainId = item.Stains[i];
|
var stainId = item.Stains[i];
|
||||||
if (stainId != 0)
|
if (stainId != 0)
|
||||||
{
|
{
|
||||||
var stainName = this.stainSheet.GetRow(stainId)?.Name.ToDalamudString().ToString() ?? "Unknown";
|
var stainName = this.stainSheet.GetRowOrDefault(stainId)?.Name.ExtractText() ?? "Unknown";
|
||||||
b.AppendLine($" Stain {i + 1}: {stainName} ({stainId})");
|
b.AppendLine($" Stain {i + 1}: {stainName} ({stainId})");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -285,13 +284,13 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.Stains[0] != 0)
|
if (item.Stains[0] != 0)
|
||||||
b.AppendLine($"{this.stainSheet.GetRow(item.Stains[0])?.Name.ToDalamudString() ?? "Unknown"} ({item.Stains[0]})");
|
b.AppendLine($"{this.stainSheet.GetRowOrDefault(item.Stains[0])?.Name.ExtractText() ?? "Unknown"} ({item.Stains[0]})");
|
||||||
else
|
else
|
||||||
b.AppendLine("None");
|
b.AppendLine("None");
|
||||||
|
|
||||||
b.Append("Glamoured Item: ");
|
b.Append("Glamoured Item: ");
|
||||||
if (item.GlamourId != 0)
|
if (item.GlamourId != 0)
|
||||||
b.AppendLine($"{this.itemSheet.GetRow(item.GlamourId)?.Name.ToDalamudString() ?? "Unknown"} ({item.GlamourId})");
|
b.AppendLine($"{this.itemSheet.GetRowOrDefault(item.GlamourId)?.Name.ExtractText() ?? "Unknown"} ({item.GlamourId})");
|
||||||
else
|
else
|
||||||
b.AppendLine("None");
|
b.AppendLine("None");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
|
|
@ -11,31 +8,46 @@ namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps;
|
||||||
/// Test setup for Lumina.
|
/// Test setup for Lumina.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">ExcelRow to run test on.</typeparam>
|
/// <typeparam name="T">ExcelRow to run test on.</typeparam>
|
||||||
internal class LuminaAgingStep<T> : IAgingStep
|
/// <param name="isLargeSheet">Whether or not the sheet is large. If it is large, the self test will iterate through the full sheet in one frame and benchmark the time taken.</param>
|
||||||
where T : ExcelRow
|
internal class LuminaAgingStep<T>(bool isLargeSheet) : IAgingStep
|
||||||
|
where T : struct, IExcelRow<T>
|
||||||
{
|
{
|
||||||
private int step = 0;
|
private int step = 0;
|
||||||
private List<T> rows;
|
private ExcelSheet<T> rows;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Name => "Test Lumina";
|
public string Name => $"Test Lumina ({typeof(T).Name})";
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public SelfTestStepResult RunStep()
|
public SelfTestStepResult RunStep()
|
||||||
{
|
{
|
||||||
var dataManager = Service<DataManager>.Get();
|
this.rows ??= Service<DataManager>.Get().GetExcelSheet<T>();
|
||||||
|
|
||||||
this.rows ??= dataManager.GetExcelSheet<T>().ToList();
|
if (isLargeSheet)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
T currentRow = default;
|
||||||
|
foreach (var row in this.rows)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
currentRow = row;
|
||||||
|
}
|
||||||
|
|
||||||
Util.ShowObject(this.rows[this.step]);
|
Util.ShowObject(currentRow);
|
||||||
|
return SelfTestStepResult.Pass;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Util.ShowObject(this.rows.GetRowAt(this.step));
|
||||||
|
|
||||||
this.step++;
|
this.step++;
|
||||||
return this.step >= this.rows.Count ? SelfTestStepResult.Pass : SelfTestStepResult.Waiting;
|
return this.step >= this.rows.Count ? SelfTestStepResult.Pass : SelfTestStepResult.Waiting;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void CleanUp()
|
public void CleanUp()
|
||||||
{
|
{
|
||||||
// ignored
|
this.step = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Interface.Internal.Windows.SelfTest;
|
namespace Dalamud.Interface.Internal.Windows.SelfTest;
|
||||||
|
|
||||||
|
|
@ -39,7 +39,11 @@ internal class SelfTestWindow : Window
|
||||||
new GamepadStateAgingStep(),
|
new GamepadStateAgingStep(),
|
||||||
new ChatAgingStep(),
|
new ChatAgingStep(),
|
||||||
new HoverAgingStep(),
|
new HoverAgingStep(),
|
||||||
new LuminaAgingStep<TerritoryType>(),
|
new LuminaAgingStep<Item>(true),
|
||||||
|
new LuminaAgingStep<Level>(true),
|
||||||
|
new LuminaAgingStep<Lumina.Excel.Sheets.Action>(true),
|
||||||
|
new LuminaAgingStep<Quest>(true),
|
||||||
|
new LuminaAgingStep<TerritoryType>(false),
|
||||||
new AddonLifecycleAgingStep(),
|
new AddonLifecycleAgingStep(),
|
||||||
new PartyFinderAgingStep(),
|
new PartyFinderAgingStep(),
|
||||||
new HandledExceptionAgingStep(),
|
new HandledExceptionAgingStep(),
|
||||||
|
|
|
||||||
|
|
@ -599,7 +599,7 @@ internal class LocalPlugin : IAsyncDisposable
|
||||||
// Changes to Lumina should be upstreamed if feasible, and if there is a desire to re-add unpinned Lumina we
|
// Changes to Lumina should be upstreamed if feasible, and if there is a desire to re-add unpinned Lumina we
|
||||||
// will need to put this behind some kind of feature flag somewhere.
|
// will need to put this behind some kind of feature flag somewhere.
|
||||||
config.SharedAssemblies.Add((typeof(Lumina.GameData).Assembly.GetName(), true));
|
config.SharedAssemblies.Add((typeof(Lumina.GameData).Assembly.GetName(), true));
|
||||||
config.SharedAssemblies.Add((typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName(), true));
|
config.SharedAssemblies.Add((typeof(Lumina.Excel.Sheets.Addon).Assembly.GetName(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnsureLoader()
|
private void EnsureLoader()
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public interface IClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that gets fired when a duty is ready.
|
/// Event that gets fired when a duty is ready.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event Action<Lumina.Excel.GeneratedSheets.ContentFinderCondition> CfPop;
|
public event Action<Lumina.Excel.Sheets.ContentFinderCondition> CfPop;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the language of the client.
|
/// Gets the language of the client.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,9 @@ using Dalamud.Game;
|
||||||
|
|
||||||
using Lumina;
|
using Lumina;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
|
using Lumina.Data.Structs.Excel;
|
||||||
using Lumina.Excel;
|
using Lumina.Excel;
|
||||||
|
using Lumina.Excel.Exceptions;
|
||||||
|
|
||||||
namespace Dalamud.Plugin.Services;
|
namespace Dalamud.Plugin.Services;
|
||||||
|
|
||||||
|
|
@ -37,17 +39,38 @@ public interface IDataManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get an <see cref="ExcelSheet{T}"/> with the given Excel sheet row type.
|
/// Get an <see cref="ExcelSheet{T}"/> with the given Excel sheet row type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="language">Language of the sheet to get. Leave <see langword="null"/> or empty to use the default language.</param>
|
||||||
|
/// <param name="name">Explicitly provide the name of the sheet to get. Leave <see langword="null"/> to use <typeparamref name="T"/>'s sheet name. Explicit names are necessary for quest/dungeon/cutscene sheets.</param>
|
||||||
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
||||||
/// <returns>The <see cref="ExcelSheet{T}"/>, giving access to game rows.</returns>
|
/// <returns>The <see cref="ExcelSheet{T}"/>, giving access to game rows.</returns>
|
||||||
public ExcelSheet<T>? GetExcelSheet<T>() where T : ExcelRow;
|
/// <remarks>
|
||||||
|
/// If the sheet type you want has subrows, use <see cref="GetSubrowExcelSheet{T}(ClientLanguage?, string?)"/> instead.
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="SheetNameEmptyException">Sheet name was not specified neither via <typeparamref name="T"/>'s <see cref="SheetAttribute.Name"/> nor <paramref name="name"/>.</exception>
|
||||||
|
/// <exception cref="SheetAttributeMissingException"><typeparamref name="T"/> does not have a valid <see cref="SheetAttribute"/>.</exception>
|
||||||
|
/// <exception cref="SheetNotFoundException">Sheet does not exist.</exception>
|
||||||
|
/// <exception cref="MismatchedColumnHashException">Sheet had a mismatched column hash.</exception>
|
||||||
|
/// <exception cref="UnsupportedLanguageException">Sheet does not support <paramref name="language" /> nor <see cref="Language.None"/>.</exception>
|
||||||
|
/// <exception cref="NotSupportedException">Sheet was not a <see cref="ExcelVariant.Default"/>.</exception>
|
||||||
|
public ExcelSheet<T> GetExcelSheet<T>(ClientLanguage? language = null, string? name = null) where T : struct, IExcelRow<T>;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get an <see cref="ExcelSheet{T}"/> with the given Excel sheet row type with a specified language.
|
/// Get a <see cref="SubrowExcelSheet{T}"/> with the given Excel sheet row type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="language">Language of the sheet to get.</param>
|
/// <param name="language">Language of the sheet to get. Leave <see langword="null"/> or empty to use the default language.</param>
|
||||||
|
/// <param name="name">Explicitly provide the name of the sheet to get. Leave <see langword="null"/> to use <typeparamref name="T"/>'s sheet name. Explicit names are necessary for quest/dungeon/cutscene sheets.</param>
|
||||||
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
||||||
/// <returns>The <see cref="ExcelSheet{T}"/>, giving access to game rows.</returns>
|
/// <returns>The <see cref="SubrowExcelSheet{T}"/>, giving access to game rows.</returns>
|
||||||
public ExcelSheet<T>? GetExcelSheet<T>(ClientLanguage language) where T : ExcelRow;
|
/// <remarks>
|
||||||
|
/// If the sheet type you want has only rows, use <see cref="GetExcelSheet{T}(ClientLanguage?, string?)"/> instead.
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="SheetNameEmptyException">Sheet name was not specified neither via <typeparamref name="T"/>'s <see cref="SheetAttribute.Name"/> nor <paramref name="name"/>.</exception>
|
||||||
|
/// <exception cref="SheetAttributeMissingException"><typeparamref name="T"/> does not have a valid <see cref="SheetAttribute"/>.</exception>
|
||||||
|
/// <exception cref="SheetNotFoundException">Sheet does not exist.</exception>
|
||||||
|
/// <exception cref="MismatchedColumnHashException">Sheet had a mismatched column hash.</exception>
|
||||||
|
/// <exception cref="UnsupportedLanguageException">Sheet does not support <paramref name="language" /> nor <see cref="Language.None"/>.</exception>
|
||||||
|
/// <exception cref="NotSupportedException">Sheet was not a <see cref="ExcelVariant.Subrows"/>.</exception>
|
||||||
|
public SubrowExcelSheet<T> GetSubrowExcelSheet<T>(ClientLanguage? language = null, string? name = null) where T : struct, IExcelSubrow<T>;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get a <see cref="FileResource"/> with the given path.
|
/// Get a <see cref="FileResource"/> with the given path.
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||||
|
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
|
|
||||||
namespace Dalamud.Utility;
|
namespace Dalamud.Utility;
|
||||||
|
|
||||||
|
|
@ -149,9 +149,7 @@ public static class MapUtil
|
||||||
if (agentMap == null || agentMap->CurrentMapId == 0)
|
if (agentMap == null || agentMap->CurrentMapId == 0)
|
||||||
throw new InvalidOperationException("Could not determine active map - data may not be loaded yet?");
|
throw new InvalidOperationException("Could not determine active map - data may not be loaded yet?");
|
||||||
|
|
||||||
var territoryTransient = Service<DataManager>.Get()
|
var territoryTransient = LuminaUtils.CreateRef<TerritoryTypeTransient>(agentMap->CurrentTerritoryId);
|
||||||
.GetExcelSheet<TerritoryTypeTransient>()!
|
|
||||||
.GetRow(agentMap->CurrentTerritoryId);
|
|
||||||
|
|
||||||
return WorldToMap(
|
return WorldToMap(
|
||||||
go.Position,
|
go.Position,
|
||||||
|
|
@ -161,7 +159,7 @@ public static class MapUtil
|
||||||
*/
|
*/
|
||||||
-agentMap->CurrentOffsetX,
|
-agentMap->CurrentOffsetX,
|
||||||
-agentMap->CurrentOffsetY,
|
-agentMap->CurrentOffsetY,
|
||||||
territoryTransient?.OffsetZ ?? 0,
|
territoryTransient.ValueNullable?.OffsetZ ?? 0,
|
||||||
(uint)agentMap->CurrentMapSizeFactor,
|
(uint)agentMap->CurrentMapSizeFactor,
|
||||||
correctZOffset);
|
correctZOffset);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
using Lumina.Text.Parse;
|
using Lumina.Text.Parse;
|
||||||
|
|
||||||
|
using Lumina.Text.ReadOnly;
|
||||||
|
|
||||||
using DSeString = Dalamud.Game.Text.SeStringHandling.SeString;
|
using DSeString = Dalamud.Game.Text.SeStringHandling.SeString;
|
||||||
using DSeStringBuilder = Dalamud.Game.Text.SeStringHandling.SeStringBuilder;
|
using DSeStringBuilder = Dalamud.Game.Text.SeStringHandling.SeStringBuilder;
|
||||||
|
|
@ -20,6 +22,22 @@ public static class SeStringExtensions
|
||||||
/// <returns>The re-parsed Dalamud SeString.</returns>
|
/// <returns>The re-parsed Dalamud SeString.</returns>
|
||||||
public static DSeString ToDalamudString(this LSeString originalString) => DSeString.Parse(originalString.RawData);
|
public static DSeString ToDalamudString(this LSeString originalString) => DSeString.Parse(originalString.RawData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a Lumina ReadOnlySeString into a Dalamud SeString.
|
||||||
|
/// This conversion re-parses the string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="originalString">The original Lumina ReadOnlySeString.</param>
|
||||||
|
/// <returns>The re-parsed Dalamud SeString.</returns>
|
||||||
|
public static DSeString ToDalamudString(this ReadOnlySeString originalString) => DSeString.Parse(originalString.Data.Span);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a Lumina ReadOnlySeStringSpan into a Dalamud SeString.
|
||||||
|
/// This conversion re-parses the string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="originalString">The original Lumina ReadOnlySeStringSpan.</param>
|
||||||
|
/// <returns>The re-parsed Dalamud SeString.</returns>
|
||||||
|
public static DSeString ToDalamudString(this ReadOnlySeStringSpan originalString) => DSeString.Parse(originalString.Data);
|
||||||
|
|
||||||
/// <summary>Compiles and appends a macro string.</summary>
|
/// <summary>Compiles and appends a macro string.</summary>
|
||||||
/// <param name="ssb">Target SeString builder.</param>
|
/// <param name="ssb">Target SeString builder.</param>
|
||||||
/// <param name="macroString">Macro string in UTF-8 to compile and append to <paramref name="ssb"/>.</param>
|
/// <param name="macroString">Macro string in UTF-8 to compile and append to <paramref name="ssb"/>.</param>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ using Dalamud.Interface.Colors;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
using Dalamud.Support;
|
using Dalamud.Support;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.Sheets;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using TerraFX.Interop.Windows;
|
using TerraFX.Interop.Windows;
|
||||||
using Windows.Win32.Storage.FileSystem;
|
using Windows.Win32.Storage.FileSystem;
|
||||||
|
|
@ -813,7 +813,7 @@ public static class Util
|
||||||
var names = data.GetExcelSheet<BNpcName>(ClientLanguage.English)!;
|
var names = data.GetExcelSheet<BNpcName>(ClientLanguage.English)!;
|
||||||
var rng = new Random();
|
var rng = new Random();
|
||||||
|
|
||||||
return names.ElementAt(rng.Next(0, names.Count() - 1)).Singular.RawString;
|
return names.GetRowAt(rng.Next(0, names.Count - 1)).Singular.ExtractText();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -891,13 +891,13 @@ public static class Util
|
||||||
if (actor is ICharacter chara)
|
if (actor is ICharacter chara)
|
||||||
{
|
{
|
||||||
actorString +=
|
actorString +=
|
||||||
$" Level: {chara.Level} ClassJob: {(resolveGameData ? chara.ClassJob.GameData?.Name : chara.ClassJob.Id.ToString())} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n Customize: {BitConverter.ToString(chara.Customize).Replace("-", " ")} StatusFlags: {chara.StatusFlags}\n";
|
$" Level: {chara.Level} ClassJob: {(resolveGameData ? chara.ClassJob.ValueNullable?.Name : chara.ClassJob.RowId.ToString())} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n Customize: {BitConverter.ToString(chara.Customize).Replace("-", " ")} StatusFlags: {chara.StatusFlags}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor is IPlayerCharacter pc)
|
if (actor is IPlayerCharacter pc)
|
||||||
{
|
{
|
||||||
actorString +=
|
actorString +=
|
||||||
$" HomeWorld: {(resolveGameData ? pc.HomeWorld.GameData?.Name : pc.HomeWorld.Id.ToString())} CurrentWorld: {(resolveGameData ? pc.CurrentWorld.GameData?.Name : pc.CurrentWorld.Id.ToString())} FC: {pc.CompanyTag}\n";
|
$" HomeWorld: {(resolveGameData ? pc.HomeWorld.ValueNullable?.Name : pc.HomeWorld.RowId.ToString())} CurrentWorld: {(resolveGameData ? pc.CurrentWorld.ValueNullable?.Name : pc.CurrentWorld.RowId.ToString())} FC: {pc.CompanyTag}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TextUnformatted(actorString);
|
ImGui.TextUnformatted(actorString);
|
||||||
|
|
@ -925,13 +925,13 @@ public static class Util
|
||||||
if (actor is Character chara)
|
if (actor is Character chara)
|
||||||
{
|
{
|
||||||
actorString +=
|
actorString +=
|
||||||
$" Level: {chara.Level} ClassJob: {(resolveGameData ? chara.ClassJob.GameData?.Name : chara.ClassJob.Id.ToString())} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n Customize: {BitConverter.ToString(chara.Customize).Replace("-", " ")} StatusFlags: {chara.StatusFlags}\n";
|
$" Level: {chara.Level} ClassJob: {(resolveGameData ? chara.ClassJob.ValueNullable?.Name : chara.ClassJob.RowId.ToString())} CHP: {chara.CurrentHp} MHP: {chara.MaxHp} CMP: {chara.CurrentMp} MMP: {chara.MaxMp}\n Customize: {BitConverter.ToString(chara.Customize).Replace("-", " ")} StatusFlags: {chara.StatusFlags}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor is PlayerCharacter pc)
|
if (actor is PlayerCharacter pc)
|
||||||
{
|
{
|
||||||
actorString +=
|
actorString +=
|
||||||
$" HomeWorld: {(resolveGameData ? pc.HomeWorld.GameData?.Name : pc.HomeWorld.Id.ToString())} CurrentWorld: {(resolveGameData ? pc.CurrentWorld.GameData?.Name : pc.CurrentWorld.Id.ToString())} FC: {pc.CompanyTag}\n";
|
$" HomeWorld: {(resolveGameData ? pc.HomeWorld.ValueNullable?.Name : pc.HomeWorld.RowId.ToString())} CurrentWorld: {(resolveGameData ? pc.CurrentWorld.ValueNullable?.Name : pc.CurrentWorld.RowId.ToString())} FC: {pc.CompanyTag}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.TextUnformatted(actorString);
|
ImGui.TextUnformatted(actorString);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 81fb801905b7fe8e02aa40dcf9942e0f707dcc21
|
Subproject commit 7c5f04e346067f7a316ad9072fb8260122ba80f0
|
||||||
Loading…
Add table
Add a link
Reference in a new issue