diff --git a/Dalamud/Game/ClientState/Party/PartyList.cs b/Dalamud/Game/ClientState/Party/PartyList.cs
index bfd423a79..ec22932ab 100644
--- a/Dalamud/Game/ClientState/Party/PartyList.cs
+++ b/Dalamud/Game/ClientState/Party/PartyList.cs
@@ -8,6 +8,7 @@ using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using CSGroupManager = FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager;
+using CSPartyMember = FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember;
namespace Dalamud.Game.ClientState.Party;
@@ -42,20 +43,20 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
public bool IsAlliance => this.GroupManagerStruct->MainGroup.AllianceFlags > 0;
///
- public unsafe IntPtr GroupManagerAddress => (nint)CSGroupManager.Instance();
+ public unsafe nint GroupManagerAddress => (nint)CSGroupManager.Instance();
///
- public IntPtr GroupListAddress => (IntPtr)Unsafe.AsPointer(ref GroupManagerStruct->MainGroup.PartyMembers[0]);
+ public nint GroupListAddress => (nint)Unsafe.AsPointer(ref GroupManagerStruct->MainGroup.PartyMembers[0]);
///
- public IntPtr AllianceListAddress => (IntPtr)Unsafe.AsPointer(ref this.GroupManagerStruct->MainGroup.AllianceMembers[0]);
+ public nint AllianceListAddress => (nint)Unsafe.AsPointer(ref this.GroupManagerStruct->MainGroup.AllianceMembers[0]);
///
public long PartyId => this.GroupManagerStruct->MainGroup.PartyId;
- private static int PartyMemberSize { get; } = Marshal.SizeOf();
+ private static int PartyMemberSize { get; } = Marshal.SizeOf();
- private FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager* GroupManagerStruct => (FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager*)this.GroupManagerAddress;
+ private CSGroupManager* GroupManagerStruct => (CSGroupManager*)this.GroupManagerAddress;
///
public IPartyMember? this[int index]
@@ -80,45 +81,45 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
}
///
- public IntPtr GetPartyMemberAddress(int index)
+ public nint GetPartyMemberAddress(int index)
{
if (index < 0 || index >= GroupLength)
- return IntPtr.Zero;
+ return 0;
return this.GroupListAddress + (index * PartyMemberSize);
}
///
- public IPartyMember? CreatePartyMemberReference(IntPtr address)
+ public IPartyMember? CreatePartyMemberReference(nint address)
{
if (this.clientState.LocalContentId == 0)
return null;
- if (address == IntPtr.Zero)
+ if (address == 0)
return null;
- return new PartyMember(address);
+ return new PartyMember((CSPartyMember*)address);
}
///
- public IntPtr GetAllianceMemberAddress(int index)
+ public nint GetAllianceMemberAddress(int index)
{
if (index < 0 || index >= AllianceLength)
- return IntPtr.Zero;
+ return 0;
return this.AllianceListAddress + (index * PartyMemberSize);
}
///
- public IPartyMember? CreateAllianceMemberReference(IntPtr address)
+ public IPartyMember? CreateAllianceMemberReference(nint address)
{
if (this.clientState.LocalContentId == 0)
return null;
- if (address == IntPtr.Zero)
+ if (address == 0)
return null;
- return new PartyMember(address);
+ return new PartyMember((CSPartyMember*)address);
}
}
diff --git a/Dalamud/Game/ClientState/Party/PartyMember.cs b/Dalamud/Game/ClientState/Party/PartyMember.cs
index 4c738d866..c9980d9f2 100644
--- a/Dalamud/Game/ClientState/Party/PartyMember.cs
+++ b/Dalamud/Game/ClientState/Party/PartyMember.cs
@@ -1,26 +1,27 @@
+using System.Diagnostics.CodeAnalysis;
using System.Numerics;
-using System.Runtime.CompilerServices;
using Dalamud.Data;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Statuses;
using Dalamud.Game.Text.SeStringHandling;
-using Dalamud.Memory;
using Lumina.Excel;
+using CSPartyMember = FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember;
+
namespace Dalamud.Game.ClientState.Party;
///
/// Interface representing a party member.
///
-public interface IPartyMember
+public interface IPartyMember : IEquatable
{
///
/// Gets the address of this party member in memory.
///
- IntPtr Address { get; }
+ nint Address { get; }
///
/// Gets a list of buffs or debuffs applied to this party member.
@@ -108,69 +109,81 @@ public interface IPartyMember
}
///
-/// This class represents a party member in the group manager.
+/// This struct represents a party member in the group manager.
///
-internal unsafe class PartyMember : IPartyMember
+/// A pointer to the PartyMember.
+internal unsafe readonly struct PartyMember(CSPartyMember* ptr) : IPartyMember
{
- ///
- /// Initializes a new instance of the class.
- ///
- /// Address of the party member.
- internal PartyMember(IntPtr address)
- {
- this.Address = address;
- }
+ ///
+ public nint Address => (nint)ptr;
///
- public IntPtr Address { get; }
+ public StatusList Statuses => new(&ptr->StatusManager);
///
- public StatusList Statuses => new(&this.Struct->StatusManager);
+ public Vector3 Position => ptr->Position;
///
- public Vector3 Position => this.Struct->Position;
+ public long ContentId => (long)ptr->ContentId;
///
- public long ContentId => (long)this.Struct->ContentId;
+ public uint ObjectId => ptr->EntityId;
///
- public uint ObjectId => this.Struct->EntityId;
-
- ///
- public uint EntityId => this.Struct->EntityId;
+ public uint EntityId => ptr->EntityId;
///
public IGameObject? GameObject => Service.Get().SearchById(this.EntityId);
///
- public uint CurrentHP => this.Struct->CurrentHP;
+ public uint CurrentHP => ptr->CurrentHP;
///
- public uint MaxHP => this.Struct->MaxHP;
+ public uint MaxHP => ptr->MaxHP;
///
- public ushort CurrentMP => this.Struct->CurrentMP;
+ public ushort CurrentMP => ptr->CurrentMP;
///
- public ushort MaxMP => this.Struct->MaxMP;
+ public ushort MaxMP => ptr->MaxMP;
///
- public RowRef Territory => LuminaUtils.CreateRef(this.Struct->TerritoryType);
+ public RowRef Territory => LuminaUtils.CreateRef(ptr->TerritoryType);
///
- public RowRef World => LuminaUtils.CreateRef(this.Struct->HomeWorld);
+ public RowRef World => LuminaUtils.CreateRef(ptr->HomeWorld);
///
- public SeString Name => SeString.Parse(this.Struct->Name);
+ public SeString Name => SeString.Parse(ptr->Name);
///
- public byte Sex => this.Struct->Sex;
+ public byte Sex => ptr->Sex;
///
- public RowRef ClassJob => LuminaUtils.CreateRef(this.Struct->ClassJob);
+ public RowRef ClassJob => LuminaUtils.CreateRef(ptr->ClassJob);
///
- public byte Level => this.Struct->Level;
+ public byte Level => ptr->Level;
- private FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember*)this.Address;
+ public static bool operator ==(PartyMember x, PartyMember y) => x.Equals(y);
+
+ public static bool operator !=(PartyMember x, PartyMember y) => !(x == y);
+
+ ///
+ public bool Equals(IPartyMember? other)
+ {
+ return this.EntityId == other.EntityId;
+ }
+
+ ///
+ public override bool Equals([NotNullWhen(true)] object? obj)
+ {
+ return obj is PartyMember fate && this.Equals(fate);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return this.EntityId.GetHashCode();
+ }
}