mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Add interfaces to non public/sealed classes referenced in public interfaces (#1808)
* Add interfaces to non public/sealed classes referenced in public interfaces * Fixed inheritdocs + made most classes internal * Add missing properties to IFate and Fate, fix documentation --------- Co-authored-by: goat <16760685+goaaats@users.noreply.github.com>
This commit is contained in:
parent
3994f528b8
commit
7947b896ea
55 changed files with 1466 additions and 584 deletions
|
|
@ -73,7 +73,7 @@ namespace Dalamud.CorePlugin
|
||||||
Log.Information($"CorePlugin : DefaultFontHandle.ImFontChanged called {fc}");
|
Log.Information($"CorePlugin : DefaultFontHandle.ImFontChanged called {fc}");
|
||||||
};
|
};
|
||||||
|
|
||||||
Service<CommandManager>.Get().AddHandler("/coreplug", new(this.OnCommand) { HelpMessage = "Access the plugin." });
|
Service<CommandManager>.Get().AddHandler("/coreplug", new CommandInfo(this.OnCommand) { HelpMessage = "Access the plugin." });
|
||||||
|
|
||||||
log.Information("CorePlugin ctor!");
|
log.Information("CorePlugin ctor!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@ using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||||
namespace Dalamud.Game.ClientState.Aetherytes;
|
namespace Dalamud.Game.ClientState.Aetherytes;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an entry in the Aetheryte list.
|
/// Class representing an aetheryte entry available to the game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class AetheryteEntry
|
internal sealed class AetheryteEntry : IAetheryteEntry
|
||||||
{
|
{
|
||||||
private readonly TeleportInfo data;
|
private readonly TeleportInfo data;
|
||||||
|
|
||||||
|
|
@ -19,53 +19,90 @@ public sealed class AetheryteEntry
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint AetheryteId => this.data.AetheryteId;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint TerritoryId => this.data.TerritoryId;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public byte SubIndex => this.data.SubIndex;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public byte Ward => this.data.Ward;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public byte Plot => this.data.Plot;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint GilCost => this.data.GilCost;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsFavourite => this.data.IsFavourite != 0;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsSharedHouse => this.data.IsSharedHouse;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public bool IsApartment => this.data.IsApartment;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.Aetheryte> AetheryteData => new(this.AetheryteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing an aetheryte entry available to the game.
|
||||||
|
/// </summary>
|
||||||
|
public interface IAetheryteEntry
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Aetheryte ID.
|
/// Gets the Aetheryte ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint AetheryteId => this.data.AetheryteId;
|
uint AetheryteId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Territory ID.
|
/// Gets the Territory ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint TerritoryId => this.data.TerritoryId;
|
uint TerritoryId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the SubIndex used when there can be multiple Aetherytes with the same ID (Private/Shared Estates etc.).
|
/// Gets the SubIndex used when there can be multiple Aetherytes with the same ID (Private/Shared Estates etc.).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte SubIndex => this.data.SubIndex;
|
byte SubIndex { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Ward. Zero if not a Shared Estate.
|
/// Gets the Ward. Zero if not a Shared Estate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte Ward => this.data.Ward;
|
byte Ward { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Plot. Zero if not a Shared Estate.
|
/// Gets the Plot. Zero if not a Shared Estate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte Plot => this.data.Plot;
|
byte Plot { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Cost in Gil to Teleport to this location.
|
/// Gets the Cost in Gil to Teleport to this location.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint GilCost => this.data.GilCost;
|
uint GilCost { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether the LocalPlayer has set this Aetheryte as Favorite or not.
|
/// Gets a value indicating whether the LocalPlayer has set this Aetheryte as Favorite or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsFavourite => this.data.IsFavourite != 0;
|
bool IsFavourite { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Aetheryte is a Shared Estate or not.
|
/// Gets a value indicating whether this Aetheryte is a Shared Estate or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsSharedHouse => this.data.IsSharedHouse;
|
bool IsSharedHouse { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether this Aetheryte is an Apartment or not.
|
/// Gets a value indicating whether this Aetheryte is an Apartment or not.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsApartment => this.data.IsApartment;
|
bool IsApartment { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Aetheryte data related to this aetheryte.
|
/// Gets the Aetheryte data related to this aetheryte.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Aetheryte> AetheryteData => new(this.AetheryteId);
|
ExcelResolver<Lumina.Excel.GeneratedSheets.Aetheryte> AetheryteData { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public AetheryteEntry? this[int index]
|
public IAetheryteEntry? this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -84,7 +84,7 @@ internal sealed partial class AetheryteList
|
||||||
public int Count => this.Length;
|
public int Count => this.Length;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<AetheryteEntry> GetEnumerator()
|
public IEnumerator<IAetheryteEntry> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < this.Length; i++)
|
for (var i = 0; i < this.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public BuddyMember? CompanionBuddy
|
public IBuddyMember? CompanionBuddy
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -66,7 +66,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public BuddyMember? PetBuddy
|
public IBuddyMember? PetBuddy
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -85,7 +85,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
||||||
private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy*)this.BuddyListAddress;
|
private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy*)this.BuddyListAddress;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public BuddyMember? this[int index]
|
public IBuddyMember? this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -116,7 +116,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public BuddyMember? CreateBuddyMemberReference(IntPtr address)
|
public IBuddyMember? CreateBuddyMemberReference(IntPtr address)
|
||||||
{
|
{
|
||||||
if (this.clientState.LocalContentId == 0)
|
if (this.clientState.LocalContentId == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -138,10 +138,10 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
||||||
internal sealed partial class BuddyList
|
internal sealed partial class BuddyList
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
int IReadOnlyCollection<BuddyMember>.Count => this.Length;
|
int IReadOnlyCollection<IBuddyMember>.Count => this.Length;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<BuddyMember> GetEnumerator()
|
public IEnumerator<IBuddyMember> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < this.Length; i++)
|
for (var i = 0; i < this.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Dalamud.Game.ClientState.Buddy;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a buddy such as the chocobo companion, summoned pets, squadron groups and trust parties.
|
/// This class represents a buddy such as the chocobo companion, summoned pets, squadron groups and trust parties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class BuddyMember
|
internal unsafe class BuddyMember : IBuddyMember
|
||||||
{
|
{
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly ObjectTable objectTable = Service<ObjectTable>.Get();
|
private readonly ObjectTable objectTable = Service<ObjectTable>.Get();
|
||||||
|
|
@ -21,15 +21,50 @@ public unsafe class BuddyMember
|
||||||
this.Address = address;
|
this.Address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint ObjectId => this.Struct->EntityId;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IGameObject? GameObject => this.objectTable.SearchById(this.ObjectId);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint CurrentHP => this.Struct->CurrentHealth;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint MaxHP => this.Struct->MaxHealth;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public uint DataID => this.Struct->DataId;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.Mount> MountData => new(this.DataID);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.Pet> PetData => new(this.DataID);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData => new(this.DataID);
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing represents a buddy such as the chocobo companion, summoned pets, squadron groups and trust parties.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBuddyMember
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the buddy in memory.
|
/// Gets the address of the buddy in memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr Address { get; }
|
IntPtr Address { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the object ID of this buddy.
|
/// Gets the object ID of this buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint ObjectId => this.Struct->EntityId;
|
unsafe uint ObjectId { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the actor associated with this buddy.
|
/// Gets the actor associated with this buddy.
|
||||||
|
|
@ -37,37 +72,35 @@ public unsafe class BuddyMember
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This iterates the actor table, it should be used with care.
|
/// This iterates the actor table, it should be used with care.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public GameObject? GameObject => this.objectTable.SearchById(this.ObjectId);
|
IGameObject? GameObject { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current health of this buddy.
|
/// Gets the current health of this buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint CurrentHP => this.Struct->CurrentHealth;
|
unsafe uint CurrentHP { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum health of this buddy.
|
/// Gets the maximum health of this buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint MaxHP => this.Struct->MaxHealth;
|
unsafe uint MaxHP { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data ID of this buddy.
|
/// Gets the data ID of this buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint DataID => this.Struct->DataId;
|
unsafe uint DataID { get; }
|
||||||
|
|
||||||
/// <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>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Mount> MountData => new(this.DataID);
|
ExcelResolver<Lumina.Excel.GeneratedSheets.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>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.Pet> PetData => new(this.DataID);
|
ExcelResolver<Lumina.Excel.GeneratedSheets.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>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData => new(this.DataID);
|
ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData { get; }
|
||||||
|
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public PlayerCharacter? LocalPlayer => Service<ObjectTable>.GetNullable()?[0] as PlayerCharacter;
|
public IPlayerCharacter? LocalPlayer => Service<ObjectTable>.GetNullable()?[0] as IPlayerCharacter;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ulong LocalContentId => (ulong)Marshal.ReadInt64(this.address.LocalContentId);
|
public ulong LocalContentId => (ulong)Marshal.ReadInt64(this.address.LocalContentId);
|
||||||
|
|
@ -275,7 +275,7 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
||||||
public uint MapId => this.clientStateService.MapId;
|
public uint MapId => this.clientStateService.MapId;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public PlayerCharacter? LocalPlayer => this.clientStateService.LocalPlayer;
|
public IPlayerCharacter? LocalPlayer => this.clientStateService.LocalPlayer;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ulong LocalContentId => this.clientStateService.LocalContentId;
|
public ulong LocalContentId => this.clientStateService.LocalContentId;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Dalamud.Game.ClientState.Fates;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an FFXIV Fate.
|
/// This class represents an FFXIV Fate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe partial class Fate : IEquatable<Fate>
|
internal unsafe partial class Fate
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Fate"/> class.
|
/// Initializes a new instance of the <see cref="Fate"/> class.
|
||||||
|
|
@ -21,9 +21,7 @@ public unsafe partial class Fate : IEquatable<Fate>
|
||||||
this.Address = address;
|
this.Address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// Gets the address of this Fate in memory.
|
|
||||||
/// </summary>
|
|
||||||
public IntPtr Address { get; }
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext*)this.Address;
|
private FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateContext*)this.Address;
|
||||||
|
|
@ -63,10 +61,10 @@ public unsafe partial class Fate : IEquatable<Fate>
|
||||||
public bool IsValid() => IsValid(this);
|
public bool IsValid() => IsValid(this);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
bool IEquatable<Fate>.Equals(Fate other) => this.FateId == other?.FateId;
|
bool IEquatable<IFate>.Equals(IFate other) => this.FateId == other?.FateId;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool Equals(object obj) => ((IEquatable<Fate>)this).Equals(obj as Fate);
|
public override bool Equals(object obj) => ((IEquatable<IFate>)this).Equals(obj as IFate);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override int GetHashCode() => this.FateId.GetHashCode();
|
public override int GetHashCode() => this.FateId.GetHashCode();
|
||||||
|
|
@ -75,60 +73,171 @@ public unsafe partial class Fate : IEquatable<Fate>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an FFXIV Fate.
|
/// This class represents an FFXIV Fate.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe partial class Fate
|
internal unsafe partial class Fate : IFate
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Fate ID of this <see cref="Fate" />.
|
|
||||||
/// </summary>
|
|
||||||
public ushort FateId => this.Struct->FateId;
|
public ushort FateId => this.Struct->FateId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets game data linked to this Fate.
|
|
||||||
/// </summary>
|
|
||||||
public Lumina.Excel.GeneratedSheets.Fate GameData => Service<DataManager>.Get().GetExcelSheet<Lumina.Excel.GeneratedSheets.Fate>().GetRow(this.FateId);
|
public Lumina.Excel.GeneratedSheets.Fate GameData => Service<DataManager>.Get().GetExcelSheet<Lumina.Excel.GeneratedSheets.Fate>().GetRow(this.FateId);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the time this <see cref="Fate"/> started.
|
|
||||||
/// </summary>
|
|
||||||
public int StartTimeEpoch => this.Struct->StartTimeEpoch;
|
public int StartTimeEpoch => this.Struct->StartTimeEpoch;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets how long this <see cref="Fate"/> will run.
|
|
||||||
/// </summary>
|
|
||||||
public short Duration => this.Struct->Duration;
|
public short Duration => this.Struct->Duration;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the remaining time in seconds for this <see cref="Fate"/>.
|
|
||||||
/// </summary>
|
|
||||||
public long TimeRemaining => this.StartTimeEpoch + this.Duration - DateTimeOffset.Now.ToUnixTimeSeconds();
|
public long TimeRemaining => this.StartTimeEpoch + this.Duration - DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the displayname of this <see cref="Fate" />.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Name => MemoryHelper.ReadSeString(&this.Struct->Name);
|
public SeString Name => MemoryHelper.ReadSeString(&this.Struct->Name);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the state of this <see cref="Fate"/> (Running, Ended, Failed, Preparation, WaitingForEnd).
|
public SeString Description => MemoryHelper.ReadSeString(&this.Struct->Description);
|
||||||
/// </summary>
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public SeString Objective => MemoryHelper.ReadSeString(&this.Struct->Objective);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public FateState State => (FateState)this.Struct->State;
|
public FateState State => (FateState)this.Struct->State;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the progress amount of this <see cref="Fate"/>.
|
public byte HandInCount => this.Struct->HandInCount;
|
||||||
/// </summary>
|
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public byte Progress => this.Struct->Progress;
|
public byte Progress => this.Struct->Progress;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the level of this <see cref="Fate"/>.
|
public bool HasExpBonus => this.Struct->IsExpBonus;
|
||||||
/// </summary>
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public uint IconId => this.Struct->IconId;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public byte Level => this.Struct->Level;
|
public byte Level => this.Struct->Level;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the position of this <see cref="Fate"/>.
|
public byte MaxLevel => this.Struct->MaxLevel;
|
||||||
/// </summary>
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public Vector3 Position => this.Struct->Location;
|
public Vector3 Position => this.Struct->Location;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public float Radius => this.Struct->Radius;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public uint MapIconId => this.Struct->MapIconId;
|
||||||
|
|
||||||
/// <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 ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> TerritoryType => new(this.Struct->TerritoryId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing an fate entry that can be seen in the current area.
|
||||||
|
/// </summary>
|
||||||
|
public interface IFate : IEquatable<IFate>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Fate ID of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
ushort FateId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets game data linked to this Fate.
|
||||||
|
/// </summary>
|
||||||
|
Lumina.Excel.GeneratedSheets.Fate GameData { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time this <see cref="Fate"/> started.
|
||||||
|
/// </summary>
|
||||||
|
int StartTimeEpoch { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets how long this <see cref="Fate"/> will run.
|
||||||
|
/// </summary>
|
||||||
|
short Duration { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the remaining time in seconds for this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
long TimeRemaining { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the displayname of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
SeString Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the description of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
SeString Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the objective of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
SeString Objective { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of this <see cref="Fate"/> (Running, Ended, Failed, Preparation, WaitingForEnd).
|
||||||
|
/// </summary>
|
||||||
|
FateState State { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hand in count of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
byte HandInCount { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the progress amount of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
byte Progress { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether or not this <see cref="Fate"/> has a EXP bonus.
|
||||||
|
/// </summary>
|
||||||
|
bool HasExpBonus { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the icon id of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
uint IconId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
byte Level { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the max level level of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
byte MaxLevel { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
Vector3 Position { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the radius of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
float Radius { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the map icon id of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
uint MapIconId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the territory this <see cref="Fate"/> is located in.
|
||||||
|
/// </summary>
|
||||||
|
ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> TerritoryType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of this Fate in memory.
|
||||||
|
/// </summary>
|
||||||
|
IntPtr Address { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
||||||
private unsafe FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager*)this.FateTableAddress;
|
private unsafe FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Fate.FateManager*)this.FateTableAddress;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Fate? this[int index]
|
public IFate? this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -78,6 +78,20 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsValid(IFate fate)
|
||||||
|
{
|
||||||
|
var clientState = Service<ClientState>.GetNullable();
|
||||||
|
|
||||||
|
if (fate == null || clientState == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (clientState.LocalContentId == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public unsafe IntPtr GetFateAddress(int index)
|
public unsafe IntPtr GetFateAddress(int index)
|
||||||
{
|
{
|
||||||
|
|
@ -92,7 +106,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public Fate? CreateFateReference(IntPtr offset)
|
public IFate? CreateFateReference(IntPtr offset)
|
||||||
{
|
{
|
||||||
var clientState = Service<ClientState>.Get();
|
var clientState = Service<ClientState>.Get();
|
||||||
|
|
||||||
|
|
@ -112,10 +126,10 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
||||||
internal sealed partial class FateTable
|
internal sealed partial class FateTable
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
int IReadOnlyCollection<Fate>.Count => this.Length;
|
int IReadOnlyCollection<IFate>.Count => this.Length;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<Fate> GetEnumerator()
|
public IEnumerator<IFate> GetEnumerator()
|
||||||
{
|
{
|
||||||
for (var i = 0; i < this.Length; i++)
|
for (var i = 0; i < this.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
||||||
public int Length => ObjectTableLength;
|
public int Length => ObjectTableLength;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? this[int index]
|
public IGameObject? this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -82,7 +82,7 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? SearchById(ulong gameObjectId)
|
public IGameObject? SearchById(ulong gameObjectId)
|
||||||
{
|
{
|
||||||
_ = this.WarnMultithreadedUsage();
|
_ = this.WarnMultithreadedUsage();
|
||||||
|
|
||||||
|
|
@ -107,7 +107,7 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public unsafe GameObject? CreateObjectReference(nint address)
|
public unsafe IGameObject? CreateObjectReference(nint address)
|
||||||
{
|
{
|
||||||
_ = this.WarnMultithreadedUsage();
|
_ = this.WarnMultithreadedUsage();
|
||||||
|
|
||||||
|
|
@ -216,7 +216,7 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
||||||
internal sealed partial class ObjectTable
|
internal sealed partial class ObjectTable
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<GameObject> GetEnumerator()
|
public IEnumerator<IGameObject> GetEnumerator()
|
||||||
{
|
{
|
||||||
// If something's trying to enumerate outside the framework thread, we use the ObjectPool.
|
// If something's trying to enumerate outside the framework thread, we use the ObjectPool.
|
||||||
if (this.WarnMultithreadedUsage())
|
if (this.WarnMultithreadedUsage())
|
||||||
|
|
@ -246,7 +246,7 @@ internal sealed partial class ObjectTable
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
|
||||||
private sealed class Enumerator : IEnumerator<GameObject>, IResettable
|
private sealed class Enumerator : IEnumerator<IGameObject>, IResettable
|
||||||
{
|
{
|
||||||
private readonly int slotId;
|
private readonly int slotId;
|
||||||
private ObjectTable? owner;
|
private ObjectTable? owner;
|
||||||
|
|
@ -261,7 +261,7 @@ internal sealed partial class ObjectTable
|
||||||
this.slotId = slotId;
|
this.slotId = slotId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameObject Current { get; private set; } = null!;
|
public IGameObject Current { get; private set; } = null!;
|
||||||
|
|
||||||
object IEnumerator.Current => this.Current;
|
object IEnumerator.Current => this.Current;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Dalamud.Game.ClientState.Objects.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a battle NPC.
|
/// This class represents a battle NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class BattleNpc : BattleChara
|
internal unsafe class BattleNpc : BattleChara, IBattleNpc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
||||||
|
|
@ -25,3 +25,14 @@ public unsafe class BattleNpc : BattleChara
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override ulong TargetObjectId => this.Struct->Character.TargetId;
|
public override ulong TargetObjectId => this.Struct->Character.TargetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A interface that represents a battle NPC.
|
||||||
|
/// </summary>
|
||||||
|
internal interface IBattleNpc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the BattleNpc <see cref="BattleNpcSubKind" /> of this BattleNpc.
|
||||||
|
/// </summary>
|
||||||
|
BattleNpcSubKind BattleNpcKind { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an EventObj.
|
/// This class represents an EventObj.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class EventObj : GameObject
|
internal unsafe class EventObj : GameObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a NPC.
|
/// This class represents a NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class Npc : Character
|
internal unsafe class Npc : Character
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Npc"/> class.
|
/// Initializes a new instance of the <see cref="Npc"/> class.
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,19 @@
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
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.Resolvers;
|
||||||
|
using Dalamud.Game.ClientState.Statuses;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
|
||||||
|
using Lumina.Excel.GeneratedSheets;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
namespace Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a player character.
|
/// This class represents a player character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class PlayerCharacter : BattleChara
|
internal unsafe class PlayerCharacter : BattleChara, IPlayerCharacter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
||||||
|
|
@ -18,14 +25,10 @@ public unsafe class PlayerCharacter : BattleChara
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
|
|
||||||
/// </summary>
|
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(this.Struct->CurrentWorld);
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(this.Struct->CurrentWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
|
|
||||||
/// </summary>
|
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(this.Struct->HomeWorld);
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(this.Struct->HomeWorld);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -33,3 +36,19 @@ public unsafe class PlayerCharacter : BattleChara
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override ulong TargetObjectId => this.Struct->LookAt.Controller.Params[0].TargetParam.TargetId;
|
public override ulong TargetObjectId => this.Struct->LookAt.Controller.Params[0].TargetParam.TargetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a player character.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPlayerCharacter : IBattleChara
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
|
||||||
|
/// </summary>
|
||||||
|
unsafe ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
|
||||||
|
/// </summary>
|
||||||
|
unsafe ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,49 +27,49 @@ internal sealed unsafe class TargetManager : IServiceType, ITargetManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? Target
|
public IGameObject? Target
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->Target);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->Target);
|
||||||
set => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? MouseOverTarget
|
public IGameObject? MouseOverTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->MouseOverTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->MouseOverTarget);
|
||||||
set => Struct->MouseOverTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->MouseOverTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? FocusTarget
|
public IGameObject? FocusTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->FocusTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->FocusTarget);
|
||||||
set => Struct->FocusTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->FocusTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? PreviousTarget
|
public IGameObject? PreviousTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->PreviousTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->PreviousTarget);
|
||||||
set => Struct->PreviousTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->PreviousTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? SoftTarget
|
public IGameObject? SoftTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->SoftTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->SoftTarget);
|
||||||
set => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? GPoseTarget
|
public IGameObject? GPoseTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->GPoseTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->GPoseTarget);
|
||||||
set => Struct->GPoseTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->GPoseTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public GameObject? MouseOverNameplateTarget
|
public IGameObject? MouseOverNameplateTarget
|
||||||
{
|
{
|
||||||
get => this.objectTable.CreateObjectReference((IntPtr)Struct->MouseOverNameplateTarget);
|
get => this.objectTable.CreateObjectReference((IntPtr)Struct->MouseOverNameplateTarget);
|
||||||
set => Struct->MouseOverNameplateTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
set => Struct->MouseOverNameplateTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)value?.Address;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Dalamud.Game.ClientState.Objects.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents the battle characters.
|
/// This class represents the battle characters.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class BattleChara : Character
|
internal unsafe class BattleChara : Character, IBattleChara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BattleChara"/> class.
|
/// Initializes a new instance of the <see cref="BattleChara"/> class.
|
||||||
|
|
@ -18,57 +18,32 @@ public unsafe class BattleChara : Character
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current status effects.
|
|
||||||
/// </summary>
|
|
||||||
public StatusList StatusList => new(this.Struct->GetStatusManager());
|
public StatusList StatusList => new(this.Struct->GetStatusManager());
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a value indicating whether the chara is currently casting.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsCasting => this.Struct->GetCastInfo()->IsCasting > 0;
|
public bool IsCasting => this.Struct->GetCastInfo()->IsCasting > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a value indicating whether the cast is interruptible.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsCastInterruptible => this.Struct->GetCastInfo()->Interruptible > 0;
|
public bool IsCastInterruptible => this.Struct->GetCastInfo()->Interruptible > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the spell action type of the spell being cast by the actor.
|
|
||||||
/// </summary>
|
|
||||||
public byte CastActionType => (byte)this.Struct->GetCastInfo()->ActionType;
|
public byte CastActionType => (byte)this.Struct->GetCastInfo()->ActionType;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the spell action ID of the spell being cast by the actor.
|
|
||||||
/// </summary>
|
|
||||||
public uint CastActionId => this.Struct->GetCastInfo()->ActionId;
|
public uint CastActionId => this.Struct->GetCastInfo()->ActionId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the object ID of the target currently being cast at by the chara.
|
|
||||||
/// </summary>
|
|
||||||
public ulong CastTargetObjectId => this.Struct->GetCastInfo()->TargetId;
|
public ulong CastTargetObjectId => this.Struct->GetCastInfo()->TargetId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current casting time of the spell being cast by the chara.
|
|
||||||
/// </summary>
|
|
||||||
public float CurrentCastTime => this.Struct->GetCastInfo()->CurrentCastTime;
|
public float CurrentCastTime => this.Struct->GetCastInfo()->CurrentCastTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the total casting time of the spell being cast by the chara.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This can only be a portion of the total cast for some actions.
|
|
||||||
/// Use AdjustedTotalCastTime if you always need the total cast time.
|
|
||||||
/// </remarks>
|
|
||||||
[Api10ToDo("Rename so it is not confused with AdjustedTotalCastTime")]
|
[Api10ToDo("Rename so it is not confused with AdjustedTotalCastTime")]
|
||||||
public float TotalCastTime => this.Struct->GetCastInfo()->TotalCastTime;
|
public float TotalCastTime => this.Struct->GetCastInfo()->TotalCastTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the <see cref="TotalCastTime"/> plus any adjustments from the game, such as Action offset 2B. Used for display purposes.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is the actual total cast time for all actions.
|
|
||||||
/// </remarks>
|
|
||||||
[Api10ToDo("Rename so it is not confused with TotalCastTime")]
|
[Api10ToDo("Rename so it is not confused with TotalCastTime")]
|
||||||
public float AdjustedTotalCastTime => this.Struct->GetCastInfo()->AdjustedTotalCastTime;
|
public float AdjustedTotalCastTime => this.Struct->GetCastInfo()->AdjustedTotalCastTime;
|
||||||
|
|
||||||
|
|
@ -77,3 +52,61 @@ public unsafe class BattleChara : Character
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected internal new FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)this.Address;
|
protected internal new FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)this.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a battle character.
|
||||||
|
/// </summary>
|
||||||
|
public interface IBattleChara : ICharacter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current status effects.
|
||||||
|
/// </summary>
|
||||||
|
public StatusList StatusList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the chara is currently casting.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCasting { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the cast is interruptible.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCastInterruptible { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the spell action type of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public byte CastActionType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the spell action ID of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public uint CastActionId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the object ID of the target currently being cast at by the chara.
|
||||||
|
/// </summary>
|
||||||
|
public ulong CastTargetObjectId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current casting time of the spell being cast by the chara.
|
||||||
|
/// </summary>
|
||||||
|
public float CurrentCastTime { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total casting time of the spell being cast by the chara.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This can only be a portion of the total cast for some actions.
|
||||||
|
/// Use AdjustedTotalCastTime if you always need the total cast time.
|
||||||
|
/// </remarks>
|
||||||
|
public float TotalCastTime { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the <see cref="TotalCastTime"/> plus any adjustments from the game, such as Action offset 2B. Used for display purposes.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the actual total cast time for all actions.
|
||||||
|
/// </remarks>
|
||||||
|
public float AdjustedTotalCastTime { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Dalamud.Game.ClientState.Objects.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents the base for non-static entities.
|
/// This class represents the base for non-static entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class Character : GameObject
|
internal unsafe class Character : GameObject, ICharacter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Character"/> class.
|
/// Initializes a new instance of the <see cref="Character"/> class.
|
||||||
|
|
@ -23,70 +23,43 @@ public unsafe class Character : GameObject
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current HP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentHp => this.Struct->CharacterData.Health;
|
public uint CurrentHp => this.Struct->CharacterData.Health;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the maximum HP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxHp => this.Struct->CharacterData.MaxHealth;
|
public uint MaxHp => this.Struct->CharacterData.MaxHealth;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current MP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentMp => this.Struct->CharacterData.Mana;
|
public uint CurrentMp => this.Struct->CharacterData.Mana;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the maximum MP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxMp => this.Struct->CharacterData.MaxMana;
|
public uint MaxMp => this.Struct->CharacterData.MaxMana;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current GP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentGp => this.Struct->CharacterData.GatheringPoints;
|
public uint CurrentGp => this.Struct->CharacterData.GatheringPoints;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the maximum GP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxGp => this.Struct->CharacterData.MaxGatheringPoints;
|
public uint MaxGp => this.Struct->CharacterData.MaxGatheringPoints;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current CP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentCp => this.Struct->CharacterData.CraftingPoints;
|
public uint CurrentCp => this.Struct->CharacterData.CraftingPoints;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the maximum CP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxCp => this.Struct->CharacterData.MaxCraftingPoints;
|
public uint MaxCp => this.Struct->CharacterData.MaxCraftingPoints;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the shield percentage of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public byte ShieldPercentage => this.Struct->CharacterData.ShieldValue;
|
public byte ShieldPercentage => this.Struct->CharacterData.ShieldValue;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the ClassJob of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public ExcelResolver<ClassJob> ClassJob => new(this.Struct->CharacterData.ClassJob);
|
public ExcelResolver<ClassJob> ClassJob => new(this.Struct->CharacterData.ClassJob);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the level of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public byte Level => this.Struct->CharacterData.Level;
|
public byte Level => this.Struct->CharacterData.Level;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a byte array describing the visual appearance of this Chara.
|
|
||||||
/// Indexed by <see cref="CustomizeIndex"/>.
|
|
||||||
/// </summary>
|
|
||||||
public byte[] Customize => this.Struct->DrawData.CustomizeData.Data.ToArray();
|
public byte[] Customize => this.Struct->DrawData.CustomizeData.Data.ToArray();
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Free Company tag of this chara.
|
|
||||||
/// </summary>
|
|
||||||
public SeString CompanyTag => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->FreeCompanyTag[0]), 6);
|
public SeString CompanyTag => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->FreeCompanyTag[0]), 6);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -94,14 +67,10 @@ public unsafe class Character : GameObject
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override ulong TargetObjectId => this.Struct->TargetId;
|
public override ulong TargetObjectId => this.Struct->TargetId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the name ID of the character.
|
|
||||||
/// </summary>
|
|
||||||
public uint NameId => this.Struct->NameId;
|
public uint NameId => this.Struct->NameId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current online status of the character.
|
|
||||||
/// </summary>
|
|
||||||
public ExcelResolver<OnlineStatus> OnlineStatus => new(this.Struct->CharacterData.OnlineStatus);
|
public ExcelResolver<OnlineStatus> OnlineStatus => new(this.Struct->CharacterData.OnlineStatus);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -123,3 +92,90 @@ public unsafe class Character : GameObject
|
||||||
protected internal new FFXIVClientStructs.FFXIV.Client.Game.Character.Character* Struct =>
|
protected internal new FFXIVClientStructs.FFXIV.Client.Game.Character.Character* Struct =>
|
||||||
(FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)this.Address;
|
(FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)this.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a character.
|
||||||
|
/// </summary>
|
||||||
|
public interface ICharacter : IGameObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current HP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentHp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum HP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxHp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current MP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentMp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum MP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxMp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current GP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentGp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum GP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxGp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current CP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentCp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum CP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxCp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the shield percentage of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public byte ShieldPercentage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ClassJob of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<ClassJob> ClassJob { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public byte Level { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a byte array describing the visual appearance of this Chara.
|
||||||
|
/// Indexed by <see cref="CustomizeIndex"/>.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Customize { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Free Company tag of this chara.
|
||||||
|
/// </summary>
|
||||||
|
public SeString CompanyTag { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name ID of the character.
|
||||||
|
/// </summary>
|
||||||
|
public uint NameId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current online status of the character.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<OnlineStatus> OnlineStatus { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the status flags.
|
||||||
|
/// </summary>
|
||||||
|
public StatusFlags StatusFlags { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Dalamud.Game.ClientState.Objects.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a GameObject in FFXIV.
|
/// This class represents a GameObject in FFXIV.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe partial class GameObject : IEquatable<GameObject>
|
internal partial class GameObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="GameObject"/> class.
|
/// Initializes a new instance of the <see cref="GameObject"/> class.
|
||||||
|
|
@ -54,7 +54,7 @@ public unsafe partial class GameObject : IEquatable<GameObject>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actor">The actor to check.</param>
|
/// <param name="actor">The actor to check.</param>
|
||||||
/// <returns>True or false.</returns>
|
/// <returns>True or false.</returns>
|
||||||
public static bool IsValid(GameObject? actor)
|
public static bool IsValid(IGameObject? actor)
|
||||||
{
|
{
|
||||||
var clientState = Service<ClientState>.GetNullable();
|
var clientState = Service<ClientState>.GetNullable();
|
||||||
|
|
||||||
|
|
@ -74,10 +74,10 @@ public unsafe partial class GameObject : IEquatable<GameObject>
|
||||||
public bool IsValid() => IsValid(this);
|
public bool IsValid() => IsValid(this);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
bool IEquatable<GameObject>.Equals(GameObject other) => this.GameObjectId == other?.GameObjectId;
|
bool IEquatable<IGameObject>.Equals(IGameObject other) => this.GameObjectId == other?.GameObjectId;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override bool Equals(object obj) => ((IEquatable<GameObject>)this).Equals(obj as GameObject);
|
public override bool Equals(object obj) => ((IEquatable<IGameObject>)this).Equals(obj as IGameObject);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override int GetHashCode() => this.GameObjectId.GetHashCode();
|
public override int GetHashCode() => this.GameObjectId.GetHashCode();
|
||||||
|
|
@ -86,103 +86,59 @@ public unsafe partial class GameObject : IEquatable<GameObject>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a basic actor (GameObject) in FFXIV.
|
/// This class represents a basic actor (GameObject) in FFXIV.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe partial class GameObject
|
internal unsafe partial class GameObject : IGameObject
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the name of this <see cref="GameObject" />.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->Name[0]), 64);
|
public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->Name[0]), 64);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the GameObjectID for this GameObject. The Game Object ID is a globally unique identifier that points to
|
|
||||||
/// this specific object. This ID is used to reference specific objects on the local client (e.g. for targeting).
|
|
||||||
///
|
|
||||||
/// Not to be confused with <see cref="EntityId"/>.
|
|
||||||
/// </summary>
|
|
||||||
public ulong GameObjectId => this.Struct->GetGameObjectId();
|
public ulong GameObjectId => this.Struct->GetGameObjectId();
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Entity ID for this GameObject. Entity IDs are assigned to networked GameObjects.
|
|
||||||
///
|
|
||||||
/// A value of <c>0xE000_0000</c> indicates that this entity is not networked and has specific interactivity rules.
|
|
||||||
/// </summary>
|
|
||||||
public uint EntityId => this.Struct->EntityId;
|
public uint EntityId => this.Struct->EntityId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the data ID for linking to other respective game data.
|
|
||||||
/// </summary>
|
|
||||||
public uint DataId => this.Struct->BaseId;
|
public uint DataId => this.Struct->BaseId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the ID of this GameObject's owner.
|
|
||||||
/// </summary>
|
|
||||||
public uint OwnerId => this.Struct->OwnerId;
|
public uint OwnerId => this.Struct->OwnerId;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the index of this object in the object table.
|
|
||||||
/// </summary>
|
|
||||||
public ushort ObjectIndex => this.Struct->ObjectIndex;
|
public ushort ObjectIndex => this.Struct->ObjectIndex;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the entity kind of this <see cref="GameObject" />.
|
|
||||||
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
|
||||||
/// </summary>
|
|
||||||
public ObjectKind ObjectKind => (ObjectKind)this.Struct->ObjectKind;
|
public ObjectKind ObjectKind => (ObjectKind)this.Struct->ObjectKind;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the sub kind of this Actor.
|
|
||||||
/// </summary>
|
|
||||||
public byte SubKind => this.Struct->SubKind;
|
public byte SubKind => this.Struct->SubKind;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the X distance from the local player in yalms.
|
|
||||||
/// </summary>
|
|
||||||
public byte YalmDistanceX => this.Struct->YalmDistanceFromPlayerX;
|
public byte YalmDistanceX => this.Struct->YalmDistanceFromPlayerX;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Y distance from the local player in yalms.
|
|
||||||
/// </summary>
|
|
||||||
public byte YalmDistanceZ => this.Struct->YalmDistanceFromPlayerZ;
|
public byte YalmDistanceZ => this.Struct->YalmDistanceFromPlayerZ;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a value indicating whether the object is dead or alive.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDead => this.Struct->IsDead();
|
public bool IsDead => this.Struct->IsDead();
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a value indicating whether the object is targetable.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsTargetable => this.Struct->GetIsTargetable();
|
public bool IsTargetable => this.Struct->GetIsTargetable();
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the position of this <see cref="GameObject" />.
|
|
||||||
/// </summary>
|
|
||||||
public Vector3 Position => new(this.Struct->Position.X, this.Struct->Position.Y, this.Struct->Position.Z);
|
public Vector3 Position => new(this.Struct->Position.X, this.Struct->Position.Y, this.Struct->Position.Z);
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the rotation of this <see cref="GameObject" />.
|
|
||||||
/// This ranges from -pi to pi radians.
|
|
||||||
/// </summary>
|
|
||||||
public float Rotation => this.Struct->Rotation;
|
public float Rotation => this.Struct->Rotation;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the hitbox radius of this <see cref="GameObject" />.
|
|
||||||
/// </summary>
|
|
||||||
public float HitboxRadius => this.Struct->HitboxRadius;
|
public float HitboxRadius => this.Struct->HitboxRadius;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current target of the game object.
|
|
||||||
/// </summary>
|
|
||||||
public virtual ulong TargetObjectId => 0;
|
public virtual ulong TargetObjectId => 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the target object of the game object.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This iterates the actor table, it should be used with care.
|
|
||||||
/// </remarks>
|
|
||||||
// TODO: Fix for non-networked GameObjects
|
// TODO: Fix for non-networked GameObjects
|
||||||
public virtual GameObject? TargetObject => Service<ObjectTable>.Get().SearchById(this.TargetObjectId);
|
public virtual IGameObject? TargetObject => Service<ObjectTable>.Get().SearchById(this.TargetObjectId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying structure.
|
/// Gets the underlying structure.
|
||||||
|
|
@ -192,3 +148,116 @@ public unsafe partial class GameObject
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override string ToString() => $"{this.GameObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}";
|
public override string ToString() => $"{this.GameObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a game object.
|
||||||
|
/// </summary>
|
||||||
|
public interface IGameObject : IEquatable<IGameObject>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public SeString Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the GameObjectID for this GameObject. The Game Object ID is a globally unique identifier that points to
|
||||||
|
/// this specific object. This ID is used to reference specific objects on the local client (e.g. for targeting).
|
||||||
|
///
|
||||||
|
/// Not to be confused with <see cref="EntityId"/>.
|
||||||
|
/// </summary>
|
||||||
|
public ulong GameObjectId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Entity ID for this GameObject. Entity IDs are assigned to networked GameObjects.
|
||||||
|
///
|
||||||
|
/// A value of <c>0xE000_0000</c> indicates that this entity is not networked and has specific interactivity rules.
|
||||||
|
/// </summary>
|
||||||
|
public uint EntityId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the data ID for linking to other respective game data.
|
||||||
|
/// </summary>
|
||||||
|
public uint DataId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of this GameObject's owner.
|
||||||
|
/// </summary>
|
||||||
|
public uint OwnerId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of this object in the object table.
|
||||||
|
/// </summary>
|
||||||
|
public ushort ObjectIndex { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the entity kind of this <see cref="GameObject" />.
|
||||||
|
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
||||||
|
/// </summary>
|
||||||
|
public ObjectKind ObjectKind { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sub kind of this Actor.
|
||||||
|
/// </summary>
|
||||||
|
public byte SubKind { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the X distance from the local player in yalms.
|
||||||
|
/// </summary>
|
||||||
|
public byte YalmDistanceX { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Y distance from the local player in yalms.
|
||||||
|
/// </summary>
|
||||||
|
public byte YalmDistanceZ { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the object is dead or alive.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsDead { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the object is targetable.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsTargetable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the rotation of this <see cref="GameObject" />.
|
||||||
|
/// This ranges from -pi to pi radians.
|
||||||
|
/// </summary>
|
||||||
|
public float Rotation { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hitbox radius of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public float HitboxRadius { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current target of the game object.
|
||||||
|
/// </summary>
|
||||||
|
public ulong TargetObjectId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the target object of the game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
// TODO: Fix for non-networked GameObjects
|
||||||
|
public IGameObject? TargetObject { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the game object in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this actor is still valid in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public bool IsValid();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager* GroupManagerStruct => (FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager*)this.GroupManagerAddress;
|
private FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager* GroupManagerStruct => (FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager*)this.GroupManagerAddress;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public PartyMember? this[int index]
|
public IPartyMember? this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -94,7 +94,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public PartyMember? CreatePartyMemberReference(IntPtr address)
|
public IPartyMember? CreatePartyMemberReference(IntPtr address)
|
||||||
{
|
{
|
||||||
if (this.clientState.LocalContentId == 0)
|
if (this.clientState.LocalContentId == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -115,7 +115,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public PartyMember? CreateAllianceMemberReference(IntPtr address)
|
public IPartyMember? CreateAllianceMemberReference(IntPtr address)
|
||||||
{
|
{
|
||||||
if (this.clientState.LocalContentId == 0)
|
if (this.clientState.LocalContentId == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -133,10 +133,10 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
||||||
internal sealed partial class PartyList
|
internal sealed partial class PartyList
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
int IReadOnlyCollection<PartyMember>.Count => this.Length;
|
int IReadOnlyCollection<IPartyMember>.Count => this.Length;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<PartyMember> GetEnumerator()
|
public IEnumerator<IPartyMember> GetEnumerator()
|
||||||
{
|
{
|
||||||
// Normally using Length results in a recursion crash, however we know the party size via ptr.
|
// Normally using Length results in a recursion crash, however we know the party size via ptr.
|
||||||
for (var i = 0; i < this.Length; i++)
|
for (var i = 0; i < this.Length; i++)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ namespace Dalamud.Game.ClientState.Party;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a party member in the group manager.
|
/// This class represents a party member in the group manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class PartyMember
|
public unsafe class PartyMember : IPartyMember
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
||||||
|
|
@ -55,7 +55,7 @@ public unsafe class PartyMember
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This iterates the actor table, it should be used with care.
|
/// This iterates the actor table, it should be used with care.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public GameObject? GameObject => Service<ObjectTable>.Get().SearchById(this.ObjectId);
|
public IGameObject? GameObject => Service<ObjectTable>.Get().SearchById(this.ObjectId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current HP of this party member.
|
/// Gets the current HP of this party member.
|
||||||
|
|
@ -109,3 +109,92 @@ public unsafe class PartyMember
|
||||||
|
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember*)this.Address;
|
private FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember*)this.Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a party member.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPartyMember
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of this party member in memory.
|
||||||
|
/// </summary>
|
||||||
|
IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of buffs or debuffs applied to this party member.
|
||||||
|
/// </summary>
|
||||||
|
StatusList Statuses { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of the party member.
|
||||||
|
/// </summary>
|
||||||
|
Vector3 Position { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the content ID of the party member.
|
||||||
|
/// </summary>
|
||||||
|
long ContentId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor ID of this party member.
|
||||||
|
/// </summary>
|
||||||
|
uint ObjectId { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor associated with this buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
IGameObject? GameObject { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current HP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
uint CurrentHP { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum HP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
uint MaxHP { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current MP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
ushort CurrentMP { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum MP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
ushort MaxMP { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the territory this party member is located in.
|
||||||
|
/// </summary>
|
||||||
|
ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> Territory { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the World this party member resides in.
|
||||||
|
/// </summary>
|
||||||
|
ExcelResolver<Lumina.Excel.GeneratedSheets.World> World { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the displayname of this party member.
|
||||||
|
/// </summary>
|
||||||
|
SeString Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sex of this party member.
|
||||||
|
/// </summary>
|
||||||
|
byte Sex { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the classjob of this party member.
|
||||||
|
/// </summary>
|
||||||
|
ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> ClassJob { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this party member.
|
||||||
|
/// </summary>
|
||||||
|
byte Level { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ public unsafe class Status
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This iterates the actor table, it should be used with care.
|
/// This iterates the actor table, it should be used with care.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public GameObject? SourceObject => Service<ObjectTable>.Get().SearchById(this.SourceId);
|
public IGameObject? SourceObject => Service<ObjectTable>.Get().SearchById(this.SourceId);
|
||||||
|
|
||||||
private FFXIVClientStructs.FFXIV.Client.Game.Status* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Status*)this.Address;
|
private FFXIVClientStructs.FFXIV.Client.Game.Status* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Status*)this.Address;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,42 +3,52 @@ namespace Dalamud.Game.Command;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class describes a registered command.
|
/// This class describes a registered command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class CommandInfo
|
internal sealed class CommandInfo : ICommandInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CommandInfo"/> class.
|
/// Initializes a new instance of the <see cref="CommandInfo"/> class.
|
||||||
/// Create a new CommandInfo with the provided handler.
|
/// Create a new CommandInfo with the provided handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="handler">The method to call when the command is run.</param>
|
/// <param name="handler">The method to call when the command is run.</param>
|
||||||
public CommandInfo(HandlerDelegate handler)
|
public CommandInfo(ICommandInfo.HandlerDelegate handler)
|
||||||
{
|
{
|
||||||
this.Handler = handler;
|
this.Handler = handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ICommandInfo.HandlerDelegate Handler { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string HelpMessage { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool ShowInHelp { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a registered command.
|
||||||
|
/// </summary>
|
||||||
|
public interface ICommandInfo
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The function to be executed when the command is dispatched.
|
/// The function to be executed when the command is dispatched.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="command">The command itself.</param>
|
/// <param name="command">The command itself.</param>
|
||||||
/// <param name="arguments">The arguments supplied to the command, ready for parsing.</param>
|
/// <param name="arguments">The arguments supplied to the command, ready for parsing.</param>
|
||||||
public delegate void HandlerDelegate(string command, string arguments);
|
public delegate void HandlerDelegate(string command, string arguments);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a <see cref="HandlerDelegate"/> which will be called when the command is dispatched.
|
/// Gets a <see cref="HandlerDelegate"/> which will be called when the command is dispatched.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public HandlerDelegate Handler { get; }
|
HandlerDelegate Handler { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the help message for this command.
|
/// Gets or sets the help message for this command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string HelpMessage { get; set; } = string.Empty;
|
string HelpMessage { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether if this command should be shown in the help output.
|
/// Gets or sets a value indicating whether if this command should be shown in the help output.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ShowInHelp { get; set; } = true;
|
bool ShowInHelp { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the assembly responsible for this command.
|
|
||||||
/// </summary>
|
|
||||||
internal string LoaderAssemblyName { get; set; } = string.Empty;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
using Dalamud.Console;
|
using Dalamud.Console;
|
||||||
|
|
@ -23,7 +24,8 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
|
||||||
{
|
{
|
||||||
private static readonly ModuleLog Log = new("Command");
|
private static readonly ModuleLog Log = new("Command");
|
||||||
|
|
||||||
private readonly ConcurrentDictionary<string, CommandInfo> commandMap = new();
|
private readonly ConcurrentDictionary<string, ICommandInfo> commandMap = new();
|
||||||
|
private readonly ConcurrentDictionary<(string, ICommandInfo), string> commandAssemblyNameMap = new();
|
||||||
private readonly Regex commandRegexEn = new(@"^The command (?<command>.+) does not exist\.$", RegexOptions.Compiled);
|
private readonly Regex commandRegexEn = new(@"^The command (?<command>.+) does not exist\.$", RegexOptions.Compiled);
|
||||||
private readonly Regex commandRegexJp = new(@"^そのコマンドはありません。: (?<command>.+)$", RegexOptions.Compiled);
|
private readonly Regex commandRegexJp = new(@"^そのコマンドはありません。: (?<command>.+)$", RegexOptions.Compiled);
|
||||||
private readonly Regex commandRegexDe = new(@"^„(?<command>.+)“ existiert nicht als Textkommando\.$", RegexOptions.Compiled);
|
private readonly Regex commandRegexDe = new(@"^„(?<command>.+)“ existiert nicht als Textkommando\.$", RegexOptions.Compiled);
|
||||||
|
|
@ -54,7 +56,7 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ReadOnlyDictionary<string, CommandInfo> Commands => new(this.commandMap);
|
public ReadOnlyDictionary<string, ICommandInfo> Commands => new(this.commandMap);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool ProcessCommand(string content)
|
public bool ProcessCommand(string content)
|
||||||
|
|
@ -100,7 +102,7 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void DispatchCommand(string command, string argument, CommandInfo info)
|
public void DispatchCommand(string command, string argument, ICommandInfo info)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -111,9 +113,31 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
|
||||||
Log.Error(ex, "Error while dispatching command {CommandName} (Argument: {Argument})", command, argument);
|
Log.Error(ex, "Error while dispatching command {CommandName} (Argument: {Argument})", command, argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool AddHandler(string command, ICommandInfo info, string loaderAssemblyName = "")
|
||||||
|
{
|
||||||
|
if (info == null)
|
||||||
|
throw new ArgumentNullException(nameof(info), "Command handler is null.");
|
||||||
|
|
||||||
|
if (!this.commandMap.TryAdd(command, info))
|
||||||
|
{
|
||||||
|
Log.Error("Command {CommandName} is already registered.", command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.commandAssemblyNameMap.TryAdd((command, info), loaderAssemblyName))
|
||||||
|
{
|
||||||
|
this.commandMap.Remove(command, out _);
|
||||||
|
Log.Error("Command {CommandName} is already registered in the assembly name map.", command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool AddHandler(string command, CommandInfo info)
|
public bool AddHandler(string command, ICommandInfo info)
|
||||||
{
|
{
|
||||||
if (info == null)
|
if (info == null)
|
||||||
throw new ArgumentNullException(nameof(info), "Command handler is null.");
|
throw new ArgumentNullException(nameof(info), "Command handler is null.");
|
||||||
|
|
@ -133,6 +157,32 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
|
||||||
return this.commandMap.Remove(command, out _);
|
return this.commandMap.Remove(command, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the assembly name from which the command was added or blank if added internally.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">The command.</param>
|
||||||
|
/// <param name="commandInfo">A ICommandInfo object.</param>
|
||||||
|
/// <returns>The name of the assembly.</returns>
|
||||||
|
public string GetHandlerAssemblyName(string command, ICommandInfo commandInfo)
|
||||||
|
{
|
||||||
|
if (this.commandAssemblyNameMap.TryGetValue((command, commandInfo), out var assemblyName))
|
||||||
|
{
|
||||||
|
return assemblyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of commands given a specified assembly name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="assemblyName">The name of the assembly.</param>
|
||||||
|
/// <returns>A list of commands and their associated activation string.</returns>
|
||||||
|
public List<KeyValuePair<(string, ICommandInfo), string>> GetHandlersByAssemblyName(string assemblyName)
|
||||||
|
{
|
||||||
|
return this.commandAssemblyNameMap.Where(c => c.Value == assemblyName).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
{
|
{
|
||||||
|
|
@ -199,7 +249,7 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ReadOnlyDictionary<string, CommandInfo> Commands => this.commandManagerService.Commands;
|
public ReadOnlyDictionary<string, ICommandInfo> Commands => this.commandManagerService.Commands;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
|
|
@ -217,16 +267,15 @@ internal class CommandManagerPluginScoped : IInternalDisposableService, ICommand
|
||||||
=> this.commandManagerService.ProcessCommand(content);
|
=> this.commandManagerService.ProcessCommand(content);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void DispatchCommand(string command, string argument, CommandInfo info)
|
public void DispatchCommand(string command, string argument, ICommandInfo info)
|
||||||
=> this.commandManagerService.DispatchCommand(command, argument, info);
|
=> this.commandManagerService.DispatchCommand(command, argument, info);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool AddHandler(string command, CommandInfo info)
|
public bool AddHandler(string command, ICommandInfo info)
|
||||||
{
|
{
|
||||||
if (!this.pluginRegisteredCommands.Contains(command))
|
if (!this.pluginRegisteredCommands.Contains(command))
|
||||||
{
|
{
|
||||||
info.LoaderAssemblyName = this.pluginInfo.InternalName;
|
if (this.commandManagerService.AddHandler(command, info, this.pluginInfo.InternalName))
|
||||||
if (this.commandManagerService.AddHandler(command, info))
|
|
||||||
{
|
{
|
||||||
this.pluginRegisteredCommands.Add(command);
|
this.pluginRegisteredCommands.Add(command);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IContextMenu.OnMenuOpenedDelegate? OnMenuOpened;
|
public event IContextMenu.OnMenuOpenedDelegate? OnMenuOpened;
|
||||||
|
|
||||||
private Dictionary<ContextMenuType, List<MenuItem>> MenuItems { get; } = new();
|
private Dictionary<ContextMenuType, List<IMenuItem>> MenuItems { get; } = new();
|
||||||
|
|
||||||
private object MenuItemsLock { get; } = new();
|
private object MenuItemsLock { get; } = new();
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
|
|
||||||
private ContextMenuType? SelectedMenuType { get; set; }
|
private ContextMenuType? SelectedMenuType { get; set; }
|
||||||
|
|
||||||
private List<MenuItem>? SelectedItems { get; set; }
|
private List<IMenuItem>? SelectedItems { get; set; }
|
||||||
|
|
||||||
private HashSet<nint> SelectedEventInterfaces { get; } = new();
|
private HashSet<nint> SelectedEventInterfaces { get; } = new();
|
||||||
|
|
||||||
|
|
@ -72,7 +72,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
// 0 -> inf: selected items
|
// 0 -> inf: selected items
|
||||||
private List<int> MenuCallbackIds { get; } = new();
|
private List<int> MenuCallbackIds { get; } = new();
|
||||||
|
|
||||||
private IReadOnlyList<MenuItem>? SubmenuItems { get; set; }
|
private IReadOnlyList<IMenuItem>? SubmenuItems { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
|
|
@ -90,7 +90,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void AddMenuItem(ContextMenuType menuType, MenuItem item)
|
public void AddMenuItem(ContextMenuType menuType, IMenuItem item)
|
||||||
{
|
{
|
||||||
lock (this.MenuItemsLock)
|
lock (this.MenuItemsLock)
|
||||||
{
|
{
|
||||||
|
|
@ -101,7 +101,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool RemoveMenuItem(ContextMenuType menuType, MenuItem item)
|
public bool RemoveMenuItem(ContextMenuType menuType, IMenuItem item)
|
||||||
{
|
{
|
||||||
lock (this.MenuItemsLock)
|
lock (this.MenuItemsLock)
|
||||||
{
|
{
|
||||||
|
|
@ -167,7 +167,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupGenericMenu(int headerCount, int sizeHeaderIdx, int returnHeaderIdx, int submenuHeaderIdx, IReadOnlyList<MenuItem> items, ref int valueCount, ref AtkValue* values)
|
private void SetupGenericMenu(int headerCount, int sizeHeaderIdx, int returnHeaderIdx, int submenuHeaderIdx, IReadOnlyList<IMenuItem> items, ref int valueCount, ref AtkValue* values)
|
||||||
{
|
{
|
||||||
var itemsWithIdx = items.Select((item, idx) => (item, idx)).OrderBy(i => i.item.Priority).ToArray();
|
var itemsWithIdx = items.Select((item, idx) => (item, idx)).OrderBy(i => i.item.Priority).ToArray();
|
||||||
var prefixItems = itemsWithIdx.Where(i => i.item.Priority < 0).ToArray();
|
var prefixItems = itemsWithIdx.Where(i => i.item.Priority < 0).ToArray();
|
||||||
|
|
@ -215,7 +215,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
returnMask <<= prefixMenuSize;
|
returnMask <<= prefixMenuSize;
|
||||||
submenuMask <<= prefixMenuSize;
|
submenuMask <<= prefixMenuSize;
|
||||||
|
|
||||||
void FillData(Span<AtkValue> disabledData, Span<AtkValue> nameData, int i, MenuItem item, int idx)
|
void FillData(Span<AtkValue> disabledData, Span<AtkValue> nameData, int i, IMenuItem item, int idx)
|
||||||
{
|
{
|
||||||
this.MenuCallbackIds.Add(idx);
|
this.MenuCallbackIds.Add(idx);
|
||||||
|
|
||||||
|
|
@ -231,7 +231,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
submenuMask |= 1u << i;
|
submenuMask |= 1u << i;
|
||||||
|
|
||||||
nameData[i].ChangeType(ValueType.String);
|
nameData[i].ChangeType(ValueType.String);
|
||||||
nameData[i].SetManagedString(item.PrefixedName.Encode().NullTerminate());
|
nameData[i].SetManagedString(this.GetPrefixedName(item).Encode().NullTerminate());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < prefixMenuSize; ++i)
|
for (var i = 0; i < prefixMenuSize; ++i)
|
||||||
|
|
@ -253,8 +253,19 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
|
|
||||||
offsetData[sizeHeaderIdx].UInt += (uint)items.Count;
|
offsetData[sizeHeaderIdx].UInt += (uint)items.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name with the given prefix.
|
||||||
|
/// </summary>
|
||||||
|
internal SeString GetPrefixedName(IMenuItem menuItem) =>
|
||||||
|
menuItem.Prefix is { } prefix
|
||||||
|
? new SeStringBuilder()
|
||||||
|
.AddUiForeground($"{prefix.ToIconString()} ", menuItem.PrefixColor)
|
||||||
|
.Append(menuItem.Name)
|
||||||
|
.Build()
|
||||||
|
: menuItem.Name;
|
||||||
|
|
||||||
private void SetupContextMenu(IReadOnlyList<MenuItem> items, ref int valueCount, ref AtkValue* values)
|
private void SetupContextMenu(IReadOnlyList<IMenuItem> items, ref int valueCount, ref AtkValue* values)
|
||||||
{
|
{
|
||||||
// 0: UInt = Item Count
|
// 0: UInt = Item Count
|
||||||
// 1: UInt = 0 (probably window name, just unused)
|
// 1: UInt = 0 (probably window name, just unused)
|
||||||
|
|
@ -268,8 +279,8 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
{
|
{
|
||||||
if (!item.Prefix.HasValue)
|
if (!item.Prefix.HasValue)
|
||||||
{
|
{
|
||||||
item.Prefix = MenuItem.DalamudDefaultPrefix;
|
item.Prefix = IMenuItem.DalamudDefaultPrefix;
|
||||||
item.PrefixColor = MenuItem.DalamudDefaultPrefixColor;
|
item.PrefixColor = IMenuItem.DalamudDefaultPrefixColor;
|
||||||
|
|
||||||
if (!item.UseDefaultPrefix)
|
if (!item.UseDefaultPrefix)
|
||||||
{
|
{
|
||||||
|
|
@ -281,7 +292,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
this.SetupGenericMenu(7, 0, 2, 3, items, ref valueCount, ref values);
|
this.SetupGenericMenu(7, 0, 2, 3, items, ref valueCount, ref values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetupContextSubMenu(IReadOnlyList<MenuItem> items, ref int valueCount, ref AtkValue* values)
|
private void SetupContextSubMenu(IReadOnlyList<IMenuItem> items, ref int valueCount, ref AtkValue* values)
|
||||||
{
|
{
|
||||||
// 0: UInt = ContextItemCount
|
// 0: UInt = ContextItemCount
|
||||||
// 1: skipped?
|
// 1: skipped?
|
||||||
|
|
@ -376,7 +387,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MenuItem> FixupMenuList(List<MenuItem> items, int nativeMenuSize)
|
private List<IMenuItem> FixupMenuList(List<IMenuItem> items, int nativeMenuSize)
|
||||||
{
|
{
|
||||||
// The in game menu actually supports 32 items, but the last item can't have a visible submenu arrow.
|
// The in game menu actually supports 32 items, but the last item can't have a visible submenu arrow.
|
||||||
// As such, we'll only work with 31 items.
|
// As such, we'll only work with 31 items.
|
||||||
|
|
@ -401,7 +412,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenSubmenu(SeString name, IReadOnlyList<MenuItem> submenuItems, int posX, int posY)
|
private void OpenSubmenu(SeString name, IReadOnlyList<IMenuItem> submenuItems, int posX, int posY)
|
||||||
{
|
{
|
||||||
if (submenuItems.Count == 0)
|
if (submenuItems.Count == 0)
|
||||||
throw new ArgumentException("Submenu must not be empty", nameof(submenuItems));
|
throw new ArgumentException("Submenu must not be empty", nameof(submenuItems));
|
||||||
|
|
@ -513,7 +524,7 @@ internal class ContextMenuPluginScoped : IInternalDisposableService, IContextMen
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public event IContextMenu.OnMenuOpenedDelegate? OnMenuOpened;
|
public event IContextMenu.OnMenuOpenedDelegate? OnMenuOpened;
|
||||||
|
|
||||||
private Dictionary<ContextMenuType, List<MenuItem>> MenuItems { get; } = new();
|
private Dictionary<ContextMenuType, List<IMenuItem>> MenuItems { get; } = new();
|
||||||
|
|
||||||
private object MenuItemsLock { get; } = new();
|
private object MenuItemsLock { get; } = new();
|
||||||
|
|
||||||
|
|
@ -535,7 +546,7 @@ internal class ContextMenuPluginScoped : IInternalDisposableService, IContextMen
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void AddMenuItem(ContextMenuType menuType, MenuItem item)
|
public void AddMenuItem(ContextMenuType menuType, IMenuItem item)
|
||||||
{
|
{
|
||||||
lock (this.MenuItemsLock)
|
lock (this.MenuItemsLock)
|
||||||
{
|
{
|
||||||
|
|
@ -548,7 +559,7 @@ internal class ContextMenuPluginScoped : IInternalDisposableService, IContextMen
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool RemoveMenuItem(ContextMenuType menuType, MenuItem item)
|
public bool RemoveMenuItem(ContextMenuType menuType, IMenuItem item)
|
||||||
{
|
{
|
||||||
lock (this.MenuItemsLock)
|
lock (this.MenuItemsLock)
|
||||||
{
|
{
|
||||||
|
|
@ -559,6 +570,6 @@ internal class ContextMenuPluginScoped : IInternalDisposableService, IContextMen
|
||||||
return this.parentService.RemoveMenuItem(menuType, item);
|
return this.parentService.RemoveMenuItem(menuType, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMenuOpenedForward(MenuOpenedArgs args) =>
|
private void OnMenuOpenedForward(IMenuOpenedArgs args) =>
|
||||||
this.OnMenuOpened?.Invoke(args);
|
this.OnMenuOpened?.Invoke(args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class for <see cref="IContextMenu"/> menu args.
|
/// Base class for <see cref="IContextMenu"/> menu args.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract unsafe class MenuArgs
|
internal abstract unsafe class MenuArgs : IMenuArgs
|
||||||
{
|
{
|
||||||
private IReadOnlySet<nint>? eventInterfaces;
|
private IReadOnlySet<nint>? eventInterfaces;
|
||||||
|
|
||||||
|
|
@ -37,6 +37,51 @@ public abstract unsafe class MenuArgs
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string? AddonName { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public nint AddonPtr { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public nint AgentPtr { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ContextMenuType MenuType { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public MenuTarget Target { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IReadOnlySet<nint> EventInterfaces
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.MenuType is ContextMenuType.Default)
|
||||||
|
{
|
||||||
|
return this.eventInterfaces ?? new HashSet<nint>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Not a default context menu");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a context menus args.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMenuArgs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of AtkEventInterface pointers associated with the context menu.
|
||||||
|
/// Only available with <see cref="ContextMenuType.Default"/>.
|
||||||
|
/// Almost always an agent pointer. You can use this to find out what type of context menu it is.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown when the context menu is not a <see cref="ContextMenuType.Default"/>.</exception>
|
||||||
|
public IReadOnlySet<nint> EventInterfaces { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the addon that opened the context menu.
|
/// Gets the name of the addon that opened the context menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -63,25 +108,4 @@ public abstract unsafe class MenuArgs
|
||||||
/// <see cref="ContextMenuType.Inventory"/> signifies a <see cref="MenuTargetInventory"/>.
|
/// <see cref="ContextMenuType.Inventory"/> signifies a <see cref="MenuTargetInventory"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public MenuTarget Target { get; }
|
public MenuTarget Target { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a list of AtkEventInterface pointers associated with the context menu.
|
|
||||||
/// Only available with <see cref="ContextMenuType.Default"/>.
|
|
||||||
/// Almost always an agent pointer. You can use this to find out what type of context menu it is.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="InvalidOperationException">Thrown when the context menu is not a <see cref="ContextMenuType.Default"/>.</exception>
|
|
||||||
public IReadOnlySet<nint> EventInterfaces
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (this.MenuType is ContextMenuType.Default)
|
|
||||||
{
|
|
||||||
return this.eventInterfaces ?? new HashSet<nint>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException("Not a default context menu");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,32 +8,15 @@ namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A menu item that can be added to a context menu.
|
/// A menu item that can be added to a context menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed record MenuItem
|
public sealed record MenuItem : IMenuItem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// The default prefix used if no specific preset is specified.
|
|
||||||
/// </summary>
|
|
||||||
public const SeIconChar DalamudDefaultPrefix = SeIconChar.BoxedLetterD;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The default prefix color used if no specific preset is specified.
|
|
||||||
/// </summary>
|
|
||||||
public const ushort DalamudDefaultPrefixColor = 539;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the display name of the menu item.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Name { get; set; } = SeString.Empty;
|
public SeString Name { get; set; } = SeString.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets or sets the prefix attached to the beginning of <see cref="Name"/>.
|
|
||||||
/// </summary>
|
|
||||||
public SeIconChar? Prefix { get; set; }
|
public SeIconChar? Prefix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Sets the character to prefix the <see cref="Name"/> with. Will be converted into a fancy boxed letter icon. Must be an uppercase letter.
|
|
||||||
/// </summary>
|
|
||||||
/// <exception cref="ArgumentException"><paramref name="value"/> must be an uppercase letter.</exception>
|
|
||||||
public char? PrefixChar
|
public char? PrefixChar
|
||||||
{
|
{
|
||||||
set
|
set
|
||||||
|
|
@ -52,55 +35,97 @@ public sealed record MenuItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ushort PrefixColor { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool UseDefaultPrefix { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public Action<IMenuItemClickedArgs>? OnClicked { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int Priority { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsEnabled { get; set; } = true;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsSubmenu { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsReturn { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Interface representing a menu item to be added to a context menu.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMenuItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The default prefix used if no specific preset is specified.
|
||||||
|
/// </summary>
|
||||||
|
public const SeIconChar DalamudDefaultPrefix = SeIconChar.BoxedLetterD;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The default prefix color used if no specific preset is specified.
|
||||||
|
/// </summary>
|
||||||
|
public const ushort DalamudDefaultPrefixColor = 539;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the display name of the menu item.
|
||||||
|
/// </summary>
|
||||||
|
SeString Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the prefix attached to the beginning of <see cref="Name"/>.
|
||||||
|
/// </summary>
|
||||||
|
SeIconChar? Prefix { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the character to prefix the <see cref="Name"/> with. Will be converted into a fancy boxed letter icon. Must be an uppercase letter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="ArgumentException"><paramref name="value"/> must be an uppercase letter.</exception>
|
||||||
|
char? PrefixChar { set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the color of the <see cref="Prefix"/>. Specifies a <see cref="UIColor"/> row id.
|
/// Gets or sets the color of the <see cref="Prefix"/>. Specifies a <see cref="UIColor"/> row id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ushort PrefixColor { get; set; }
|
ushort PrefixColor { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the dev wishes to intentionally use the default prefix symbol and color.
|
/// Gets or sets a value indicating whether the dev wishes to intentionally use the default prefix symbol and color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool UseDefaultPrefix { get; set; }
|
bool UseDefaultPrefix { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the callback to be invoked when the menu item is clicked.
|
/// Gets or sets the callback to be invoked when the menu item is clicked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Action<MenuItemClickedArgs>? OnClicked { get; set; }
|
Action<IMenuItemClickedArgs>? OnClicked { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the priority (or order) with which the menu item should be displayed in descending order.
|
/// Gets or sets the priority (or order) with which the menu item should be displayed in descending order.
|
||||||
/// Priorities below 0 will be displayed above the native menu items.
|
/// Priorities below 0 will be displayed above the native menu items.
|
||||||
/// Other priorities will be displayed below the native menu items.
|
/// Other priorities will be displayed below the native menu items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Priority { get; set; }
|
int Priority { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the menu item is enabled.
|
/// Gets or sets a value indicating whether the menu item is enabled.
|
||||||
/// Disabled items will be faded and cannot be clicked on.
|
/// Disabled items will be faded and cannot be clicked on.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsEnabled { get; set; } = true;
|
bool IsEnabled { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the menu item is a submenu.
|
/// Gets or sets a value indicating whether the menu item is a submenu.
|
||||||
/// This value is purely visual. Submenu items will have an arrow to its right.
|
/// This value is purely visual. Submenu items will have an arrow to its right.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsSubmenu { get; set; }
|
bool IsSubmenu { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the menu item is a return item.
|
/// Gets or sets a value indicating whether the menu item is a return item.
|
||||||
/// This value is purely visual. Return items will have a back arrow to its left.
|
/// This value is purely visual. Return items will have a back arrow to its left.
|
||||||
/// If both <see cref="IsSubmenu"/> and <see cref="IsReturn"/> are true, the return arrow will take precedence.
|
/// If both <see cref="IsSubmenu"/> and <see cref="IsReturn"/> are true, the return arrow will take precedence.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsReturn { get; set; }
|
bool IsReturn { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the name with the given prefix.
|
|
||||||
/// </summary>
|
|
||||||
internal SeString PrefixedName =>
|
|
||||||
this.Prefix is { } prefix
|
|
||||||
? new SeStringBuilder()
|
|
||||||
.AddUiForeground($"{prefix.ToIconString()} ", this.PrefixColor)
|
|
||||||
.Append(this.Name)
|
|
||||||
.Build()
|
|
||||||
: this.Name;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback args used when a menu item is clicked.
|
/// Callback args used when a menu item is clicked.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed unsafe class MenuItemClickedArgs : MenuArgs
|
internal sealed unsafe class MenuItemClickedArgs : MenuArgs, IMenuItemClickedArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MenuItemClickedArgs"/> class.
|
/// Initializes a new instance of the <see cref="MenuItemClickedArgs"/> class.
|
||||||
|
|
@ -20,26 +20,73 @@ public sealed unsafe class MenuItemClickedArgs : MenuArgs
|
||||||
/// <param name="agent">Agent associated with the context menu.</param>
|
/// <param name="agent">Agent associated with the context menu.</param>
|
||||||
/// <param name="type">The type of context menu.</param>
|
/// <param name="type">The type of context menu.</param>
|
||||||
/// <param name="eventInterfaces">List of AtkEventInterfaces associated with the context menu.</param>
|
/// <param name="eventInterfaces">List of AtkEventInterfaces associated with the context menu.</param>
|
||||||
internal MenuItemClickedArgs(Action<SeString?, IReadOnlyList<MenuItem>> openSubmenu, AtkUnitBase* addon, AgentInterface* agent, ContextMenuType type, IReadOnlySet<nint> eventInterfaces)
|
internal MenuItemClickedArgs(Action<SeString?, IReadOnlyList<IMenuItem>> openSubmenu, AtkUnitBase* addon, AgentInterface* agent, ContextMenuType type, IReadOnlySet<nint> eventInterfaces)
|
||||||
: base(addon, agent, type, eventInterfaces)
|
: base(addon, agent, type, eventInterfaces)
|
||||||
{
|
{
|
||||||
this.OnOpenSubmenu = openSubmenu;
|
this.OnOpenSubmenu = openSubmenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action<SeString?, IReadOnlyList<MenuItem>> OnOpenSubmenu { get; }
|
private Action<SeString?, IReadOnlyList<IMenuItem>> OnOpenSubmenu { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OpenSubmenu(SeString name, IReadOnlyList<IMenuItem> items) =>
|
||||||
|
this.OnOpenSubmenu(name, items);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OpenSubmenu(IReadOnlyList<IMenuItem> items) =>
|
||||||
|
this.OnOpenSubmenu(null, items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An interface representing the callback args used when a menu item is clicked.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMenuItemClickedArgs
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens a submenu with the given name and items.
|
/// Opens a submenu with the given name and items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the submenu, displayed at the top.</param>
|
/// <param name="name">The name of the submenu, displayed at the top.</param>
|
||||||
/// <param name="items">The items to display in the submenu.</param>
|
/// <param name="items">The items to display in the submenu.</param>
|
||||||
public void OpenSubmenu(SeString name, IReadOnlyList<MenuItem> items) =>
|
void OpenSubmenu(SeString name, IReadOnlyList<IMenuItem> items);
|
||||||
this.OnOpenSubmenu(name, items);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens a submenu with the given items.
|
/// Opens a submenu with the given items.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="items">The items to display in the submenu.</param>
|
/// <param name="items">The items to display in the submenu.</param>
|
||||||
public void OpenSubmenu(IReadOnlyList<MenuItem> items) =>
|
void OpenSubmenu(IReadOnlyList<IMenuItem> items);
|
||||||
this.OnOpenSubmenu(null, items);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of AtkEventInterface pointers associated with the context menu.
|
||||||
|
/// Only available with <see cref="ContextMenuType.Default"/>.
|
||||||
|
/// Almost always an agent pointer. You can use this to find out what type of context menu it is.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown when the context menu is not a <see cref="ContextMenuType.Default"/>.</exception>
|
||||||
|
IReadOnlySet<nint> EventInterfaces { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the addon that opened the context menu.
|
||||||
|
/// </summary>
|
||||||
|
string? AddonName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the memory pointer of the addon that opened the context menu.
|
||||||
|
/// </summary>
|
||||||
|
nint AddonPtr { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the memory pointer of the agent that opened the context menu.
|
||||||
|
/// </summary>
|
||||||
|
nint AgentPtr { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of the context menu.
|
||||||
|
/// </summary>
|
||||||
|
ContextMenuType MenuType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the target info of the context menu. The actual type depends on <see cref="MenuType"/>.
|
||||||
|
/// <see cref="ContextMenuType.Default"/> signifies a <see cref="MenuTargetDefault"/>.
|
||||||
|
/// <see cref="ContextMenuType.Inventory"/> signifies a <see cref="MenuTargetInventory"/>.
|
||||||
|
/// </summary>
|
||||||
|
MenuTarget Target { get; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace Dalamud.Game.Gui.ContextMenu;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Callback args used when a menu item is opened.
|
/// Callback args used when a menu item is opened.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed unsafe class MenuOpenedArgs : MenuArgs
|
internal sealed unsafe class MenuOpenedArgs : MenuArgs, IMenuOpenedArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MenuOpenedArgs"/> class.
|
/// Initializes a new instance of the <see cref="MenuOpenedArgs"/> class.
|
||||||
|
|
@ -26,10 +26,19 @@ public sealed unsafe class MenuOpenedArgs : MenuArgs
|
||||||
|
|
||||||
private Action<MenuItem> OnAddMenuItem { get; }
|
private Action<MenuItem> OnAddMenuItem { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void AddMenuItem(MenuItem item) =>
|
||||||
|
this.OnAddMenuItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An interface representing the callback args used when a menu item is opened.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMenuOpenedArgs : IMenuArgs
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a custom menu item to the context menu.
|
/// Adds a custom menu item to the context menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="item">The menu item to add.</param>
|
/// <param name="item">The menu item to add.</param>
|
||||||
public void AddMenuItem(MenuItem item) =>
|
void AddMenuItem(MenuItem item);
|
||||||
this.OnAddMenuItem(item);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ public sealed unsafe class MenuTargetDefault : MenuTarget
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target object.
|
/// Gets the target object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? TargetObject => Service<ObjectTable>.Get().SearchById(this.TargetObjectId);
|
public IGameObject? TargetObject => Service<ObjectTable>.Get().SearchById(this.TargetObjectId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content id of the target.
|
/// Gets the content id of the target.
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
|
||||||
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.entries;
|
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.entries;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DtrBarEntry Get(string title, SeString? text = null)
|
public IDtrBarEntry Get(string title, SeString? text = null)
|
||||||
{
|
{
|
||||||
if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title))
|
if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title))
|
||||||
throw new ArgumentException("An entry with the same title already exists.");
|
throw new ArgumentException("An entry with the same title already exists.");
|
||||||
|
|
@ -501,7 +501,7 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly DtrBar dtrBarService = Service<DtrBar>.Get();
|
private readonly DtrBar dtrBarService = Service<DtrBar>.Get();
|
||||||
|
|
||||||
private readonly Dictionary<string, DtrBarEntry> pluginEntries = new();
|
private readonly Dictionary<string, IDtrBarEntry> pluginEntries = new();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.dtrBarService.Entries;
|
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.dtrBarService.Entries;
|
||||||
|
|
@ -518,7 +518,7 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public DtrBarEntry Get(string title, SeString? text = null)
|
public IDtrBarEntry Get(string title, SeString? text = null)
|
||||||
{
|
{
|
||||||
// If we already have a known entry for this plugin, return it.
|
// If we already have a known entry for this plugin, return it.
|
||||||
if (this.pluginEntries.TryGetValue(title, out var existingEntry)) return existingEntry;
|
if (this.pluginEntries.TryGetValue(title, out var existingEntry)) return existingEntry;
|
||||||
|
|
|
||||||
|
|
@ -154,5 +154,5 @@ internal class PartyFinderGuiPluginScoped : IInternalDisposableService, IPartyFi
|
||||||
this.ReceiveListing = null;
|
this.ReceiveListing = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReceiveListingForward(PartyFinderListing listing, PartyFinderListingEventArgs args) => this.ReceiveListing?.Invoke(listing, args);
|
private void ReceiveListingForward(IPartyFinderListing listing, IPartyFinderListingEventArgs args) => this.ReceiveListing?.Invoke(listing, args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Dalamud.Game.Gui.PartyFinder.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A single listing in party finder.
|
/// A single listing in party finder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PartyFinderListing
|
internal class PartyFinderListing : IPartyFinderListing
|
||||||
{
|
{
|
||||||
private readonly byte objective;
|
private readonly byte objective;
|
||||||
private readonly byte conditions;
|
private readonly byte conditions;
|
||||||
|
|
@ -63,171 +63,267 @@ public class PartyFinderListing
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the ID assigned to this listing by the game's server.
|
|
||||||
/// </summary>
|
|
||||||
public uint Id { get; }
|
public uint Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the lower bits of the player's content ID.
|
|
||||||
/// </summary>
|
|
||||||
public uint ContentIdLower { get; }
|
public uint ContentIdLower { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the name of the player hosting this listing.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Name { get; }
|
public SeString Name { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the description of this listing as set by the host. May be multiple lines.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Description { get; }
|
public SeString Description { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the world that this listing was created on.
|
|
||||||
/// </summary>
|
|
||||||
public Lazy<World> World { get; }
|
public Lazy<World> World { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the home world of the listing's host.
|
|
||||||
/// </summary>
|
|
||||||
public Lazy<World> HomeWorld { get; }
|
public Lazy<World> HomeWorld { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the current world of the listing's host.
|
|
||||||
/// </summary>
|
|
||||||
public Lazy<World> CurrentWorld { get; }
|
public Lazy<World> CurrentWorld { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Party Finder category this listing is listed under.
|
|
||||||
/// </summary>
|
|
||||||
public DutyCategory Category { get; }
|
public DutyCategory Category { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the row ID of the duty this listing is for. May be 0 for non-duty listings.
|
|
||||||
/// </summary>
|
|
||||||
public ushort RawDuty { get; }
|
public ushort RawDuty { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the duty this listing is for. May be null for non-duty listings.
|
|
||||||
/// </summary>
|
|
||||||
public Lazy<ContentFinderCondition> Duty { get; }
|
public Lazy<ContentFinderCondition> Duty { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the type of duty this listing is for.
|
|
||||||
/// </summary>
|
|
||||||
public DutyType DutyType { get; }
|
public DutyType DutyType { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a value indicating whether if this listing is beginner-friendly. Shown with a sprout icon in-game.
|
|
||||||
/// </summary>
|
|
||||||
public bool BeginnersWelcome { get; }
|
public bool BeginnersWelcome { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets how many seconds this listing will continue to be available for. It may end before this time if the party
|
|
||||||
/// fills or the host ends it early.
|
|
||||||
/// </summary>
|
|
||||||
public ushort SecondsRemaining { get; }
|
public ushort SecondsRemaining { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the minimum item level required to join this listing.
|
|
||||||
/// </summary>
|
|
||||||
public ushort MinimumItemLevel { get; }
|
public ushort MinimumItemLevel { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the number of parties this listing is recruiting for.
|
|
||||||
/// </summary>
|
|
||||||
public byte Parties { get; }
|
public byte Parties { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the number of player slots this listing is recruiting for.
|
|
||||||
/// </summary>
|
|
||||||
public byte SlotsAvailable { get; }
|
public byte SlotsAvailable { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the time at which the server this listings is on last restarted for a patch/hotfix.
|
|
||||||
/// Probably.
|
|
||||||
/// </summary>
|
|
||||||
public uint LastPatchHotfixTimestamp { get; }
|
public uint LastPatchHotfixTimestamp { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a list of player slots that the Party Finder is accepting.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyCollection<PartyFinderSlot> Slots => this.slots;
|
public IReadOnlyCollection<PartyFinderSlot> Slots => this.slots;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the objective of this listing.
|
|
||||||
/// </summary>
|
|
||||||
public ObjectiveFlags Objective => (ObjectiveFlags)this.objective;
|
public ObjectiveFlags Objective => (ObjectiveFlags)this.objective;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the conditions of this listing.
|
|
||||||
/// </summary>
|
|
||||||
public ConditionFlags Conditions => (ConditionFlags)this.conditions;
|
public ConditionFlags Conditions => (ConditionFlags)this.conditions;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the Duty Finder settings that will be used for this listing.
|
|
||||||
/// </summary>
|
|
||||||
public DutyFinderSettingsFlags DutyFinderSettings => (DutyFinderSettingsFlags)this.dutyFinderSettings;
|
public DutyFinderSettingsFlags DutyFinderSettings => (DutyFinderSettingsFlags)this.dutyFinderSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the loot rules that will be used for this listing.
|
|
||||||
/// </summary>
|
|
||||||
public LootRuleFlags LootRules => (LootRuleFlags)this.lootRules;
|
public LootRuleFlags LootRules => (LootRuleFlags)this.lootRules;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets where this listing is searching. Note that this is also used for denoting alliance raid listings and one
|
|
||||||
/// player per job.
|
|
||||||
/// </summary>
|
|
||||||
public SearchAreaFlags SearchArea => (SearchAreaFlags)this.searchArea;
|
public SearchAreaFlags SearchArea => (SearchAreaFlags)this.searchArea;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a list of the class/job IDs that are currently present in the party.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyCollection<byte> RawJobsPresent => this.jobsPresent;
|
public IReadOnlyCollection<byte> RawJobsPresent => this.jobsPresent;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets a list of the classes/jobs that are currently present in the party.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyCollection<Lazy<ClassJob>> JobsPresent { get; }
|
public IReadOnlyCollection<Lazy<ClassJob>> JobsPresent { get; }
|
||||||
|
|
||||||
#region Indexers
|
#region Indexers
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Check if the given flag is present.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">The flag to check for.</param>
|
|
||||||
/// <returns>A value indicating whether the flag is present.</returns>
|
|
||||||
public bool this[ObjectiveFlags flag] => this.objective == 0 || (this.objective & (uint)flag) > 0;
|
public bool this[ObjectiveFlags flag] => this.objective == 0 || (this.objective & (uint)flag) > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Check if the given flag is present.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">The flag to check for.</param>
|
|
||||||
/// <returns>A value indicating whether the flag is present.</returns>
|
|
||||||
public bool this[ConditionFlags flag] => this.conditions == 0 || (this.conditions & (uint)flag) > 0;
|
public bool this[ConditionFlags flag] => this.conditions == 0 || (this.conditions & (uint)flag) > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Check if the given flag is present.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">The flag to check for.</param>
|
|
||||||
/// <returns>A value indicating whether the flag is present.</returns>
|
|
||||||
public bool this[DutyFinderSettingsFlags flag] => this.dutyFinderSettings == 0 || (this.dutyFinderSettings & (uint)flag) > 0;
|
public bool this[DutyFinderSettingsFlags flag] => this.dutyFinderSettings == 0 || (this.dutyFinderSettings & (uint)flag) > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Check if the given flag is present.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">The flag to check for.</param>
|
|
||||||
/// <returns>A value indicating whether the flag is present.</returns>
|
|
||||||
public bool this[LootRuleFlags flag] => this.lootRules == 0 || (this.lootRules & (uint)flag) > 0;
|
public bool this[LootRuleFlags flag] => this.lootRules == 0 || (this.lootRules & (uint)flag) > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Check if the given flag is present.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="flag">The flag to check for.</param>
|
|
||||||
/// <returns>A value indicating whether the flag is present.</returns>
|
|
||||||
public bool this[SearchAreaFlags flag] => this.searchArea == 0 || (this.searchArea & (uint)flag) > 0;
|
public bool this[SearchAreaFlags flag] => this.searchArea == 0 || (this.searchArea & (uint)flag) > 0;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A interface representing a single listing in party finder.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPartyFinderListing
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the objective of this listing.
|
||||||
|
/// </summary>
|
||||||
|
ObjectiveFlags Objective { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the conditions of this listing.
|
||||||
|
/// </summary>
|
||||||
|
ConditionFlags Conditions { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Duty Finder settings that will be used for this listing.
|
||||||
|
/// </summary>
|
||||||
|
DutyFinderSettingsFlags DutyFinderSettings { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the loot rules that will be used for this listing.
|
||||||
|
/// </summary>
|
||||||
|
LootRuleFlags LootRules { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets where this listing is searching. Note that this is also used for denoting alliance raid listings and one
|
||||||
|
/// player per job.
|
||||||
|
/// </summary>
|
||||||
|
SearchAreaFlags SearchArea { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of player slots that the Party Finder is accepting.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<PartyFinderSlot> Slots { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of the classes/jobs that are currently present in the party.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<Lazy<ClassJob>> JobsPresent { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID assigned to this listing by the game's server.
|
||||||
|
/// </summary>
|
||||||
|
uint Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the lower bits of the player's content ID.
|
||||||
|
/// </summary>
|
||||||
|
uint ContentIdLower { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the player hosting this listing.
|
||||||
|
/// </summary>
|
||||||
|
SeString Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the description of this listing as set by the host. May be multiple lines.
|
||||||
|
/// </summary>
|
||||||
|
SeString Description { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the world that this listing was created on.
|
||||||
|
/// </summary>
|
||||||
|
Lazy<World> World { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the home world of the listing's host.
|
||||||
|
/// </summary>
|
||||||
|
Lazy<World> HomeWorld { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current world of the listing's host.
|
||||||
|
/// </summary>
|
||||||
|
Lazy<World> CurrentWorld { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Party Finder category this listing is listed under.
|
||||||
|
/// </summary>
|
||||||
|
DutyCategory Category { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the row ID of the duty this listing is for. May be 0 for non-duty listings.
|
||||||
|
/// </summary>
|
||||||
|
ushort RawDuty { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the duty this listing is for. May be null for non-duty listings.
|
||||||
|
/// </summary>
|
||||||
|
Lazy<ContentFinderCondition> Duty { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of duty this listing is for.
|
||||||
|
/// </summary>
|
||||||
|
DutyType DutyType { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether if this listing is beginner-friendly. Shown with a sprout icon in-game.
|
||||||
|
/// </summary>
|
||||||
|
bool BeginnersWelcome { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets how many seconds this listing will continue to be available for. It may end before this time if the party
|
||||||
|
/// fills or the host ends it early.
|
||||||
|
/// </summary>
|
||||||
|
ushort SecondsRemaining { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the minimum item level required to join this listing.
|
||||||
|
/// </summary>
|
||||||
|
ushort MinimumItemLevel { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of parties this listing is recruiting for.
|
||||||
|
/// </summary>
|
||||||
|
byte Parties { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of player slots this listing is recruiting for.
|
||||||
|
/// </summary>
|
||||||
|
byte SlotsAvailable { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time at which the server this listings is on last restarted for a patch/hotfix.
|
||||||
|
/// Probably.
|
||||||
|
/// </summary>
|
||||||
|
uint LastPatchHotfixTimestamp { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of the class/job IDs that are currently present in the party.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyCollection<byte> RawJobsPresent { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given flag is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">The flag to check for.</param>
|
||||||
|
/// <returns>A value indicating whether the flag is present.</returns>
|
||||||
|
bool this[ObjectiveFlags flag] { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given flag is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">The flag to check for.</param>
|
||||||
|
/// <returns>A value indicating whether the flag is present.</returns>
|
||||||
|
bool this[ConditionFlags flag] { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given flag is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">The flag to check for.</param>
|
||||||
|
/// <returns>A value indicating whether the flag is present.</returns>
|
||||||
|
bool this[DutyFinderSettingsFlags flag] { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given flag is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">The flag to check for.</param>
|
||||||
|
/// <returns>A value indicating whether the flag is present.</returns>
|
||||||
|
bool this[LootRuleFlags flag] { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the given flag is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">The flag to check for.</param>
|
||||||
|
/// <returns>A value indicating whether the flag is present.</returns>
|
||||||
|
bool this[SearchAreaFlags flag] { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ namespace Dalamud.Game.Gui.PartyFinder.Types;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents additional arguments passed by the game.
|
/// This class represents additional arguments passed by the game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PartyFinderListingEventArgs
|
internal class PartyFinderListingEventArgs : IPartyFinderListingEventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PartyFinderListingEventArgs"/> class.
|
/// Initializes a new instance of the <see cref="PartyFinderListingEventArgs"/> class.
|
||||||
|
|
@ -14,13 +14,25 @@ public class PartyFinderListingEventArgs
|
||||||
this.BatchNumber = batchNumber;
|
this.BatchNumber = batchNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int BatchNumber { get; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool Visible { get; set; } = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A interface representing additional arguments passed by the game.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPartyFinderListingEventArgs
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the batch number.
|
/// Gets the batch number.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int BatchNumber { get; }
|
int BatchNumber { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether the listing is visible.
|
/// Gets or sets a value indicating whether the listing is visible.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Visible { get; set; } = true;
|
bool Visible { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@ internal class CommandWidget : IDataWindowWidget
|
||||||
? commands.OrderBy(kv => kv.Key).ToArray()
|
? commands.OrderBy(kv => kv.Key).ToArray()
|
||||||
: commands.OrderByDescending(kv => kv.Key).ToArray(),
|
: commands.OrderByDescending(kv => kv.Key).ToArray(),
|
||||||
1 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending
|
1 => sortSpecs.Specs.SortDirection == ImGuiSortDirection.Ascending
|
||||||
? commands.OrderBy(kv => kv.Value.LoaderAssemblyName).ToArray()
|
? commands.OrderBy(kv => commandManager.GetHandlerAssemblyName(kv.Key, kv.Value)).ToArray()
|
||||||
: commands.OrderByDescending(kv => kv.Value.LoaderAssemblyName).ToArray(),
|
: commands.OrderByDescending(kv => commandManager.GetHandlerAssemblyName(kv.Key, kv.Value)).ToArray(),
|
||||||
_ => commands,
|
_ => commands,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ internal class CommandWidget : IDataWindowWidget
|
||||||
ImGui.Text(command.Key);
|
ImGui.Text(command.Key);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text(command.Value.LoaderAssemblyName);
|
ImGui.Text(commandManager.GetHandlerAssemblyName(command.Key, command.Value));
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.TextWrapped(command.Value.HelpMessage);
|
ImGui.TextWrapped(command.Value.HelpMessage);
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class DtrBarWidget : IDataWindowWidget
|
internal class DtrBarWidget : IDataWindowWidget
|
||||||
{
|
{
|
||||||
private DtrBarEntry? dtrTest1;
|
private IDtrBarEntry? dtrTest1;
|
||||||
private DtrBarEntry? dtrTest2;
|
private IDtrBarEntry? dtrTest2;
|
||||||
private DtrBarEntry? dtrTest3;
|
private IDtrBarEntry? dtrTest3;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string[]? CommandShortcuts { get; init; } = { "dtr", "dtrbar" };
|
public string[]? CommandShortcuts { get; init; } = { "dtr", "dtrbar" };
|
||||||
|
|
@ -51,7 +51,7 @@ internal class DtrBarWidget : IDataWindowWidget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDtrTestEntry(ref DtrBarEntry? entry, string title)
|
private void DrawDtrTestEntry(ref IDtrBarEntry? entry, string title)
|
||||||
{
|
{
|
||||||
var dtrBar = Service<DtrBar>.Get();
|
var dtrBar = Service<DtrBar>.Get();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2597,7 +2597,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
var commands = commandManager.Commands
|
var commands = commandManager.Commands
|
||||||
.Where(cInfo =>
|
.Where(cInfo =>
|
||||||
cInfo.Value is { ShowInHelp: true } &&
|
cInfo.Value is { ShowInHelp: true } &&
|
||||||
cInfo.Value.LoaderAssemblyName == plugin.Manifest.InternalName)
|
commandManager.GetHandlerAssemblyName(cInfo.Key, cInfo.Value) == plugin.Manifest.InternalName)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
if (commands.Any())
|
if (commands.Any())
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
this.targetCharacter = null;
|
this.targetCharacter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMenuOpened(MenuOpenedArgs args)
|
private void OnMenuOpened(IMenuOpenedArgs args)
|
||||||
{
|
{
|
||||||
this.LogMenuOpened(args);
|
this.LogMenuOpened(args);
|
||||||
|
|
||||||
|
|
@ -139,11 +139,11 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
PrefixColor = 56,
|
PrefixColor = 56,
|
||||||
Priority = -1,
|
Priority = -1,
|
||||||
IsSubmenu = true,
|
IsSubmenu = true,
|
||||||
OnClicked = (MenuItemClickedArgs a) =>
|
OnClicked = (IMenuItemClickedArgs a) =>
|
||||||
{
|
{
|
||||||
SeString name;
|
SeString name;
|
||||||
uint count;
|
uint count;
|
||||||
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.GetRow(item.ItemId)?.Name.ToDalamudString() ?? $"Unknown ({item.ItemId})") + (item.IsHq ? $" {SeIconChar.HighQuality.ToIconString()}" : string.Empty);
|
||||||
|
|
@ -186,7 +186,7 @@ internal class ContextMenuAgingStep : IAgingStep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogMenuOpened(MenuOpenedArgs args)
|
private void LogMenuOpened(IMenuOpenedArgs args)
|
||||||
{
|
{
|
||||||
Log.Verbose($"Got {args.MenuType} context menu with addon 0x{args.AddonPtr:X8} ({args.AddonName}) and agent 0x{args.AgentPtr:X8}");
|
Log.Verbose($"Got {args.MenuType} context menu with addon 0x{args.AddonPtr:X8} ({args.AddonName}) and agent 0x{args.AgentPtr:X8}");
|
||||||
if (args.Target is MenuTargetDefault targetDefault)
|
if (args.Target is MenuTargetDefault targetDefault)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ internal class PartyFinderAgingStep : IAgingStep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PartyFinderOnReceiveListing(PartyFinderListing listing, PartyFinderListingEventArgs args)
|
private void PartyFinderOnReceiveListing(IPartyFinderListing listing, IPartyFinderListingEventArgs args)
|
||||||
{
|
{
|
||||||
this.hasPassed = true;
|
this.hasPassed = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ internal class TitleScreenMenuWindow : Window, IDisposable
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var scale = ImGui.GetIO().FontGlobalScale;
|
var scale = ImGui.GetIO().FontGlobalScale;
|
||||||
var entries = this.titleScreenMenu.Entries;
|
var entries = this.titleScreenMenu.PluginEntries;
|
||||||
|
|
||||||
var hovered = ImGui.IsWindowHovered(
|
var hovered = ImGui.IsWindowHovered(
|
||||||
ImGuiHoveredFlags.RootAndChildWindows |
|
ImGuiHoveredFlags.RootAndChildWindows |
|
||||||
|
|
@ -283,7 +283,7 @@ internal class TitleScreenMenuWindow : Window, IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawEntry(
|
private bool DrawEntry(
|
||||||
TitleScreenMenuEntry entry, bool inhibitFadeout, bool showText, bool isFirst, bool overrideAlpha, bool interactable)
|
ITitleScreenMenuEntry entry, bool inhibitFadeout, bool showText, bool isFirst, bool overrideAlpha, bool interactable)
|
||||||
{
|
{
|
||||||
using var fontScopeDispose = this.myFontHandle.Value.Push();
|
using var fontScopeDispose = this.myFontHandle.Value.Push();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
|
||||||
internal event Action? EntryListChange;
|
internal event Action? EntryListChange;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlyList<TitleScreenMenuEntry> Entries
|
public IReadOnlyList<IReadOnlyTitleScreenMenuEntry> Entries
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
@ -50,8 +50,32 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <summary>
|
||||||
public TitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
|
/// Gets the list of entries in the title screen menu.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<ITitleScreenMenuEntry> PluginEntries
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (this.entries)
|
||||||
|
{
|
||||||
|
if (!this.entries.Any())
|
||||||
|
return Array.Empty<TitleScreenMenuEntry>();
|
||||||
|
|
||||||
|
return this.entriesView ??= this.entries.OrderByDescending(x => x.IsInternal).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a new entry to the title screen menu.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text">The text to show.</param>
|
||||||
|
/// <param name="texture">The texture to show.</param>
|
||||||
|
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
||||||
|
/// <returns>A <see cref="TitleScreenMenu"/> object that can be used to manage the entry.</returns>
|
||||||
|
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
||||||
|
public ITitleScreenMenuEntry AddPluginEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
{
|
{
|
||||||
if (texture.Height != TextureSize || texture.Width != TextureSize)
|
if (texture.Height != TextureSize || texture.Width != TextureSize)
|
||||||
{
|
{
|
||||||
|
|
@ -78,7 +102,27 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public TitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
|
public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
|
{
|
||||||
|
return this.AddPluginEntry(text, texture, onTriggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
|
{
|
||||||
|
return this.AddPluginEntry(priority, text, texture, onTriggered);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a new entry to the title screen menu.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="priority">Priority of the entry.</param>
|
||||||
|
/// <param name="text">The text to show.</param>
|
||||||
|
/// <param name="texture">The texture to show.</param>
|
||||||
|
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
||||||
|
/// <returns>A <see cref="TitleScreenMenu"/> object that can be used to manage the entry.</returns>
|
||||||
|
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
||||||
|
public ITitleScreenMenuEntry AddPluginEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
{
|
{
|
||||||
if (texture.Height != TextureSize || texture.Width != TextureSize)
|
if (texture.Height != TextureSize || texture.Width != TextureSize)
|
||||||
{
|
{
|
||||||
|
|
@ -101,11 +145,11 @@ internal class TitleScreenMenu : IServiceType, ITitleScreenMenu
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RemoveEntry(TitleScreenMenuEntry entry)
|
public void RemoveEntry(IReadOnlyTitleScreenMenuEntry entry)
|
||||||
{
|
{
|
||||||
lock (this.entries)
|
lock (this.entries)
|
||||||
{
|
{
|
||||||
this.entries.Remove(entry);
|
this.entries.RemoveAll(pluginEntry => pluginEntry == entry);
|
||||||
this.entriesView = null;
|
this.entriesView = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,10 +240,10 @@ internal class TitleScreenMenuPluginScoped : IInternalDisposableService, ITitleS
|
||||||
[ServiceManager.ServiceDependency]
|
[ServiceManager.ServiceDependency]
|
||||||
private readonly TitleScreenMenu titleScreenMenuService = Service<TitleScreenMenu>.Get();
|
private readonly TitleScreenMenu titleScreenMenuService = Service<TitleScreenMenu>.Get();
|
||||||
|
|
||||||
private readonly List<TitleScreenMenuEntry> pluginEntries = new();
|
private readonly List<IReadOnlyTitleScreenMenuEntry> pluginEntries = new();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IReadOnlyList<TitleScreenMenuEntry>? Entries => this.titleScreenMenuService.Entries;
|
public IReadOnlyList<IReadOnlyTitleScreenMenuEntry>? Entries => this.titleScreenMenuService.Entries;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
|
|
@ -211,25 +255,25 @@ internal class TitleScreenMenuPluginScoped : IInternalDisposableService, ITitleS
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public TitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
|
public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
{
|
{
|
||||||
var entry = this.titleScreenMenuService.AddEntry(text, texture, onTriggered);
|
var entry = this.titleScreenMenuService.AddPluginEntry(text, texture, onTriggered);
|
||||||
this.pluginEntries.Add(entry);
|
this.pluginEntries.Add(entry);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public TitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
|
public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered)
|
||||||
{
|
{
|
||||||
var entry = this.titleScreenMenuService.AddEntry(priority, text, texture, onTriggered);
|
var entry = this.titleScreenMenuService.AddPluginEntry(priority, text, texture, onTriggered);
|
||||||
this.pluginEntries.Add(entry);
|
this.pluginEntries.Add(entry);
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void RemoveEntry(TitleScreenMenuEntry entry)
|
public void RemoveEntry(IReadOnlyTitleScreenMenuEntry entry)
|
||||||
{
|
{
|
||||||
this.pluginEntries.Remove(entry);
|
this.pluginEntries.Remove(entry);
|
||||||
this.titleScreenMenuService.RemoveEntry(entry);
|
this.titleScreenMenuService.RemoveEntry(entry);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Dalamud.Interface;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class representing an entry in the title screen menu.
|
/// Class representing an entry in the title screen menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TitleScreenMenuEntry : IComparable<TitleScreenMenuEntry>
|
public class TitleScreenMenuEntry : ITitleScreenMenuEntry
|
||||||
{
|
{
|
||||||
private readonly Action onTriggered;
|
private readonly Action onTriggered;
|
||||||
|
|
||||||
|
|
@ -40,40 +40,26 @@ public class TitleScreenMenuEntry : IComparable<TitleScreenMenuEntry>
|
||||||
this.ShowConditionKeys = (showConditionKeys ?? Array.Empty<VirtualKey>()).ToImmutableSortedSet();
|
this.ShowConditionKeys = (showConditionKeys ?? Array.Empty<VirtualKey>()).ToImmutableSortedSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the priority of this entry.
|
|
||||||
/// </summary>
|
|
||||||
public ulong Priority { get; init; }
|
public ulong Priority { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets or sets the name of this entry.
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets or sets the texture of this entry.
|
|
||||||
/// </summary>
|
|
||||||
public IDalamudTextureWrap Texture { get; set; }
|
public IDalamudTextureWrap Texture { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets or sets a value indicating whether or not this entry is internal.
|
public bool IsInternal { get; set; }
|
||||||
/// </summary>
|
|
||||||
internal bool IsInternal { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the calling assembly of this entry.
|
public Assembly? CallingAssembly { get; init; }
|
||||||
/// </summary>
|
|
||||||
internal Assembly? CallingAssembly { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the internal ID of this entry.
|
public Guid Id { get; init; } = Guid.NewGuid();
|
||||||
/// </summary>
|
|
||||||
internal Guid Id { get; init; } = Guid.NewGuid();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc/>
|
||||||
/// Gets the keys that have to be pressed to show the menu.
|
public IReadOnlySet<VirtualKey> ShowConditionKeys { get; init; }
|
||||||
/// </summary>
|
|
||||||
internal IReadOnlySet<VirtualKey> ShowConditionKeys { get; init; }
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int CompareTo(TitleScreenMenuEntry? other)
|
public int CompareTo(TitleScreenMenuEntry? other)
|
||||||
|
|
@ -105,14 +91,72 @@ public class TitleScreenMenuEntry : IComparable<TitleScreenMenuEntry>
|
||||||
/// Determines the displaying condition of this menu entry is met.
|
/// Determines the displaying condition of this menu entry is met.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if met.</returns>
|
/// <returns>True if met.</returns>
|
||||||
internal bool IsShowConditionSatisfied() =>
|
public bool IsShowConditionSatisfied() =>
|
||||||
this.ShowConditionKeys.All(x => Service<KeyState>.GetNullable()?[x] is true);
|
this.ShowConditionKeys.All(x => Service<KeyState>.GetNullable()?[x] is true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Trigger the action associated with this entry.
|
/// Trigger the action associated with this entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal void Trigger()
|
public void Trigger()
|
||||||
{
|
{
|
||||||
this.onTriggered();
|
this.onTriggered();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A interface representing an entry in the title screen menu.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITitleScreenMenuEntry : IReadOnlyTitleScreenMenuEntry, IComparable<TitleScreenMenuEntry>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether or not this entry is internal.
|
||||||
|
/// </summary>
|
||||||
|
bool IsInternal { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the calling assembly of this entry.
|
||||||
|
/// </summary>
|
||||||
|
Assembly? CallingAssembly { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the internal ID of this entry.
|
||||||
|
/// </summary>
|
||||||
|
Guid Id { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the keys that have to be pressed to show the menu.
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlySet<VirtualKey> ShowConditionKeys { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the displaying condition of this menu entry is met.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if met.</returns>
|
||||||
|
bool IsShowConditionSatisfied();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Trigger the action associated with this entry.
|
||||||
|
/// </summary>
|
||||||
|
void Trigger();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A interface representing a read only entry in the title screen menu.
|
||||||
|
/// </summary>
|
||||||
|
public interface IReadOnlyTitleScreenMenuEntry
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the priority of this entry.
|
||||||
|
/// </summary>
|
||||||
|
ulong Priority { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of this entry.
|
||||||
|
/// </summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the texture of this entry.
|
||||||
|
/// </summary>
|
||||||
|
IDalamudTextureWrap Texture { get; }
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,10 +71,11 @@ internal static class PluginValidator
|
||||||
problems.Add(new NoMainUiProblem());
|
problems.Add(new NoMainUiProblem());
|
||||||
|
|
||||||
var cmdManager = Service<CommandManager>.Get();
|
var cmdManager = Service<CommandManager>.Get();
|
||||||
foreach (var cmd in cmdManager.Commands.Where(x => x.Value.LoaderAssemblyName == plugin.InternalName && x.Value.ShowInHelp))
|
|
||||||
|
foreach (var cmd in cmdManager.GetHandlersByAssemblyName(plugin.InternalName).Where(c => c.Key.Item2.ShowInHelp))
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(cmd.Value.HelpMessage))
|
if (string.IsNullOrEmpty(cmd.Key.Item2.HelpMessage))
|
||||||
problems.Add(new CommandWithoutHelpTextProblem(cmd.Key));
|
problems.Add(new CommandWithoutHelpTextProblem(cmd.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin.Manifest.Tags == null || plugin.Manifest.Tags.Count == 0)
|
if (plugin.Manifest.Tags == null || plugin.Manifest.Tags.Count == 0)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Dalamud.Plugin.Services;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This collection represents the list of available Aetherytes in the Teleport window.
|
/// This collection represents the list of available Aetherytes in the Teleport window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IAetheryteList : IReadOnlyCollection<AetheryteEntry>
|
public interface IAetheryteList : IReadOnlyCollection<IAetheryteEntry>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of Aetherytes the local player has unlocked.
|
/// Gets the amount of Aetherytes the local player has unlocked.
|
||||||
|
|
@ -19,5 +19,5 @@ public interface IAetheryteList : IReadOnlyCollection<AetheryteEntry>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Index.</param>
|
/// <param name="index">Index.</param>
|
||||||
/// <returns>A <see cref="AetheryteEntry"/> at the specified index.</returns>
|
/// <returns>A <see cref="AetheryteEntry"/> at the specified index.</returns>
|
||||||
public AetheryteEntry? this[int index] { get; }
|
public IAetheryteEntry? this[int index] { get; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace Dalamud.Plugin.Services;
|
||||||
/// This collection represents the buddies present in your squadron or trust party.
|
/// This collection represents the buddies present in your squadron or trust party.
|
||||||
/// It does not include the local player.
|
/// It does not include the local player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBuddyList : IReadOnlyCollection<BuddyMember>
|
public interface IBuddyList : IReadOnlyCollection<IBuddyMember>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of battle buddies the local player has.
|
/// Gets the amount of battle buddies the local player has.
|
||||||
|
|
@ -18,19 +18,19 @@ public interface IBuddyList : IReadOnlyCollection<BuddyMember>
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the active companion buddy.
|
/// Gets the active companion buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BuddyMember? CompanionBuddy { get; }
|
public IBuddyMember? CompanionBuddy { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the active pet buddy.
|
/// Gets the active pet buddy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BuddyMember? PetBuddy { get; }
|
public IBuddyMember? PetBuddy { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a battle buddy at the specified spawn index.
|
/// Gets a battle buddy at the specified spawn index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Spawn index.</param>
|
/// <param name="index">Spawn index.</param>
|
||||||
/// <returns>A <see cref="BuddyMember"/> at the specified spawn index.</returns>
|
/// <returns>A <see cref="BuddyMember"/> at the specified spawn index.</returns>
|
||||||
public BuddyMember? this[int index] { get; }
|
public IBuddyMember? this[int index] { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the companion buddy.
|
/// Gets the address of the companion buddy.
|
||||||
|
|
@ -56,5 +56,5 @@ public interface IBuddyList : IReadOnlyCollection<BuddyMember>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">The address of the buddy in memory.</param>
|
/// <param name="address">The address of the buddy in memory.</param>
|
||||||
/// <returns><see cref="BuddyMember"/> object containing the requested data.</returns>
|
/// <returns><see cref="BuddyMember"/> object containing the requested data.</returns>
|
||||||
public BuddyMember? CreateBuddyMemberReference(nint address);
|
public IBuddyMember? CreateBuddyMemberReference(nint address);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ public interface IClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the local player character, if one is present.
|
/// Gets the local player character, if one is present.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PlayerCharacter? LocalPlayer { get; }
|
public IPlayerCharacter? LocalPlayer { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content ID of the local character.
|
/// Gets the content ID of the local character.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public interface ICommandManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only list of all registered commands.
|
/// Gets a read-only list of all registered commands.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyDictionary<string, CommandInfo> Commands { get; }
|
public ReadOnlyDictionary<string, ICommandInfo> Commands { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Process a command in full.
|
/// Process a command in full.
|
||||||
|
|
@ -27,7 +27,7 @@ public interface ICommandManager
|
||||||
/// <param name="command">The command to dispatch.</param>
|
/// <param name="command">The command to dispatch.</param>
|
||||||
/// <param name="argument">The provided arguments.</param>
|
/// <param name="argument">The provided arguments.</param>
|
||||||
/// <param name="info">A <see cref="CommandInfo"/> object describing this command.</param>
|
/// <param name="info">A <see cref="CommandInfo"/> object describing this command.</param>
|
||||||
public void DispatchCommand(string command, string argument, CommandInfo info);
|
public void DispatchCommand(string command, string argument, ICommandInfo info);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a command handler, which you can use to add your own custom commands to the in-game chat.
|
/// Add a command handler, which you can use to add your own custom commands to the in-game chat.
|
||||||
|
|
@ -35,7 +35,7 @@ public interface ICommandManager
|
||||||
/// <param name="command">The command to register.</param>
|
/// <param name="command">The command to register.</param>
|
||||||
/// <param name="info">A <see cref="CommandInfo"/> object describing the command.</param>
|
/// <param name="info">A <see cref="CommandInfo"/> object describing the command.</param>
|
||||||
/// <returns>If adding was successful.</returns>
|
/// <returns>If adding was successful.</returns>
|
||||||
public bool AddHandler(string command, CommandInfo info);
|
public bool AddHandler(string command, ICommandInfo info);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove a command from the command handlers.
|
/// Remove a command from the command handlers.
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public interface IContextMenu
|
||||||
/// A delegate type used for the <see cref="OnMenuOpened"/> event.
|
/// A delegate type used for the <see cref="OnMenuOpened"/> event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">Information about the currently opening menu.</param>
|
/// <param name="args">Information about the currently opening menu.</param>
|
||||||
public delegate void OnMenuOpenedDelegate(MenuOpenedArgs args);
|
public delegate void OnMenuOpenedDelegate(IMenuOpenedArgs args);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that gets fired whenever any context menu is opened.
|
/// Event that gets fired whenever any context menu is opened.
|
||||||
|
|
@ -25,7 +25,7 @@ public interface IContextMenu
|
||||||
/// <param name="menuType">The type of context menu to add the item to.</param>
|
/// <param name="menuType">The type of context menu to add the item to.</param>
|
||||||
/// <param name="item">The item to add.</param>
|
/// <param name="item">The item to add.</param>
|
||||||
/// <remarks>Used to add a context menu entry to <em>all</em> context menus.</remarks>
|
/// <remarks>Used to add a context menu entry to <em>all</em> context menus.</remarks>
|
||||||
void AddMenuItem(ContextMenuType menuType, MenuItem item);
|
void AddMenuItem(ContextMenuType menuType, IMenuItem item);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a menu item from a context menu.
|
/// Removes a menu item from a context menu.
|
||||||
|
|
@ -34,5 +34,5 @@ public interface IContextMenu
|
||||||
/// <param name="item">The item to add.</param>
|
/// <param name="item">The item to add.</param>
|
||||||
/// <remarks>Used to remove a context menu entry from <em>all</em> context menus.</remarks>
|
/// <remarks>Used to remove a context menu entry from <em>all</em> context menus.</remarks>
|
||||||
/// <returns><see langword="true"/> if the item was removed, <see langword="false"/> if it was not found.</returns>
|
/// <returns><see langword="true"/> if the item was removed, <see langword="false"/> if it was not found.</returns>
|
||||||
bool RemoveMenuItem(ContextMenuType menuType, MenuItem item);
|
bool RemoveMenuItem(ContextMenuType menuType, IMenuItem item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@ public interface IDtrBar
|
||||||
/// <param name="text">The text the entry shows.</param>
|
/// <param name="text">The text the entry shows.</param>
|
||||||
/// <returns>The entry object used to update, hide and remove the entry.</returns>
|
/// <returns>The entry object used to update, hide and remove the entry.</returns>
|
||||||
/// <exception cref="ArgumentException">Thrown when an entry with the specified title exists.</exception>
|
/// <exception cref="ArgumentException">Thrown when an entry with the specified title exists.</exception>
|
||||||
[Api10ToDo("Return IDtrBarEntry instead of DtrBarEntry")]
|
public IDtrBarEntry Get(string title, SeString? text = null);
|
||||||
public DtrBarEntry Get(string title, SeString? text = null);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a DTR bar entry from the system.
|
/// Removes a DTR bar entry from the system.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Dalamud.Plugin.Services;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This collection represents the currently available Fate events.
|
/// This collection represents the currently available Fate events.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IFateTable : IReadOnlyCollection<Fate>
|
public interface IFateTable : IReadOnlyCollection<IFate>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the Fate table.
|
/// Gets the address of the Fate table.
|
||||||
|
|
@ -18,13 +18,20 @@ public interface IFateTable : IReadOnlyCollection<Fate>
|
||||||
/// Gets the amount of currently active Fates.
|
/// Gets the amount of currently active Fates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Length { get; }
|
public int Length { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this Fate is still valid in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fate">The fate to check.</param>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public bool IsValid(IFate fate);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get an actor at the specified spawn index.
|
/// Get an actor at the specified spawn index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Spawn index.</param>
|
/// <param name="index">Spawn index.</param>
|
||||||
/// <returns>A <see cref="Fate"/> at the specified spawn index.</returns>
|
/// <returns>A <see cref="Fate"/> at the specified spawn index.</returns>
|
||||||
public Fate? this[int index] { get; }
|
public IFate? this[int index] { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the Fate at the specified index of the fate table.
|
/// Gets the address of the Fate at the specified index of the fate table.
|
||||||
|
|
@ -38,5 +45,5 @@ public interface IFateTable : IReadOnlyCollection<Fate>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="offset">The offset of the actor in memory.</param>
|
/// <param name="offset">The offset of the actor in memory.</param>
|
||||||
/// <returns><see cref="Fate"/> object containing requested data.</returns>
|
/// <returns><see cref="Fate"/> object containing requested data.</returns>
|
||||||
public Fate? CreateFateReference(nint offset);
|
public IFate? CreateFateReference(nint offset);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Dalamud.Plugin.Services;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This collection represents the currently spawned FFXIV game objects.
|
/// This collection represents the currently spawned FFXIV game objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IObjectTable : IEnumerable<GameObject>
|
public interface IObjectTable : IEnumerable<IGameObject>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the object table.
|
/// Gets the address of the object table.
|
||||||
|
|
@ -24,14 +24,14 @@ public interface IObjectTable : IEnumerable<GameObject>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Spawn index.</param>
|
/// <param name="index">Spawn index.</param>
|
||||||
/// <returns>An <see cref="GameObject"/> at the specified spawn index.</returns>
|
/// <returns>An <see cref="GameObject"/> at the specified spawn index.</returns>
|
||||||
public GameObject? this[int index] { get; }
|
public IGameObject? this[int index] { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Search for a game object by their Object ID.
|
/// Search for a game object by their Object ID.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="gameObjectId">Object ID to find.</param>
|
/// <param name="gameObjectId">Object ID to find.</param>
|
||||||
/// <returns>A game object or null.</returns>
|
/// <returns>A game object or null.</returns>
|
||||||
public GameObject? SearchById(ulong gameObjectId);
|
public IGameObject? SearchById(ulong gameObjectId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the game object at the specified index of the object table.
|
/// Gets the address of the game object at the specified index of the object table.
|
||||||
|
|
@ -45,5 +45,5 @@ public interface IObjectTable : IEnumerable<GameObject>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">The address of the object in memory.</param>
|
/// <param name="address">The address of the object in memory.</param>
|
||||||
/// <returns><see cref="GameObject"/> object or inheritor containing the requested data.</returns>
|
/// <returns><see cref="GameObject"/> object or inheritor containing the requested data.</returns>
|
||||||
public GameObject? CreateObjectReference(nint address);
|
public IGameObject? CreateObjectReference(nint address);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ public interface IPartyFinderGui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="listing">The listings received.</param>
|
/// <param name="listing">The listings received.</param>
|
||||||
/// <param name="args">Additional arguments passed by the game.</param>
|
/// <param name="args">Additional arguments passed by the game.</param>
|
||||||
public delegate void PartyFinderListingEventDelegate(PartyFinderListing listing, PartyFinderListingEventArgs args);
|
public delegate void PartyFinderListingEventDelegate(IPartyFinderListing listing, IPartyFinderListingEventArgs args);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event fired each time the game receives an individual Party Finder listing.
|
/// Event fired each time the game receives an individual Party Finder listing.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Dalamud.Plugin.Services;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This collection represents the actors present in your party or alliance.
|
/// This collection represents the actors present in your party or alliance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPartyList : IReadOnlyCollection<PartyMember>
|
public interface IPartyList : IReadOnlyCollection<IPartyMember>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of party members the local player has.
|
/// Gets the amount of party members the local player has.
|
||||||
|
|
@ -49,7 +49,7 @@ public interface IPartyList : IReadOnlyCollection<PartyMember>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">Spawn index.</param>
|
/// <param name="index">Spawn index.</param>
|
||||||
/// <returns>A <see cref="PartyMember"/> at the specified spawn index.</returns>
|
/// <returns>A <see cref="PartyMember"/> at the specified spawn index.</returns>
|
||||||
public PartyMember? this[int index] { get; }
|
public IPartyMember? this[int index] { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the party member at the specified index of the party list.
|
/// Gets the address of the party member at the specified index of the party list.
|
||||||
|
|
@ -63,7 +63,7 @@ public interface IPartyList : IReadOnlyCollection<PartyMember>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">The address of the party member in memory.</param>
|
/// <param name="address">The address of the party member in memory.</param>
|
||||||
/// <returns>The party member object containing the requested data.</returns>
|
/// <returns>The party member object containing the requested data.</returns>
|
||||||
public PartyMember? CreatePartyMemberReference(nint address);
|
public IPartyMember? CreatePartyMemberReference(nint address);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the alliance member at the specified index of the alliance list.
|
/// Gets the address of the alliance member at the specified index of the alliance list.
|
||||||
|
|
@ -77,5 +77,5 @@ public interface IPartyList : IReadOnlyCollection<PartyMember>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="address">The address of the alliance member in memory.</param>
|
/// <param name="address">The address of the alliance member in memory.</param>
|
||||||
/// <returns>The party member object containing the requested data.</returns>
|
/// <returns>The party member object containing the requested data.</returns>
|
||||||
public PartyMember? CreateAllianceMemberReference(nint address);
|
public IPartyMember? CreateAllianceMemberReference(nint address);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,41 +11,41 @@ public interface ITargetManager
|
||||||
/// Gets or sets the current target.
|
/// Gets or sets the current target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? Target { get; set; }
|
public IGameObject? Target { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the mouseover target.
|
/// Gets or sets the mouseover target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? MouseOverTarget { get; set; }
|
public IGameObject? MouseOverTarget { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the focus target.
|
/// Gets or sets the focus target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? FocusTarget { get; set; }
|
public IGameObject? FocusTarget { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the previous target.
|
/// Gets or sets the previous target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? PreviousTarget { get; set; }
|
public IGameObject? PreviousTarget { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the soft target.
|
/// Gets or sets the soft target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? SoftTarget { get; set; }
|
public IGameObject? SoftTarget { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the gpose target.
|
/// Gets or sets the gpose target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? GPoseTarget { get; set; }
|
public IGameObject? GPoseTarget { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the mouseover nameplate target.
|
/// Gets or sets the mouseover nameplate target.
|
||||||
/// Set to null to clear the target.
|
/// Set to null to clear the target.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GameObject? MouseOverNameplateTarget { get; set; }
|
public IGameObject? MouseOverNameplateTarget { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ namespace Dalamud.Plugin.Services;
|
||||||
public interface ITitleScreenMenu
|
public interface ITitleScreenMenu
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list of entries in the title screen menu.
|
/// Gets the list of read only entries in the title screen menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<TitleScreenMenuEntry> Entries { get; }
|
public IReadOnlyList<IReadOnlyTitleScreenMenuEntry> Entries { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new entry to the title screen menu.
|
/// Adds a new entry to the title screen menu.
|
||||||
|
|
@ -21,9 +21,9 @@ public interface ITitleScreenMenu
|
||||||
/// <param name="text">The text to show.</param>
|
/// <param name="text">The text to show.</param>
|
||||||
/// <param name="texture">The texture to show.</param>
|
/// <param name="texture">The texture to show.</param>
|
||||||
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
||||||
/// <returns>A <see cref="TitleScreenMenu"/> object that can be used to manage the entry.</returns>
|
/// <returns>A <see cref="IReadOnlyTitleScreenMenuEntry"/> object that can be reference the entry.</returns>
|
||||||
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
||||||
public TitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered);
|
public IReadOnlyTitleScreenMenuEntry AddEntry(string text, IDalamudTextureWrap texture, Action onTriggered);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a new entry to the title screen menu.
|
/// Adds a new entry to the title screen menu.
|
||||||
|
|
@ -32,13 +32,13 @@ public interface ITitleScreenMenu
|
||||||
/// <param name="text">The text to show.</param>
|
/// <param name="text">The text to show.</param>
|
||||||
/// <param name="texture">The texture to show.</param>
|
/// <param name="texture">The texture to show.</param>
|
||||||
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
/// <param name="onTriggered">The action to execute when the option is selected.</param>
|
||||||
/// <returns>A <see cref="TitleScreenMenu"/> object that can be used to manage the entry.</returns>
|
/// <returns>A <see cref="IReadOnlyTitleScreenMenuEntry"/> object that can be used to reference the entry.</returns>
|
||||||
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
/// <exception cref="ArgumentException">Thrown when the texture provided does not match the required resolution(64x64).</exception>
|
||||||
public TitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered);
|
public IReadOnlyTitleScreenMenuEntry AddEntry(ulong priority, string text, IDalamudTextureWrap texture, Action onTriggered);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Remove an entry from the title screen menu.
|
/// Remove an entry from the title screen menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entry">The entry to remove.</param>
|
/// <param name="entry">The entry to remove.</param>
|
||||||
public void RemoveEntry(TitleScreenMenuEntry entry);
|
public void RemoveEntry(IReadOnlyTitleScreenMenuEntry entry);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ public static class MapUtil
|
||||||
/// <param name="go">The GameObject to get the position for.</param>
|
/// <param name="go">The GameObject to get the position for.</param>
|
||||||
/// <param name="correctZOffset">Whether to "correct" a Z offset to sane values for maps that don't have one.</param>
|
/// <param name="correctZOffset">Whether to "correct" a Z offset to sane values for maps that don't have one.</param>
|
||||||
/// <returns>A Vector3 that represents the X (east/west), Y (north/south), and Z (height) position of this object.</returns>
|
/// <returns>A Vector3 that represents the X (east/west), Y (north/south), and Z (height) position of this object.</returns>
|
||||||
public static unsafe Vector3 GetMapCoordinates(this GameObject go, bool correctZOffset = false)
|
public static unsafe Vector3 GetMapCoordinates(this IGameObject go, bool correctZOffset = false)
|
||||||
{
|
{
|
||||||
var agentMap = AgentMap.Instance();
|
var agentMap = AgentMap.Instance();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ public static class Util
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="go">The GameObject to show.</param>
|
/// <param name="go">The GameObject to show.</param>
|
||||||
/// <param name="autoExpand">Whether or not the struct should start as expanded.</param>
|
/// <param name="autoExpand">Whether or not the struct should start as expanded.</param>
|
||||||
public static unsafe void ShowGameObjectStruct(GameObject go, bool autoExpand = true)
|
public static unsafe void ShowGameObjectStruct(IGameObject go, bool autoExpand = true)
|
||||||
{
|
{
|
||||||
switch (go)
|
switch (go)
|
||||||
{
|
{
|
||||||
|
|
@ -280,8 +280,8 @@ public static class Util
|
||||||
case Character chara:
|
case Character chara:
|
||||||
ShowStruct(chara.Struct, autoExpand);
|
ShowStruct(chara.Struct, autoExpand);
|
||||||
break;
|
break;
|
||||||
default:
|
case GameObject gameObject:
|
||||||
ShowStruct(go.Struct, autoExpand);
|
ShowStruct(gameObject.Struct, autoExpand);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -739,6 +739,40 @@ public static class Util
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print formatted IGameObject Information to ImGui.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">IGameObject to Display.</param>
|
||||||
|
/// <param name="tag">Display Tag.</param>
|
||||||
|
/// <param name="resolveGameData">If the IGameObjects data should be resolved.</param>
|
||||||
|
internal static void PrintGameObject(IGameObject actor, string tag, bool resolveGameData)
|
||||||
|
{
|
||||||
|
var actorString =
|
||||||
|
$"{actor.Address.ToInt64():X}:{actor.GameObjectId:X}[{tag}] - {actor.ObjectKind} - {actor.Name} - X{actor.Position.X} Y{actor.Position.Y} Z{actor.Position.Z} D{actor.YalmDistanceX} R{actor.Rotation} - Target: {actor.TargetObjectId:X}\n";
|
||||||
|
|
||||||
|
if (actor is Npc npc)
|
||||||
|
actorString += $" DataId: {npc.DataId} NameId:{npc.NameId}\n";
|
||||||
|
|
||||||
|
if (actor is ICharacter chara)
|
||||||
|
{
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor is IPlayerCharacter pc)
|
||||||
|
{
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(actorString);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.Button($"C##{actor.Address.ToInt64()}"))
|
||||||
|
{
|
||||||
|
ImGui.SetClipboardText(actor.Address.ToInt64().ToString("X"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Print formatted GameObject Information to ImGui.
|
/// Print formatted GameObject Information to ImGui.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue