mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add IPlayerState service
This commit is contained in:
parent
7bf79bdea6
commit
4422622e1e
25 changed files with 1043 additions and 112 deletions
|
|
@ -77,7 +77,7 @@ internal partial class ChatHandlers : IServiceType
|
|||
}
|
||||
|
||||
// For injections while logged in
|
||||
if (clientState.LocalPlayer != null && clientState.TerritoryType == 0 && !this.hasSeenLoadingMsg)
|
||||
if (clientState.IsLoggedIn && clientState.TerritoryType == 0 && !this.hasSeenLoadingMsg)
|
||||
this.PrintWelcomeMessage();
|
||||
|
||||
#if !DEBUG && false
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
|
@ -22,7 +23,7 @@ namespace Dalamud.Game.ClientState.Aetherytes;
|
|||
internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteList
|
||||
{
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly ClientState clientState = Service<ClientState>.Get();
|
||||
private readonly ObjectTable objectTable = Service<ObjectTable>.Get();
|
||||
|
||||
private readonly Telepo* telepoInstance = Telepo.Instance();
|
||||
|
||||
|
|
@ -37,7 +38,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
|
|||
{
|
||||
get
|
||||
{
|
||||
if (this.clientState.LocalPlayer == null)
|
||||
if (this.objectTable.LocalPlayer == null)
|
||||
return 0;
|
||||
|
||||
this.Update();
|
||||
|
|
@ -59,7 +60,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
|
|||
return null;
|
||||
}
|
||||
|
||||
if (this.clientState.LocalPlayer == null)
|
||||
if (this.objectTable.LocalPlayer == null)
|
||||
return null;
|
||||
|
||||
return new AetheryteEntry(this.telepoInstance->TeleportList[index]);
|
||||
|
|
@ -69,7 +70,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
|
|||
private void Update()
|
||||
{
|
||||
// this is very very important as otherwise it crashes
|
||||
if (this.clientState.LocalPlayer == null)
|
||||
if (this.objectTable.LocalPlayer == null)
|
||||
return;
|
||||
|
||||
this.telepoInstance->UpdateAetheryteList();
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
|||
private const uint InvalidObjectID = 0xE0000000;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly ClientState clientState = Service<ClientState>.Get();
|
||||
private readonly PlayerState.PlayerState playerState = Service<PlayerState.PlayerState>.Get();
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private BuddyList()
|
||||
|
|
@ -105,10 +105,10 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
|
|||
/// <inheritdoc/>
|
||||
public IBuddyMember? CreateBuddyMemberReference(IntPtr address)
|
||||
{
|
||||
if (this.clientState.LocalContentId == 0)
|
||||
if (address == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
if (!this.playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
var buddy = new BuddyMember(address);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
[ServiceManager.ServiceDependency]
|
||||
private readonly NetworkHandlers networkHandlers = Service<NetworkHandlers>.Get();
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly PlayerState.PlayerState playerState = Service<PlayerState.PlayerState>.Get();
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly ObjectTable objectTable = Service<ObjectTable>.Get();
|
||||
|
||||
private Hook<LogoutCallbackInterface.Delegates.OnLogout> onLogoutHook;
|
||||
private bool initialized;
|
||||
private ushort territoryTypeId;
|
||||
|
|
@ -184,10 +190,10 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlayerCharacter? LocalPlayer => Service<ObjectTable>.GetNullable()?[0] as IPlayerCharacter;
|
||||
public IPlayerCharacter? LocalPlayer => this.objectTable.LocalPlayer;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public unsafe ulong LocalContentId => PlayerState.Instance()->ContentId;
|
||||
public unsafe ulong LocalContentId => this.playerState.ContentId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public unsafe bool IsLoggedIn
|
||||
|
|
@ -241,7 +247,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
public bool IsClientIdle(out ConditionFlag blockingFlag)
|
||||
{
|
||||
blockingFlag = 0;
|
||||
if (this.LocalPlayer is null) return true;
|
||||
if (this.objectTable.LocalPlayer is null) return true;
|
||||
|
||||
var condition = Service<Conditions.Condition>.GetNullable();
|
||||
|
||||
|
|
@ -368,7 +374,7 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
|||
if (condition == null || gameGui == null || data == null)
|
||||
return;
|
||||
|
||||
if (condition.Any() && this.lastConditionNone && this.LocalPlayer != null)
|
||||
if (condition.Any() && this.lastConditionNone && this.objectTable.LocalPlayer != null)
|
||||
{
|
||||
Log.Debug("Is login");
|
||||
this.lastConditionNone = false;
|
||||
|
|
|
|||
|
|
@ -150,15 +150,11 @@ internal unsafe partial class Fate
|
|||
/// <returns>True or false.</returns>
|
||||
public static bool IsValid(Fate fate)
|
||||
{
|
||||
var clientState = Service<ClientState>.GetNullable();
|
||||
|
||||
if (fate == null || clientState == null)
|
||||
if (fate == null)
|
||||
return false;
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
return playerState.IsLoaded == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -60,15 +60,11 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
|||
/// <inheritdoc/>
|
||||
public bool IsValid(IFate fate)
|
||||
{
|
||||
var clientState = Service<ClientState>.GetNullable();
|
||||
|
||||
if (fate == null || clientState == null)
|
||||
if (fate == null)
|
||||
return false;
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
return playerState.IsLoaded == true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -87,12 +83,11 @@ internal sealed partial class FateTable : IServiceType, IFateTable
|
|||
/// <inheritdoc/>
|
||||
public IFate? CreateFateReference(IntPtr offset)
|
||||
{
|
||||
var clientState = Service<ClientState>.Get();
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
if (offset == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
if (offset == IntPtr.Zero)
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
if (!playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
return new Fate(offset);
|
||||
|
|
|
|||
|
|
@ -31,16 +31,16 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
|||
{
|
||||
private static int objectTableLength;
|
||||
|
||||
private readonly ClientState clientState;
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly PlayerState.PlayerState playerState = Service<PlayerState.PlayerState>.Get();
|
||||
|
||||
private readonly CachedEntry[] cachedObjectTable;
|
||||
|
||||
private readonly Enumerator?[] frameworkThreadEnumerators = new Enumerator?[4];
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private unsafe ObjectTable(ClientState clientState)
|
||||
private unsafe ObjectTable()
|
||||
{
|
||||
this.clientState = clientState;
|
||||
|
||||
var nativeObjectTable = CSGameObjectManager.Instance()->Objects.IndexSorted;
|
||||
objectTableLength = nativeObjectTable.Length;
|
||||
|
||||
|
|
@ -66,6 +66,9 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
|||
/// <inheritdoc/>
|
||||
public int Length => objectTableLength;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IPlayerCharacter? LocalPlayer => this[0] as IPlayerCharacter;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<IBattleChara> PlayerObjects => this.GetPlayerObjects();
|
||||
|
||||
|
|
@ -142,10 +145,10 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
|
|||
{
|
||||
ThreadSafety.AssertMainThread();
|
||||
|
||||
if (this.clientState.LocalContentId == 0)
|
||||
if (address == nint.Zero)
|
||||
return null;
|
||||
|
||||
if (address == nint.Zero)
|
||||
if (!this.playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
var obj = (CSGameObject*)address;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using Dalamud.Game.ClientState.Objects.Enums;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
using Dalamud.Memory;
|
||||
|
||||
namespace Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
|
|
@ -170,15 +168,11 @@ internal partial class GameObject
|
|||
/// <returns>True or false.</returns>
|
||||
public static bool IsValid(IGameObject? actor)
|
||||
{
|
||||
var clientState = Service<ClientState>.GetNullable();
|
||||
|
||||
if (actor is null || clientState == null)
|
||||
if (actor == null)
|
||||
return false;
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
return playerState.IsLoaded == true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
|||
private const int AllianceLength = 20;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly ClientState clientState = Service<ClientState>.Get();
|
||||
private readonly PlayerState.PlayerState playerState = Service<PlayerState.PlayerState>.Get();
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private PartyList()
|
||||
|
|
@ -91,10 +91,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
|||
/// <inheritdoc/>
|
||||
public IPartyMember? CreatePartyMemberReference(IntPtr address)
|
||||
{
|
||||
if (this.clientState.LocalContentId == 0)
|
||||
return null;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
if (address == IntPtr.Zero || !this.playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
return new PartyMember(address);
|
||||
|
|
@ -112,10 +109,7 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
|
|||
/// <inheritdoc/>
|
||||
public IPartyMember? CreateAllianceMemberReference(IntPtr address)
|
||||
{
|
||||
if (this.clientState.LocalContentId == 0)
|
||||
return null;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
if (address == IntPtr.Zero || !this.playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
return new PartyMember(address);
|
||||
|
|
|
|||
|
|
@ -66,15 +66,14 @@ public sealed unsafe partial class StatusList
|
|||
/// <returns>The status object containing the requested data.</returns>
|
||||
public static StatusList? CreateStatusListReference(IntPtr address)
|
||||
{
|
||||
if (address == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
// The use case for CreateStatusListReference and CreateStatusReference to be static is so
|
||||
// fake status lists can be generated. Since they aren't exposed as services, it's either
|
||||
// here or somewhere else.
|
||||
var clientState = Service<ClientState>.Get();
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
return null;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
if (!playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
return new StatusList(address);
|
||||
|
|
@ -87,12 +86,11 @@ public sealed unsafe partial class StatusList
|
|||
/// <returns>The status object containing the requested data.</returns>
|
||||
public static Status? CreateStatusReference(IntPtr address)
|
||||
{
|
||||
var clientState = Service<ClientState>.Get();
|
||||
|
||||
if (clientState.LocalContentId == 0)
|
||||
if (address == IntPtr.Zero)
|
||||
return null;
|
||||
|
||||
if (address == IntPtr.Zero)
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
if (!playerState.IsLoaded)
|
||||
return null;
|
||||
|
||||
return new Status(address);
|
||||
|
|
|
|||
|
|
@ -16,13 +16,12 @@ using Dalamud.Hooking;
|
|||
using Dalamud.Networking.Http;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Control;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.InstanceContent;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
||||
using FFXIVClientStructs.FFXIV.Client.Network;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Info;
|
||||
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Network.Internal;
|
||||
|
|
@ -269,29 +268,8 @@ internal unsafe class NetworkHandlers : IInternalDisposableService
|
|||
|
||||
private static (ulong UploaderId, uint WorldId) GetUploaderInfo()
|
||||
{
|
||||
var agentLobby = AgentLobby.Instance();
|
||||
|
||||
var uploaderId = agentLobby->LobbyData.ContentId;
|
||||
if (uploaderId == 0)
|
||||
{
|
||||
var playerState = PlayerState.Instance();
|
||||
if (playerState->IsLoaded)
|
||||
{
|
||||
uploaderId = playerState->ContentId;
|
||||
}
|
||||
}
|
||||
|
||||
var worldId = agentLobby->LobbyData.CurrentWorldId;
|
||||
if (worldId == 0)
|
||||
{
|
||||
var localPlayer = Control.GetLocalPlayer();
|
||||
if (localPlayer != null)
|
||||
{
|
||||
worldId = localPlayer->CurrentWorld;
|
||||
}
|
||||
}
|
||||
|
||||
return (uploaderId, worldId);
|
||||
var playerState = Service<PlayerState.PlayerState>.Get();
|
||||
return (playerState.ContentId, playerState.CurrentWorld.RowId);
|
||||
}
|
||||
|
||||
private unsafe nint CfPopDetour(PublicContentDirector.EnterContentInfoPacket* packetData)
|
||||
|
|
|
|||
27
Dalamud/Game/PlayerState/MentorVersion.cs
Normal file
27
Dalamud/Game/PlayerState/MentorVersion.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
namespace Dalamud.Game.PlayerState;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the mentor certification version for a player.
|
||||
/// </summary>
|
||||
public enum MentorVersion : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the player has never held mentor status in any expansion.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the player was last a mentor during the <c>Shadowbringers</c> expansion.
|
||||
/// </summary>
|
||||
Shadowbringers = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the player was last a mentor during the <c>Endwalker</c> expansion.
|
||||
/// </summary>
|
||||
Endwalker = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the player was last a mentor during the <c>Dawntrail</c> expansion.
|
||||
/// </summary>
|
||||
Dawntrail = 3,
|
||||
}
|
||||
489
Dalamud/Game/PlayerState/PlayerAttribute.cs
Normal file
489
Dalamud/Game/PlayerState/PlayerAttribute.cs
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
namespace Dalamud.Game.PlayerState;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a player's attribute.
|
||||
/// </summary>
|
||||
public enum PlayerAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Strength.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects physical damage dealt by gladiator's arms, marauder's arms, dark knight's arms, gunbreaker's arms, pugilist's arms, lancer's arms, samurai's arms, reaper's arms, thaumaturge's arms, arcanist's arms, red mage's arms, pictomancer's arms, conjurer's arms, astrologian's arms, sage's arms, and blue mage's arms.
|
||||
/// </remarks>
|
||||
Strength = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Dexterity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects physical damage dealt by rogue's arms, viper's arms, archer's arms, machinist's arms, and dancer's arms.
|
||||
/// </remarks>
|
||||
Dexterity = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Vitality.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects maximum HP.
|
||||
/// </remarks>
|
||||
Vitality = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Intelligence.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects attack magic potency when role is DPS.
|
||||
/// </remarks>
|
||||
Intelligence = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Mind.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects healing magic potency. Also affects attack magic potency when role is Healer.
|
||||
/// </remarks>
|
||||
Mind = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Piety.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects MP regeneration. Regeneration rate is determined by piety. Only applicable when in battle and role is Healer.
|
||||
/// </remarks>
|
||||
Piety = 6,
|
||||
|
||||
/// <summary>
|
||||
/// Health Points.
|
||||
/// </summary>
|
||||
HP = 7,
|
||||
|
||||
/// <summary>
|
||||
/// Mana Points.
|
||||
/// </summary>
|
||||
MP = 8,
|
||||
|
||||
/// <summary>
|
||||
/// Tactical Points.
|
||||
/// </summary>
|
||||
TP = 9,
|
||||
|
||||
/// <summary>
|
||||
/// Gathering Point.
|
||||
/// </summary>
|
||||
GP = 10,
|
||||
|
||||
/// <summary>
|
||||
/// Crafting Points.
|
||||
/// </summary>
|
||||
CP = 11,
|
||||
|
||||
/// <summary>
|
||||
/// Physical Damage.
|
||||
/// </summary>
|
||||
PhysicalDamage = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Magic Damage.
|
||||
/// </summary>
|
||||
MagicDamage = 13,
|
||||
|
||||
/// <summary>
|
||||
/// Delay.
|
||||
/// </summary>
|
||||
Delay = 14,
|
||||
|
||||
/// <summary>
|
||||
/// Additional Effect.
|
||||
/// </summary>
|
||||
AdditionalEffect = 15,
|
||||
|
||||
/// <summary>
|
||||
/// Attack Speed.
|
||||
/// </summary>
|
||||
AttackSpeed = 16,
|
||||
|
||||
/// <summary>
|
||||
/// Block Rate.
|
||||
/// </summary>
|
||||
BlockRate = 17,
|
||||
|
||||
/// <summary>
|
||||
/// Block Strength.
|
||||
/// </summary>
|
||||
BlockStrength = 18,
|
||||
|
||||
/// <summary>
|
||||
/// Tenacity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of physical and magic damage dealt and received, as well as HP restored. The higher the value, the more damage dealt, the more HP restored, and the less damage taken. Only applicable when role is Tank.
|
||||
/// </remarks>
|
||||
Tenacity = 19,
|
||||
|
||||
/// <summary>
|
||||
/// Attack Power.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects amount of damage dealt by physical attacks. The higher the value, the more damage dealt.
|
||||
/// </remarks>
|
||||
AttackPower = 20,
|
||||
|
||||
/// <summary>
|
||||
/// Defense.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of damage taken by physical attacks. The higher the value, the less damage taken.
|
||||
/// </remarks>
|
||||
Defense = 21,
|
||||
|
||||
/// <summary>
|
||||
/// Direct Hit Rate.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the rate at which your physical and magic attacks land direct hits, dealing slightly more damage than normal hits. The higher the value, the higher the frequency with which your hits will be direct. Higher values will also result in greater damage for actions which guarantee direct hits.
|
||||
/// </remarks>
|
||||
DirectHitRate = 22,
|
||||
|
||||
/// <summary>
|
||||
/// Evasion.
|
||||
/// </summary>
|
||||
Evasion = 23,
|
||||
|
||||
/// <summary>
|
||||
/// Magic Defense.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of damage taken by magic attacks. The higher the value, the less damage taken.
|
||||
/// </remarks>
|
||||
MagicDefense = 24,
|
||||
|
||||
/// <summary>
|
||||
/// Critical Hit Power.
|
||||
/// </summary>
|
||||
CriticalHitPower = 25,
|
||||
|
||||
/// <summary>
|
||||
/// Critical Hit Resilience.
|
||||
/// </summary>
|
||||
CriticalHitResilience = 26,
|
||||
|
||||
/// <summary>
|
||||
/// Critical Hit.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of physical and magic damage dealt, as well as HP restored. The higher the value, the higher the frequency with which your hits will be critical/higher the potency of critical hits.
|
||||
/// </remarks>
|
||||
CriticalHit = 27,
|
||||
|
||||
/// <summary>
|
||||
/// Critical Hit Evasion.
|
||||
/// </summary>
|
||||
CriticalHitEvasion = 28,
|
||||
|
||||
/// <summary>
|
||||
/// Slashing Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases damage done by slashing attacks.
|
||||
/// </remarks>
|
||||
SlashingResistance = 29,
|
||||
|
||||
/// <summary>
|
||||
/// Piercing Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases damage done by piercing attacks.
|
||||
/// </remarks>
|
||||
PiercingResistance = 30,
|
||||
|
||||
/// <summary>
|
||||
/// Blunt Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases damage done by blunt attacks.
|
||||
/// </remarks>
|
||||
BluntResistance = 31,
|
||||
|
||||
/// <summary>
|
||||
/// Projectile Resistance.
|
||||
/// </summary>
|
||||
ProjectileResistance = 32,
|
||||
|
||||
/// <summary>
|
||||
/// Attack Magic Potency.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of damage dealt by magic attacks.
|
||||
/// </remarks>
|
||||
AttackMagicPotency = 33,
|
||||
|
||||
/// <summary>
|
||||
/// Healing Magic Potency.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of HP restored via healing magic.
|
||||
/// </remarks>
|
||||
HealingMagicPotency = 34,
|
||||
|
||||
/// <summary>
|
||||
/// Enhancement Magic Potency.
|
||||
/// </summary>
|
||||
EnhancementMagicPotency = 35,
|
||||
|
||||
/// <summary>
|
||||
/// Elemental Bonus.
|
||||
/// </summary>
|
||||
ElementalBonus = 36,
|
||||
|
||||
/// <summary>
|
||||
/// Fire Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases fire-aspected damage.
|
||||
/// </remarks>
|
||||
FireResistance = 37,
|
||||
|
||||
/// <summary>
|
||||
/// Ice Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases ice-aspected damage.
|
||||
/// </remarks>
|
||||
IceResistance = 38,
|
||||
|
||||
/// <summary>
|
||||
/// Wind Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases wind-aspected damage.
|
||||
/// </remarks>
|
||||
WindResistance = 39,
|
||||
|
||||
/// <summary>
|
||||
/// Earth Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases earth-aspected damage.
|
||||
/// </remarks>
|
||||
EarthResistance = 40,
|
||||
|
||||
/// <summary>
|
||||
/// Lightning Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases lightning-aspected damage.
|
||||
/// </remarks>
|
||||
LightningResistance = 41,
|
||||
|
||||
/// <summary>
|
||||
/// Water Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Decreases water-aspected damage.
|
||||
/// </remarks>
|
||||
WaterResistance = 42,
|
||||
|
||||
/// <summary>
|
||||
/// Magic Resistance.
|
||||
/// </summary>
|
||||
MagicResistance = 43,
|
||||
|
||||
/// <summary>
|
||||
/// Determination.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of damage dealt by both physical and magic attacks, as well as the amount of HP restored by healing spells.
|
||||
/// </remarks>
|
||||
Determination = 44,
|
||||
|
||||
/// <summary>
|
||||
/// Skill Speed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects both the casting and recast timers, as well as the damage over time potency for weaponskills and auto-attacks. The higher the value, the shorter the timers/higher the potency.
|
||||
/// </remarks>
|
||||
SkillSpeed = 45,
|
||||
|
||||
/// <summary>
|
||||
/// Spell Speed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects both the casting and recast timers for spells. The higher the value, the shorter the timers. Also affects a spell's damage over time or healing over time potency.
|
||||
/// </remarks>
|
||||
SpellSpeed = 46,
|
||||
|
||||
/// <summary>
|
||||
/// Haste.
|
||||
/// </summary>
|
||||
Haste = 47,
|
||||
|
||||
/// <summary>
|
||||
/// Morale.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In PvP, replaces physical and magical defense in determining damage inflicted by other players. Also influences the amount of damage dealt to other players.
|
||||
/// </remarks>
|
||||
Morale = 48,
|
||||
|
||||
/// <summary>
|
||||
/// Enmity.
|
||||
/// </summary>
|
||||
Enmity = 49,
|
||||
|
||||
/// <summary>
|
||||
/// Enmity Reduction.
|
||||
/// </summary>
|
||||
EnmityReduction = 50,
|
||||
|
||||
/// <summary>
|
||||
/// Desynthesis Skill Gain.
|
||||
/// </summary>
|
||||
DesynthesisSkillGain = 51,
|
||||
|
||||
/// <summary>
|
||||
/// EXP Bonus.
|
||||
/// </summary>
|
||||
EXPBonus = 52,
|
||||
|
||||
/// <summary>
|
||||
/// Regen.
|
||||
/// </summary>
|
||||
Regen = 53,
|
||||
|
||||
/// <summary>
|
||||
/// Special Attribute.
|
||||
/// </summary>
|
||||
SpecialAttribute = 54,
|
||||
|
||||
/// <summary>
|
||||
/// Main Attribute.
|
||||
/// </summary>
|
||||
MainAttribute = 55,
|
||||
|
||||
/// <summary>
|
||||
/// Secondary Attribute.
|
||||
/// </summary>
|
||||
SecondaryAttribute = 56,
|
||||
|
||||
/// <summary>
|
||||
/// Slow Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of slow.
|
||||
/// </remarks>
|
||||
SlowResistance = 57,
|
||||
|
||||
/// <summary>
|
||||
/// Petrification Resistance.
|
||||
/// </summary>
|
||||
PetrificationResistance = 58,
|
||||
|
||||
/// <summary>
|
||||
/// Paralysis Resistance.
|
||||
/// </summary>
|
||||
ParalysisResistance = 59,
|
||||
|
||||
/// <summary>
|
||||
/// Silence Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of silence.
|
||||
/// </remarks>
|
||||
SilenceResistance = 60,
|
||||
|
||||
/// <summary>
|
||||
/// Blind Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of blind.
|
||||
/// </remarks>
|
||||
BlindResistance = 61,
|
||||
|
||||
/// <summary>
|
||||
/// Poison Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of poison.
|
||||
/// </remarks>
|
||||
PoisonResistance = 62,
|
||||
|
||||
/// <summary>
|
||||
/// Stun Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of stun.
|
||||
/// </remarks>
|
||||
StunResistance = 63,
|
||||
|
||||
/// <summary>
|
||||
/// Sleep Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of sleep.
|
||||
/// </remarks>
|
||||
SleepResistance = 64,
|
||||
|
||||
/// <summary>
|
||||
/// Bind Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of bind.
|
||||
/// </remarks>
|
||||
BindResistance = 65,
|
||||
|
||||
/// <summary>
|
||||
/// Heavy Resistance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Shortens the duration of heavy.
|
||||
/// </remarks>
|
||||
HeavyResistance = 66,
|
||||
|
||||
/// <summary>
|
||||
/// Doom Resistance.
|
||||
/// </summary>
|
||||
DoomResistance = 67,
|
||||
|
||||
/// <summary>
|
||||
/// Reduced Durability Loss.
|
||||
/// </summary>
|
||||
ReducedDurabilityLoss = 68,
|
||||
|
||||
/// <summary>
|
||||
/// Increased Spiritbond Gain.
|
||||
/// </summary>
|
||||
IncreasedSpiritbondGain = 69,
|
||||
|
||||
/// <summary>
|
||||
/// Craftsmanship.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of progress achieved in a single synthesis step.
|
||||
/// </remarks>
|
||||
Craftsmanship = 70,
|
||||
|
||||
/// <summary>
|
||||
/// Control.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the amount of quality improved in a single synthesis step.
|
||||
/// </remarks>
|
||||
Control = 71,
|
||||
|
||||
/// <summary>
|
||||
/// Gathering.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects the rate at which items are gathered.
|
||||
/// </remarks>
|
||||
Gathering = 72,
|
||||
|
||||
/// <summary>
|
||||
/// Perception.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Affects item yield when gathering as a botanist or miner, and the size of fish when fishing or spearfishing.
|
||||
/// </remarks>
|
||||
Perception = 73,
|
||||
}
|
||||
205
Dalamud/Game/PlayerState/PlayerState.cs
Normal file
205
Dalamud/Game/PlayerState/PlayerState.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using Dalamud.Data;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
|
||||
|
||||
using Lumina.Excel;
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
using CSPlayerState = FFXIVClientStructs.FFXIV.Client.Game.UI.PlayerState;
|
||||
using GrandCompany = Lumina.Excel.Sheets.GrandCompany;
|
||||
|
||||
namespace Dalamud.Game.PlayerState;
|
||||
|
||||
/// <summary>
|
||||
/// This class contains the PlayerState wrappers.
|
||||
/// </summary>
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
[ResolveVia<IPlayerState>]
|
||||
internal unsafe class PlayerState : IPlayerState, IServiceType
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public bool IsLoaded => CSPlayerState.Instance()->IsLoaded;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string CharacterName => this.IsLoaded ? CSPlayerState.Instance()->CharacterNameString : string.Empty;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint EntityId => this.IsLoaded ? CSPlayerState.Instance()->EntityId : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong ContentId => this.IsLoaded ? CSPlayerState.Instance()->ContentId : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<World> CurrentWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
var agentLobby = AgentLobby.Instance();
|
||||
return agentLobby->IsLoggedIn
|
||||
? LuminaUtils.CreateRef<World>(agentLobby->LobbyData.CurrentWorldId)
|
||||
: default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<World> HomeWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
var agentLobby = AgentLobby.Instance();
|
||||
return agentLobby->IsLoggedIn
|
||||
? LuminaUtils.CreateRef<World>(agentLobby->LobbyData.HomeWorldId)
|
||||
: default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Sex Sex => this.IsLoaded ? (Sex)CSPlayerState.Instance()->Sex : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<Race> Race => this.IsLoaded ? LuminaUtils.CreateRef<Race>(CSPlayerState.Instance()->Race) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<Tribe> Tribe => this.IsLoaded ? LuminaUtils.CreateRef<Tribe>(CSPlayerState.Instance()->Tribe) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<ClassJob> ClassJob => this.IsLoaded ? LuminaUtils.CreateRef<ClassJob>(CSPlayerState.Instance()->CurrentClassJobId) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short Level => this.IsLoaded ? CSPlayerState.Instance()->CurrentLevel : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsLevelSynced => this.IsLoaded && CSPlayerState.Instance()->IsLevelSynced;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short EffectiveLevel => this.IsLoaded ? (this.IsLevelSynced ? CSPlayerState.Instance()->SyncedLevel : CSPlayerState.Instance()->CurrentLevel) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<GuardianDeity> GuardianDeity => this.IsLoaded ? LuminaUtils.CreateRef<GuardianDeity>(CSPlayerState.Instance()->GuardianDeity) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte BirthMonth => this.IsLoaded ? CSPlayerState.Instance()->BirthMonth : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte BirthDay => this.IsLoaded ? CSPlayerState.Instance()->BirthDay : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<ClassJob> FirstClass => this.IsLoaded ? LuminaUtils.CreateRef<ClassJob>(CSPlayerState.Instance()->FirstClass) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<Town> StartTown => this.IsLoaded ? LuminaUtils.CreateRef<Town>(CSPlayerState.Instance()->StartTown) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BaseStrength => this.IsLoaded ? CSPlayerState.Instance()->BaseStrength : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BaseDexterity => this.IsLoaded ? CSPlayerState.Instance()->BaseDexterity : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BaseVitality => this.IsLoaded ? CSPlayerState.Instance()->BaseVitality : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BaseIntelligence => this.IsLoaded ? CSPlayerState.Instance()->BaseIntelligence : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BaseMind => this.IsLoaded ? CSPlayerState.Instance()->BaseMind : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int BasePiety => this.IsLoaded ? CSPlayerState.Instance()->BasePiety : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<GrandCompany> GrandCompany => this.IsLoaded ? LuminaUtils.CreateRef<GrandCompany>(CSPlayerState.Instance()->GrandCompany) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<Aetheryte> HomeAetheryte => this.IsLoaded ? LuminaUtils.CreateRef<Aetheryte>(CSPlayerState.Instance()->HomeAetheryteId) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ReadOnlySpan<RowRef<Aetheryte>> FavouriteAetherytes
|
||||
{
|
||||
get
|
||||
{
|
||||
var playerState = CSPlayerState.Instance();
|
||||
if (playerState->IsLoaded || playerState->FavouriteAetheryteCount == 0)
|
||||
return [];
|
||||
|
||||
var count = playerState->FavouriteAetheryteCount;
|
||||
var array = new RowRef<Aetheryte>[count];
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
array[i] = LuminaUtils.CreateRef<Aetheryte>(playerState->FavouriteAetherytes[i]);
|
||||
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RowRef<Aetheryte> FreeAetheryte => this.IsLoaded ? LuminaUtils.CreateRef<Aetheryte>(CSPlayerState.Instance()->FreeAetheryteId) : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint BaseRestedExperience => this.IsLoaded ? CSPlayerState.Instance()->BaseRestedExperience : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short PlayerCommendations => this.IsLoaded ? CSPlayerState.Instance()->PlayerCommendations : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte DeliveryLevel => this.IsLoaded ? CSPlayerState.Instance()->DeliveryLevel : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public MentorVersion MentorVersion => this.IsLoaded ? (MentorVersion)CSPlayerState.Instance()->MentorVersion : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int GetAttribute(PlayerAttribute attribute) => this.IsLoaded ? CSPlayerState.Instance()->Attributes[(int)attribute] : default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte GetGrandCompanyRank(GrandCompany grandCompany)
|
||||
{
|
||||
if (!this.IsLoaded)
|
||||
return default;
|
||||
|
||||
return grandCompany.RowId switch
|
||||
{
|
||||
1 => CSPlayerState.Instance()->GCRankMaelstrom,
|
||||
2 => CSPlayerState.Instance()->GCRankTwinAdders,
|
||||
3 => CSPlayerState.Instance()->GCRankImmortalFlames,
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short GetClassJobLevel(ClassJob classJob)
|
||||
{
|
||||
if (classJob.ExpArrayIndex == -1)
|
||||
return default;
|
||||
|
||||
if (!this.IsLoaded)
|
||||
return default;
|
||||
|
||||
return CSPlayerState.Instance()->ClassJobLevels[classJob.ExpArrayIndex];
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int GetClassJobExperience(ClassJob classJob)
|
||||
{
|
||||
if (classJob.ExpArrayIndex == -1)
|
||||
return default;
|
||||
|
||||
if (!this.IsLoaded)
|
||||
return default;
|
||||
|
||||
return CSPlayerState.Instance()->ClassJobExperience[classJob.ExpArrayIndex];
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public float GetDesynthesisLevel(ClassJob classJob)
|
||||
{
|
||||
if (classJob.DohDolJobIndex == -1)
|
||||
return default;
|
||||
|
||||
if (!this.IsLoaded)
|
||||
return default;
|
||||
|
||||
return CSPlayerState.Instance()->DesynthesisLevels[classJob.DohDolJobIndex] / 100f;
|
||||
}
|
||||
}
|
||||
17
Dalamud/Game/PlayerState/Sex.cs
Normal file
17
Dalamud/Game/PlayerState/Sex.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
namespace Dalamud.Game.PlayerState;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the sex of a character.
|
||||
/// </summary>
|
||||
public enum Sex : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Male sex.
|
||||
/// </summary>
|
||||
Male = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Female sex.
|
||||
/// </summary>
|
||||
Female = 1,
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@ using Lumina.Text.Payloads;
|
|||
using Lumina.Text.ReadOnly;
|
||||
|
||||
using AddonSheet = Lumina.Excel.Sheets.Addon;
|
||||
using PlayerState = FFXIVClientStructs.FFXIV.Client.Game.UI.PlayerState;
|
||||
using StatusSheet = Lumina.Excel.Sheets.Status;
|
||||
|
||||
namespace Dalamud.Game.Text.Evaluator;
|
||||
|
|
@ -68,6 +67,9 @@ internal class SeStringEvaluator : IServiceType, ISeStringEvaluator
|
|||
[ServiceManager.ServiceDependency]
|
||||
private readonly SheetRedirectResolver sheetRedirectResolver = Service<SheetRedirectResolver>.Get();
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly PlayerState.PlayerState playerState = Service<PlayerState.PlayerState>.Get();
|
||||
|
||||
private readonly ConcurrentDictionary<StringCacheKey<ActionKind>, string> actStrCache = [];
|
||||
private readonly ConcurrentDictionary<StringCacheKey<ObjectKind>, string> objStrCache = [];
|
||||
|
||||
|
|
@ -564,7 +566,7 @@ internal class SeStringEvaluator : IServiceType, ISeStringEvaluator
|
|||
return false;
|
||||
|
||||
// the game uses LocalPlayer here, but using PlayerState seems more safe.
|
||||
return this.ResolveStringExpression(in context, PlayerState.Instance()->EntityId == entityId ? eTrue : eFalse);
|
||||
return this.ResolveStringExpression(in context, playerState.EntityId == entityId ? eTrue : eFalse);
|
||||
}
|
||||
|
||||
private bool TryResolveColor(in SeStringContext context, in ReadOnlySePayloadSpan payload)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.JobGauge;
|
||||
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||
|
|
@ -29,10 +29,10 @@ internal class GaugeWidget : IDataWindowWidget
|
|||
/// <inheritdoc/>
|
||||
public void Draw()
|
||||
{
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var objectTable = Service<ObjectTable>.Get();
|
||||
var jobGauges = Service<JobGauges>.Get();
|
||||
|
||||
var player = clientState.LocalPlayer;
|
||||
var player = objectTable.LocalPlayer;
|
||||
if (player == null)
|
||||
{
|
||||
ImGui.Text("Player is not present"u8);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using Dalamud.Bindings.ImGui;
|
|||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.PlayerState;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||
|
|
@ -39,12 +40,13 @@ internal class ObjectTableWidget : IDataWindowWidget
|
|||
|
||||
var chatGui = Service<ChatGui>.Get();
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var playerState = Service<PlayerState>.Get();
|
||||
var gameGui = Service<GameGui>.Get();
|
||||
var objectTable = Service<ObjectTable>.Get();
|
||||
|
||||
var stateString = string.Empty;
|
||||
|
||||
if (clientState.LocalPlayer == null)
|
||||
if (objectTable.LocalPlayer == null)
|
||||
{
|
||||
ImGui.Text("LocalPlayer null."u8);
|
||||
}
|
||||
|
|
@ -55,10 +57,10 @@ internal class ObjectTableWidget : IDataWindowWidget
|
|||
else
|
||||
{
|
||||
stateString += $"ObjectTableLen: {objectTable.Length}\n";
|
||||
stateString += $"LocalPlayerName: {clientState.LocalPlayer.Name}\n";
|
||||
stateString += $"CurrentWorldName: {(this.resolveGameData ? clientState.LocalPlayer.CurrentWorld.ValueNullable?.Name : clientState.LocalPlayer.CurrentWorld.RowId.ToString())}\n";
|
||||
stateString += $"HomeWorldName: {(this.resolveGameData ? clientState.LocalPlayer.HomeWorld.ValueNullable?.Name : clientState.LocalPlayer.HomeWorld.RowId.ToString())}\n";
|
||||
stateString += $"LocalCID: {clientState.LocalContentId:X}\n";
|
||||
stateString += $"LocalPlayerName: {playerState.CharacterName}\n";
|
||||
stateString += $"CurrentWorldName: {(this.resolveGameData ? playerState.CurrentWorld.ValueNullable?.Name : playerState.CurrentWorld.RowId.ToString())}\n";
|
||||
stateString += $"HomeWorldName: {(this.resolveGameData ? playerState.HomeWorld.ValueNullable?.Name : playerState.HomeWorld.RowId.ToString())}\n";
|
||||
stateString += $"LocalCID: {playerState.ContentId:X}\n";
|
||||
stateString += $"LastLinkedItem: {chatGui.LastLinkedItemId}\n";
|
||||
stateString += $"TerritoryType: {clientState.TerritoryType}\n\n";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||
|
|
@ -111,12 +111,12 @@ internal class PluginIpcWidget : IDataWindowWidget
|
|||
|
||||
if (ImGui.Button("Action GO"u8))
|
||||
{
|
||||
this.ipcSubGo.InvokeAction(Service<ClientState>.Get().LocalPlayer);
|
||||
this.ipcSubGo.InvokeAction(Service<ObjectTable>.Get().LocalPlayer);
|
||||
}
|
||||
|
||||
if (ImGui.Button("Func GO"u8))
|
||||
{
|
||||
this.callGateResponse = this.ipcSubGo.InvokeFunc(Service<ClientState>.Get().LocalPlayer);
|
||||
this.callGateResponse = this.ipcSubGo.InvokeFunc(Service<ObjectTable>.Get().LocalPlayer);
|
||||
}
|
||||
|
||||
if (!this.callGateResponse.IsNullOrEmpty())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Interface.Utility;
|
||||
|
|
@ -33,7 +33,7 @@ internal class TargetWidget : IDataWindowWidget
|
|||
{
|
||||
ImGui.Checkbox("Resolve GameData"u8, ref this.resolveGameData);
|
||||
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var objectTable = Service<ObjectTable>.Get();
|
||||
var targetMgr = Service<TargetManager>.Get();
|
||||
|
||||
if (targetMgr.Target != null)
|
||||
|
|
@ -80,7 +80,7 @@ internal class TargetWidget : IDataWindowWidget
|
|||
if (ImGui.Button("Clear FT"u8))
|
||||
targetMgr.FocusTarget = null;
|
||||
|
||||
var localPlayer = clientState.LocalPlayer;
|
||||
var localPlayer = objectTable.LocalPlayer;
|
||||
|
||||
if (localPlayer != null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Text.Evaluator;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
|
||||
|
|
@ -51,8 +52,8 @@ internal class SeStringEvaluatorSelfTestStep : ISelfTestStep
|
|||
// that it returned the local players name by using its EntityId,
|
||||
// and that it didn't include the world name by checking the HomeWorldId against AgentLobby.Instance()->LobbyData.HomeWorldId.
|
||||
|
||||
var clientState = Service<ClientState>.Get();
|
||||
var localPlayer = clientState.LocalPlayer;
|
||||
var objectTable = Service<ObjectTable>.Get();
|
||||
var localPlayer = objectTable.LocalPlayer;
|
||||
if (localPlayer is null)
|
||||
{
|
||||
ImGui.Text("You need to be logged in for this step."u8);
|
||||
|
|
|
|||
|
|
@ -109,11 +109,13 @@ public interface IClientState
|
|||
/// <summary>
|
||||
/// Gets the local player character, if one is present.
|
||||
/// </summary>
|
||||
[Obsolete($"Use {nameof(IPlayerState)} or {nameof(IObjectTable)}.{nameof(IObjectTable.LocalPlayer)} if you need to.")]
|
||||
public IPlayerCharacter? LocalPlayer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content ID of the local character.
|
||||
/// </summary>
|
||||
[Obsolete($"Use {nameof(IPlayerState)}.{nameof(IPlayerState.ContentId)}")]
|
||||
public ulong LocalContentId { get; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
|
@ -19,6 +20,11 @@ public interface IObjectTable : IEnumerable<IGameObject>
|
|||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the local player character, if one is present.
|
||||
/// </summary>
|
||||
public IPlayerCharacter? LocalPlayer { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator for accessing player objects. This will only contain BattleChara objects.
|
||||
/// Does not contain any mounts, minions, or accessories.
|
||||
|
|
|
|||
212
Dalamud/Plugin/Services/IPlayerState.cs
Normal file
212
Dalamud/Plugin/Services/IPlayerState.cs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
using Dalamud.Game.PlayerState;
|
||||
|
||||
using Lumina.Excel;
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
#pragma warning disable SA1400 // Access modifier should be declared: Interface members are public by default
|
||||
|
||||
/// <summary>
|
||||
/// Interface for determining unlock state of various content in the game.
|
||||
/// </summary>
|
||||
public interface IPlayerState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the local character is loaded.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The actual GameObject will not immediately exist when this changes to true.
|
||||
/// </remarks>
|
||||
bool IsLoaded { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the local character.
|
||||
/// </summary>
|
||||
string CharacterName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity ID of the local character.
|
||||
/// </summary>
|
||||
uint EntityId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the content ID of the local character.
|
||||
/// </summary>
|
||||
ulong ContentId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the World row for the local character's current world.
|
||||
/// </summary>
|
||||
RowRef<World> CurrentWorld { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the World row for the local character's home world.
|
||||
/// </summary>
|
||||
RowRef<World> HomeWorld { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the sex of the local character.
|
||||
/// </summary>
|
||||
Sex Sex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Race row for the local character.
|
||||
/// </summary>
|
||||
RowRef<Race> Race { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Tribe row for the local character.
|
||||
/// </summary>
|
||||
RowRef<Tribe> Tribe { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ClassJob row for the local character's current class/job.
|
||||
/// </summary>
|
||||
RowRef<ClassJob> ClassJob { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current class/job's level of the local character.
|
||||
/// </summary>
|
||||
short Level { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the local character's level is synced.
|
||||
/// </summary>
|
||||
bool IsLevelSynced { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effective level of the local character.
|
||||
/// </summary>
|
||||
short EffectiveLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GuardianDeity row for the local character.
|
||||
/// </summary>
|
||||
RowRef<GuardianDeity> GuardianDeity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the birth month of the local character.
|
||||
/// </summary>
|
||||
byte BirthMonth { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the birth day of the local character.
|
||||
/// </summary>
|
||||
byte BirthDay { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ClassJob row for the local character's starting class.
|
||||
/// </summary>
|
||||
RowRef<ClassJob> FirstClass { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Town row for the local character's starting town.
|
||||
/// </summary>
|
||||
RowRef<Town> StartTown { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base strength of the local character.
|
||||
/// </summary>
|
||||
int BaseStrength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base dexterity of the local character.
|
||||
/// </summary>
|
||||
int BaseDexterity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base vitality of the local character.
|
||||
/// </summary>
|
||||
int BaseVitality { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base intelligence of the local character.
|
||||
/// </summary>
|
||||
int BaseIntelligence { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base mind of the local character.
|
||||
/// </summary>
|
||||
int BaseMind { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the piety mind of the local character.
|
||||
/// </summary>
|
||||
int BasePiety { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GrandCompany row for the local character's current Grand Company affiliation.
|
||||
/// </summary>
|
||||
RowRef<GrandCompany> GrandCompany { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Aetheryte row for the local character's home aetheryte.
|
||||
/// </summary>
|
||||
RowRef<Aetheryte> HomeAetheryte { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a span of Aetheryte rows for the local character's favourite aetherytes.
|
||||
/// </summary>
|
||||
ReadOnlySpan<RowRef<Aetheryte>> FavouriteAetherytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Aetheryte row for the local character's free aetheryte.
|
||||
/// </summary>
|
||||
RowRef<Aetheryte> FreeAetheryte { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of received player commendations of the local character.
|
||||
/// </summary>
|
||||
uint BaseRestedExperience { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of received player commendations of the local character.
|
||||
/// </summary>
|
||||
short PlayerCommendations { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Carrier Level of Delivery Moogle Quests of the local character.
|
||||
/// </summary>
|
||||
byte DeliveryLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mentor version of the local character.
|
||||
/// </summary>
|
||||
MentorVersion MentorVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of an attribute of the local character.
|
||||
/// </summary>
|
||||
/// <param name="attribute">The attribute to check.</param>
|
||||
/// <returns>The value of the specific attribute.</returns>
|
||||
int GetAttribute(PlayerAttribute attribute);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Grand Company rank of the local character.
|
||||
/// </summary>
|
||||
/// <param name="grandCompany">The Grand Company to check.</param>
|
||||
/// <returns>The Grand Company rank of the local character.</returns>
|
||||
byte GetGrandCompanyRank(GrandCompany grandCompany);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the level of the local character's class/job.
|
||||
/// </summary>
|
||||
/// <param name="classJob">The ClassJob row to check.</param>
|
||||
/// <returns>The level of the requested class/job.</returns>
|
||||
short GetClassJobLevel(ClassJob classJob);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the experience of the local character's class/job.
|
||||
/// </summary>
|
||||
/// <param name="classJob">The ClassJob row to check.</param>
|
||||
/// <returns>The experience of the requested class/job.</returns>
|
||||
int GetClassJobExperience(ClassJob classJob);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the desynthesis level of the local character's crafter job.
|
||||
/// </summary>
|
||||
/// <param name="classJob">The ClassJob row to check.</param>
|
||||
/// <returns>The desynthesis level of the requested crafter job.</returns>
|
||||
float GetDesynthesisLevel(ClassJob classJob);
|
||||
}
|
||||
|
|
@ -18,18 +18,21 @@ using Dalamud.Game;
|
|||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Support;
|
||||
|
||||
using Lumina.Excel.Sheets;
|
||||
|
||||
using Serilog;
|
||||
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
using Windows.Win32.System.Memory;
|
||||
using Windows.Win32.System.Ole;
|
||||
using Windows.Win32.UI.WindowsAndMessaging;
|
||||
|
||||
using Dalamud.Interface.Internal;
|
||||
|
||||
using FLASHWINFO = Windows.Win32.UI.WindowsAndMessaging.FLASHWINFO;
|
||||
using HWND = Windows.Win32.Foundation.HWND;
|
||||
using MEMORY_BASIC_INFORMATION = Windows.Win32.System.Memory.MEMORY_BASIC_INFORMATION;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue