mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-13 12:14:16 +01:00
Merge pull request #406 from daemitus/feature/not-shit-actors
This commit is contained in:
commit
0586c47309
53 changed files with 1588 additions and 1144 deletions
|
|
@ -6,11 +6,12 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
// General
|
// General
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1118:Parameter should not span multiple lines", Justification = "Preventing long lines", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1124:Do not use regions", Justification = "I like regions", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1123:Do not place regions within elements", Justification = "I like regions in elements too", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "This is annoying", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud.CorePlugin")]
|
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1127:Generic type constraints should be on their own line", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
|
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "I like this better", Scope = "namespaceanddescendants", Target = "~N:Dalamud")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
|
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:File should have header", Justification = "We don't do those yet")]
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace Dalamud.CorePlugin
|
||||||
|
|
||||||
this.Interface = pluginInterface;
|
this.Interface = pluginInterface;
|
||||||
|
|
||||||
// this.windowSystem.AddWindow(your_window);
|
this.windowSystem.AddWindow(new PluginWindow(Dalamud.Instance));
|
||||||
|
|
||||||
this.Interface.UiBuilder.OnBuildUi += this.OnDraw;
|
this.Interface.UiBuilder.OnBuildUi += this.OnDraw;
|
||||||
this.Interface.UiBuilder.OnOpenConfigUi += this.OnOpenConfigUi;
|
this.Interface.UiBuilder.OnOpenConfigUi += this.OnOpenConfigUi;
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Label="Warnings">
|
<PropertyGroup Label="Warnings">
|
||||||
<NoWarn>IDE0003;IDE1006;CS1591;CS1701;CS1702</NoWarn>
|
<NoWarn>IDE0003;IDE0044;IDE1006;CS1591;CS1701;CS1702</NoWarn>
|
||||||
<!-- IDE1006 - Naming violation -->
|
<!-- IDE1006 - Naming violation -->
|
||||||
<!-- CS1591 - Missing XML comment for publicly visible type or member -->
|
<!-- CS1591 - Missing XML comment for publicly visible type or member -->
|
||||||
<!-- CS1701 - Runtime policy may be needed -->
|
<!-- CS1701 - Runtime policy may be needed -->
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
|
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
|
||||||
using Dalamud.Game.ClientState.Structs;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
using Actor = Dalamud.Game.ClientState.Actors.Types.Actor;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
namespace Dalamud.Game.ClientState.Actors
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This collection represents the currently spawned FFXIV actors.
|
/// This collection represents the currently spawned FFXIV actors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ActorTable : IReadOnlyCollection<Actor>, ICollection
|
public sealed partial class ActorTable
|
||||||
{
|
{
|
||||||
private const int ActorTableLength = 424;
|
private const int ActorTableLength = 424;
|
||||||
|
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ActorTable"/> class.
|
/// Initializes a new instance of the <see cref="ActorTable"/> class.
|
||||||
|
|
@ -29,10 +26,10 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
/// <param name="addressResolver">Client state address resolver.</param>
|
/// <param name="addressResolver">Client state address resolver.</param>
|
||||||
internal ActorTable(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
internal ActorTable(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
{
|
{
|
||||||
this.Address = addressResolver;
|
|
||||||
this.dalamud = dalamud;
|
this.dalamud = dalamud;
|
||||||
|
this.address = addressResolver;
|
||||||
|
|
||||||
Log.Verbose("Actor table address {ActorTable}", this.Address.ActorTable);
|
Log.Verbose($"Actor table address 0x{this.address.ActorTable.ToInt64():X}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -56,6 +53,65 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an actor at the specified spawn index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Spawn index.</param>
|
||||||
|
/// <returns>An <see cref="Actor"/> at the specified spawn index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public Actor this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var address = this.GetActorAddress(index);
|
||||||
|
return this.CreateActorReference(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the actor at the specified index of the actor table.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the actor.</param>
|
||||||
|
/// <returns>The memory address of the actor.</returns>
|
||||||
|
public unsafe IntPtr GetActorAddress(int index)
|
||||||
|
{
|
||||||
|
if (index >= ActorTableLength)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return *(IntPtr*)(this.address.ActorTable + (8 * index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to a FFXIV actor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the actor in memory.</param>
|
||||||
|
/// <returns><see cref="Actor"/> object or inheritor containing requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public unsafe Actor CreateActorReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var objKind = *(ObjectKind*)(address + ActorOffsets.ObjectKind);
|
||||||
|
return objKind switch
|
||||||
|
{
|
||||||
|
ObjectKind.Player => new PlayerCharacter(address, this.dalamud),
|
||||||
|
ObjectKind.BattleNpc => new BattleNpc(address, this.dalamud),
|
||||||
|
ObjectKind.EventObj => new EventObj(address, this.dalamud),
|
||||||
|
ObjectKind.Companion => new Npc(address, this.dalamud),
|
||||||
|
_ => new Actor(address, this.dalamud),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the currently spawned FFXIV actors.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ActorTable : IReadOnlyCollection<Actor>, ICollection
|
||||||
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
int IReadOnlyCollection<Actor>.Count => this.Length;
|
int IReadOnlyCollection<Actor>.Count => this.Length;
|
||||||
|
|
||||||
|
|
@ -68,43 +124,6 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
object ICollection.SyncRoot => this;
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
private ClientStateAddressResolver Address { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get an actor at the specified spawn index.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index">Spawn index.</param>
|
|
||||||
/// <returns><see cref="Actor" /> at the specified spawn index.</returns>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor this[int index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var ptr = this.GetActorAddress(index);
|
|
||||||
if (ptr != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
return this.CreateActorReference(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the address of the actor at the specified index of the actor table.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index">The index of the actor.</param>
|
|
||||||
/// <returns>The memory address of the actor.</returns>
|
|
||||||
public unsafe IntPtr GetActorAddress(int index)
|
|
||||||
{
|
|
||||||
if (index >= ActorTableLength)
|
|
||||||
{
|
|
||||||
return IntPtr.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *(IntPtr*)(this.Address.ActorTable + (8 * index));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IEnumerator<Actor> GetEnumerator()
|
public IEnumerator<Actor> GetEnumerator()
|
||||||
{
|
{
|
||||||
|
|
@ -115,10 +134,7 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
{
|
|
||||||
return this.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void ICollection.CopyTo(Array array, int index)
|
void ICollection.CopyTo(Array array, int index)
|
||||||
|
|
@ -129,33 +145,5 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a reference to a FFXIV actor.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="offset">The offset of the actor in memory.</param>
|
|
||||||
/// <returns><see cref="Actor"/> object or inheritor containing requested data.</returns>
|
|
||||||
[CanBeNull]
|
|
||||||
internal unsafe Actor CreateActorReference(IntPtr offset)
|
|
||||||
{
|
|
||||||
if (this.dalamud.ClientState.LocalContentId == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var objKind = *(ObjectKind*)(offset + ActorOffsets.ObjectKind);
|
|
||||||
|
|
||||||
// TODO: This is for compatibility with legacy actor classes - superseded once ready
|
|
||||||
var actorStruct = Marshal.PtrToStructure<Structs.Actor>(offset);
|
|
||||||
|
|
||||||
return objKind switch
|
|
||||||
{
|
|
||||||
ObjectKind.Player => new PlayerCharacter(offset, actorStruct, this.dalamud),
|
|
||||||
ObjectKind.BattleNpc => new BattleNpc(offset, actorStruct, this.dalamud),
|
|
||||||
ObjectKind.EventObj => new EventObj(offset, actorStruct, this.dalamud),
|
|
||||||
ObjectKind.Companion => new Npc(offset, actorStruct, this.dalamud),
|
|
||||||
_ => new Actor(offset, actorStruct, this.dalamud),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Resolvers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Base object resolver.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class BaseResolver
|
|
||||||
{
|
|
||||||
private Dalamud dalamud;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="BaseResolver"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dalamud">The Dalamud instance.</param>
|
|
||||||
internal BaseResolver(Dalamud dalamud)
|
|
||||||
{
|
|
||||||
this.dalamud = dalamud;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Dalamud instance.
|
|
||||||
/// </summary>
|
|
||||||
internal Dalamud Dalamud => this.dalamud;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Resolvers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This object represents a class or job.
|
|
||||||
/// </summary>
|
|
||||||
public class ClassJob : BaseResolver
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ID of the ClassJob.
|
|
||||||
/// </summary>
|
|
||||||
public readonly uint Id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ClassJob"/> class.
|
|
||||||
/// Set up the ClassJob resolver with the provided ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The ID of the classJob.</param>
|
|
||||||
/// <param name="dalamud">The Dalamud instance.</param>
|
|
||||||
internal ClassJob(byte id, Dalamud dalamud)
|
|
||||||
: base(dalamud)
|
|
||||||
{
|
|
||||||
this.Id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets GameData linked to this ClassJob.
|
|
||||||
/// </summary>
|
|
||||||
public Lumina.Excel.GeneratedSheets.ClassJob GameData =>
|
|
||||||
this.Dalamud.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.ClassJob>().GetRow(this.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Resolvers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This object represents a world a character can reside on.
|
|
||||||
/// </summary>
|
|
||||||
public class World : BaseResolver
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// ID of the world.
|
|
||||||
/// </summary>
|
|
||||||
public readonly uint Id;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="World"/> class.
|
|
||||||
/// Set up the world resolver with the provided ID.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The ID of the world.</param>
|
|
||||||
/// <param name="dalamud">The Dalamud instance.</param>
|
|
||||||
internal World(ushort id, Dalamud dalamud)
|
|
||||||
: base(dalamud)
|
|
||||||
{
|
|
||||||
this.Id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets GameData linked to this world.
|
|
||||||
/// </summary>
|
|
||||||
public Lumina.Excel.GeneratedSheets.World GameData =>
|
|
||||||
this.Dalamud.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.World>().GetRow(this.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -11,8 +11,8 @@ namespace Dalamud.Game.ClientState.Actors
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class Targets
|
public sealed class Targets
|
||||||
{
|
{
|
||||||
private Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
private ClientStateAddressResolver address;
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Targets"/> class.
|
/// Initializes a new instance of the <see cref="Targets"/> class.
|
||||||
|
|
|
||||||
|
|
@ -1,101 +1,165 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Structs;
|
using Dalamud.Game.ClientState.Structs;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a basic FFXIV actor.
|
/// This class represents a basic actor (GameObject) in FFXIV.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Actor : IEquatable<Actor>
|
public unsafe partial class Actor : IEquatable<Actor>
|
||||||
{
|
{
|
||||||
private readonly Structs.Actor actorStruct;
|
|
||||||
private readonly Dalamud dalamud;
|
|
||||||
|
|
||||||
private string name;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Actor"/> class.
|
/// Initializes a new instance of the <see cref="Actor"/> class.
|
||||||
/// This represents a basic FFXIV actor.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal Actor(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
|
internal Actor(IntPtr address, Dalamud dalamud)
|
||||||
{
|
{
|
||||||
this.actorStruct = actorStruct;
|
this.Dalamud = dalamud;
|
||||||
this.dalamud = dalamud;
|
|
||||||
this.Address = address;
|
this.Address = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the position of this <see cref="Actor" />.
|
/// Gets the address of the actor in memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Position3 Position => this.ActorStruct.Position;
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the rotation of this <see cref="Actor" />.
|
/// Gets Dalamud itself.
|
||||||
/// This ranges from -pi to pi radians.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float Rotation => this.ActorStruct.Rotation;
|
private protected Dalamud Dalamud { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This allows you to <c>if (actor) {...}</c> to check for validity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">The actor to check.</param>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public static implicit operator bool(Actor actor) => IsValid(actor);
|
||||||
|
|
||||||
|
public static bool operator ==(Actor actor1, Actor actor2)
|
||||||
|
{
|
||||||
|
if (actor1 is null || actor2 is null)
|
||||||
|
return Equals(actor1, actor2);
|
||||||
|
|
||||||
|
return actor1.Equals(actor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Actor actor1, Actor actor2) => !(actor1 == actor2);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this actor is still valid in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">The actor to check.</param>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public static bool IsValid(Actor actor)
|
||||||
|
{
|
||||||
|
if (actor == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (actor.Dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this actor is still valid in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public bool IsValid() => IsValid(this);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
bool IEquatable<Actor>.Equals(Actor other) => this.ActorId == other?.ActorId;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object obj) => ((IEquatable<Actor>)this).Equals(obj as Actor);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode() => this.ActorId.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a basic actor (GameObject) in FFXIV.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe partial class Actor
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the displayname of this <see cref="Actor" />.
|
/// Gets the displayname of this <see cref="Actor" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name => this.name ??= Util.GetUTF8String(this.actorStruct.Name);
|
public SeString Name => MemoryHelper.ReadSeString(this.Address + ActorOffsets.Name, 32);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the actor ID of this <see cref="Actor" />.
|
/// Gets the actor ID of this <see cref="Actor" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ActorId => this.ActorStruct.ActorId;
|
public uint ActorId => *(uint*)(this.Address + ActorOffsets.ActorId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the hitbox radius of this <see cref="Actor" />.
|
/// Gets the data ID for linking to other respective game data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float HitboxRadius => this.ActorStruct.HitboxRadius;
|
public uint DataId => *(uint*)(this.Address + ActorOffsets.DataId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of this GameObject's owner.
|
||||||
|
/// </summary>
|
||||||
|
public uint OwnerId => *(uint*)(this.Address + ActorOffsets.OwnerId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the entity kind of this <see cref="Actor" />.
|
/// Gets the entity kind of this <see cref="Actor" />.
|
||||||
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ObjectKind ObjectKind => this.ActorStruct.ObjectKind;
|
public ObjectKind ObjectKind => *(ObjectKind*)(this.Address + ActorOffsets.ObjectKind);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sub kind of this Actor.
|
||||||
|
/// </summary>
|
||||||
|
public byte SubKind => *(byte*)(this.Address + ActorOffsets.SubKind);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the actor is friendly.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsFriendly => *(int*)(this.Address + ActorOffsets.IsFriendly) > 0;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the X distance from the local player in yalms.
|
/// Gets the X distance from the local player in yalms.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte YalmDistanceX => this.ActorStruct.YalmDistanceFromPlayerX;
|
public byte YalmDistanceX => *(byte*)(this.Address + ActorOffsets.YalmDistanceFromObjectX);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the target status.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is some kind of enum. It may be <see cref="StatusEffect"/>.
|
||||||
|
/// </remarks>
|
||||||
|
public byte TargetStatus => *(byte*)(this.Address + ActorOffsets.TargetStatus);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Y distance from the local player in yalms.
|
/// Gets the Y distance from the local player in yalms.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte YalmDistanceY => this.ActorStruct.YalmDistanceFromPlayerY;
|
public byte YalmDistanceY => *(byte*)(this.Address + ActorOffsets.YalmDistanceFromObjectY);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target of the actor.
|
/// Gets the position of this <see cref="Actor" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual int TargetActorID => 0;
|
public Position3 Position => *(Position3*)(this.Address + ActorOffsets.Position);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets status Effects.
|
/// Gets the rotation of this <see cref="Actor" />.
|
||||||
|
/// This ranges from -pi to pi radians.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StatusEffect[] StatusEffects => this.ActorStruct.UIStatusEffects;
|
public float Rotation => *(float*)(this.Address + ActorOffsets.Rotation);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of this actor in memory.
|
/// Gets the hitbox radius of this <see cref="Actor" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly IntPtr Address;
|
public float HitboxRadius => *(float*)(this.Address + ActorOffsets.HitboxRadius);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the memory representation of the base actor.
|
/// Gets the current target of the Actor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Structs.Actor ActorStruct => this.actorStruct;
|
public virtual uint TargetActorID => 0;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="Dalamud"/> backing instance.
|
|
||||||
/// </summary>
|
|
||||||
internal Dalamud Dalamud => this.dalamud;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
bool IEquatable<Actor>.Equals(Actor other) => this.ActorId == other.ActorId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
61
Dalamud/Game/ClientState/Actors/Types/ActorOffsets.cs
Normal file
61
Dalamud/Game/ClientState/Actors/Types/ActorOffsets.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Memory offsets for the <see cref="Actor"/> type and all that inherit from it.
|
||||||
|
/// </summary>
|
||||||
|
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.")]
|
||||||
|
public static class ActorOffsets
|
||||||
|
{
|
||||||
|
// GameObject(Actor)
|
||||||
|
// GameObject :: Character
|
||||||
|
// GameObject :: Character :: BattleChara
|
||||||
|
// GameObject :: Character :: Companion
|
||||||
|
|
||||||
|
public const int Name = 0x30;
|
||||||
|
public const int ActorId = 0x74;
|
||||||
|
public const int DataId = 0x80;
|
||||||
|
public const int OwnerId = 0x84;
|
||||||
|
public const int ObjectKind = 0x8C;
|
||||||
|
public const int SubKind = 0x8D;
|
||||||
|
public const int IsFriendly = 0x8E;
|
||||||
|
public const int YalmDistanceFromObjectX = 0x90;
|
||||||
|
public const int TargetStatus = 0x91;
|
||||||
|
public const int YalmDistanceFromObjectY = 0x92;
|
||||||
|
public const int Position = 0xA0;
|
||||||
|
public const int Rotation = 0xB0;
|
||||||
|
public const int HitboxRadius = 0xC0;
|
||||||
|
// End GameObject 0x1A0
|
||||||
|
|
||||||
|
public const int CurrentHp = 0x1C4;
|
||||||
|
public const int MaxHp = 0x1C8;
|
||||||
|
public const int CurrentMp = 0x1CC;
|
||||||
|
public const int MaxMp = 0x1D0;
|
||||||
|
public const int CurrentGp = 0x1D4;
|
||||||
|
public const int MaxGp = 0x1D6;
|
||||||
|
public const int CurrentCp = 0x1D8;
|
||||||
|
public const int MaxCp = 0x1DA;
|
||||||
|
public const int ClassJob = 0x1E2;
|
||||||
|
public const int Level = 0x1E3;
|
||||||
|
public const int PlayerCharacterTargetActorId = 0x230;
|
||||||
|
public const int Customize = 0x1898;
|
||||||
|
public const int CompanyTag = 0x18B2;
|
||||||
|
public const int BattleNpcTargetActorId = 0x18D8;
|
||||||
|
public const int NameId = 0x1940;
|
||||||
|
public const int CurrentWorld = 0x195C;
|
||||||
|
public const int HomeWorld = 0x195E;
|
||||||
|
public const int StatusFlags = 0x19A0;
|
||||||
|
// End Character 0x19B0
|
||||||
|
// End Companion 0x19C0
|
||||||
|
|
||||||
|
public const int UIStatusEffects = 0x19F8;
|
||||||
|
public const int IsCasting = 0x1B80;
|
||||||
|
public const int IsCasting2 = 0x1B82;
|
||||||
|
public const int CurrentCastSpellActionId = 0x1B84;
|
||||||
|
public const int CurrentCastTargetActorId = 0x1B90;
|
||||||
|
public const int CurrentCastTime = 0x1BB4;
|
||||||
|
public const int TotalCastTime = 0x1BB8;
|
||||||
|
// End BattleChara 0x2C00
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,85 +1,124 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Resolvers;
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using Dalamud.Game.ClientState.Structs;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents the base for non-static entities.
|
/// This class represents the base for non-static entities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Chara : Actor
|
public unsafe class Chara : Actor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Chara"/> class.
|
/// Initializes a new instance of the <see cref="Chara"/> class.
|
||||||
/// This represents a non-static entity.
|
/// This represents a non-static entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal Chara(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
: base(address, actorStruct, dalamud)
|
internal Chara(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the level of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public byte Level => this.ActorStruct.Level;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ClassJob of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public ClassJob ClassJob => new(this.ActorStruct.ClassJob, this.Dalamud);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current HP of this Chara.
|
/// Gets the current HP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentHp => this.ActorStruct.CurrentHp;
|
public uint CurrentHp => *(uint*)(this.Address + ActorOffsets.CurrentHp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum HP of this Chara.
|
/// Gets the maximum HP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxHp => this.ActorStruct.MaxHp;
|
public uint MaxHp => *(uint*)(this.Address + ActorOffsets.MaxHp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current MP of this Chara.
|
/// Gets the current MP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentMp => this.ActorStruct.CurrentMp;
|
public uint CurrentMp => *(uint*)(this.Address + ActorOffsets.CurrentMp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum MP of this Chara.
|
/// Gets the maximum MP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxMp => this.ActorStruct.MaxMp;
|
public uint MaxMp => *(uint*)(this.Address + ActorOffsets.MaxMp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current GP of this Chara.
|
/// Gets the current GP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentGp => this.ActorStruct.CurrentGp;
|
public uint CurrentGp => *(uint*)(this.Address + ActorOffsets.CurrentGp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum GP of this Chara.
|
/// Gets the maximum GP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxGp => this.ActorStruct.MaxGp;
|
public uint MaxGp => *(uint*)(this.Address + ActorOffsets.MaxGp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current CP of this Chara.
|
/// Gets the current CP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentCp => this.ActorStruct.CurrentCp;
|
public uint CurrentCp => *(uint*)(this.Address + ActorOffsets.CurrentCp);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the maximum CP of this Chara.
|
/// Gets the maximum CP of this Chara.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int MaxCp => this.ActorStruct.MaxCp;
|
public uint MaxCp => *(uint*)(this.Address + ActorOffsets.MaxCp);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ClassJob of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public ClassJobResolver ClassJob => new(*(byte*)(this.Address + ActorOffsets.ClassJob), this.Dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public byte Level => *(byte*)(this.Address + ActorOffsets.Level);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a byte array describing the visual appearance of this Chara.
|
/// Gets a byte array describing the visual appearance of this Chara.
|
||||||
/// Indexed by <see cref="CustomizeIndex"/>.
|
/// Indexed by <see cref="CustomizeIndex"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[] Customize => this.ActorStruct.Customize;
|
public byte[] Customize => MemoryHelper.Read<byte>(this.Address + ActorOffsets.Customize, 28);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets status Effects.
|
/// Gets the status flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public StatusFlags StatusFlags => this.ActorStruct.StatusFlags;
|
public StatusFlags StatusFlags => *(StatusFlags*)(this.Address + ActorOffsets.StatusFlags);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current status effects.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This copies every time it is invoked, so make sure to only grab it once.
|
||||||
|
/// </remarks>
|
||||||
|
public StatusEffect[] StatusEffects => MemoryHelper.Read<StatusEffect>(this.Address + ActorOffsets.UIStatusEffects, 20, true);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the actor is currently casting.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCasting => *(int*)(this.Address + ActorOffsets.IsCasting) > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the actor is currently casting (again?).
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCasting2 => *(int*)(this.Address + ActorOffsets.IsCasting2) > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the spell action ID currently being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentCastSpellActionId => *(uint*)(this.Address + ActorOffsets.CurrentCastSpellActionId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor ID of the target currently being cast at by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentCastTargetActorId => *(uint*)(this.Address + ActorOffsets.CurrentCastTargetActorId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current casting time of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public float CurrentCastTime => *(float*)(this.Address + ActorOffsets.CurrentCastTime);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total casting time of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public float TotalCastTime => *(float*)(this.Address + ActorOffsets.TotalCastTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This enum describes the indices of the Customize array.
|
/// This enum describes the indices of the Customize array.
|
||||||
|
|
@ -5,33 +5,27 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a battle NPC.
|
/// This class represents a battle NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BattleNpc : Npc
|
public unsafe class BattleNpc : Npc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
||||||
/// Set up a new BattleNpc with the provided memory representation.
|
/// Set up a new BattleNpc with the provided memory representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal BattleNpc(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
: base(address, actorStruct, dalamud)
|
internal BattleNpc(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the BattleNpc <see cref="BattleNpcSubKind" /> of this BattleNpc.
|
/// Gets the BattleNpc <see cref="BattleNpcSubKind" /> of this BattleNpc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BattleNpcSubKind BattleNpcKind => (BattleNpcSubKind)this.ActorStruct.SubKind;
|
public BattleNpcSubKind BattleNpcKind => *(BattleNpcSubKind*)(this.Address + ActorOffsets.SubKind);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID of this BattleNpc's owner.
|
/// Gets the target of the Battle NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int OwnerId => this.ActorStruct.OwnerId;
|
public override uint TargetActorID => *(uint*)(this.Address + ActorOffsets.BattleNpcTargetActorId);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets target of the Battle NPC.
|
|
||||||
/// </summary>
|
|
||||||
public override int TargetActorID => this.ActorStruct.BattleNpcTargetActorId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,23 +5,22 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents an EventObj.
|
/// This class represents an EventObj.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EventObj : Actor
|
public unsafe class EventObj : Actor
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
||||||
/// This represents an Event Object.
|
/// Set up a new EventObj with the provided memory representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal EventObj(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
: base(address, actorStruct, dalamud)
|
internal EventObj(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data ID of the NPC linking to their respective game data.
|
/// Gets the event object ID of the linking to their respective game data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int DataId => this.ActorStruct.DataId;
|
public uint EventObjectId => *(uint*)(this.Address + ActorOffsets.DataId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,28 +5,27 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a NPC.
|
/// This class represents a NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Npc : Chara
|
public unsafe class Npc : Chara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Npc"/> class.
|
/// Initializes a new instance of the <see cref="Npc"/> class.
|
||||||
/// This represents a Non-playable Character.
|
/// Set up a new NPC with the provided memory representation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal Npc(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
: base(address, actorStruct, dalamud)
|
internal Npc(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data ID of the NPC linking to their respective game data.
|
/// Gets the data ID of the NPC linking to their assoicated BNpcBase data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int DataId => this.ActorStruct.DataId;
|
public uint BaseId => *(uint*)(this.Address + ActorOffsets.DataId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name ID of the NPC linking to their respective game data.
|
/// Gets the name ID of the NPC linking to their respective game data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int NameId => this.ActorStruct.NameId;
|
public uint NameId => *(uint*)(this.Address + ActorOffsets.NameId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enum describing possible entity kinds.
|
/// Enum describing possible entity kinds.
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Runtime.InteropServices;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
|
|
@ -7,26 +8,6 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PartyMember
|
public class PartyMember
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The name of the character.
|
|
||||||
/// </summary>
|
|
||||||
public string CharacterName;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unknown.
|
|
||||||
/// </summary>
|
|
||||||
public long Unknown;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The actor object that corresponds to this party member.
|
|
||||||
/// </summary>
|
|
||||||
public Actor Actor;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The kind or type of actor.
|
|
||||||
/// </summary>
|
|
||||||
public ObjectKind ObjectKind;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -34,9 +15,10 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
/// <param name="rawData">The interop data struct.</param>
|
/// <param name="rawData">The interop data struct.</param>
|
||||||
public PartyMember(ActorTable table, Structs.PartyMember rawData)
|
public PartyMember(ActorTable table, Structs.PartyMember rawData)
|
||||||
{
|
{
|
||||||
this.CharacterName = Marshal.PtrToStringAnsi(rawData.namePtr);
|
this.CharacterName = MemoryHelper.ReadSeString(rawData.namePtr);
|
||||||
this.Unknown = rawData.unknown;
|
this.Unknown = rawData.unknown;
|
||||||
this.Actor = null;
|
this.Actor = null;
|
||||||
|
|
||||||
for (var i = 0; i < table.Length; i++)
|
for (var i = 0; i < table.Length; i++)
|
||||||
{
|
{
|
||||||
if (table[i] != null && table[i].ActorId == rawData.actorId)
|
if (table[i] != null && table[i].ActorId == rawData.actorId)
|
||||||
|
|
@ -48,5 +30,25 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
|
|
||||||
this.ObjectKind = rawData.objectKind;
|
this.ObjectKind = rawData.objectKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of the character.
|
||||||
|
/// </summary>
|
||||||
|
public SeString CharacterName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets something unknown.
|
||||||
|
/// </summary>
|
||||||
|
public long Unknown { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor object that corresponds to this party member.
|
||||||
|
/// </summary>
|
||||||
|
public Actor Actor { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the kind or type of actor.
|
||||||
|
/// </summary>
|
||||||
|
public ObjectKind ObjectKind { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,45 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Resolvers;
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
using Dalamud.Game.ClientState.Structs;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a player character.
|
/// This class represents a player character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PlayerCharacter : Chara
|
public unsafe class PlayerCharacter : Chara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
||||||
/// This represents a player character.
|
/// This represents a player character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="actorStruct">The memory representation of the base actor.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
/// <param name="address">The address of this actor in memory.</param>
|
||||||
internal PlayerCharacter(IntPtr address, Structs.Actor actorStruct, Dalamud dalamud)
|
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
||||||
: base(address, actorStruct, dalamud)
|
internal PlayerCharacter(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
{
|
{
|
||||||
var companyTagBytes = new byte[5];
|
|
||||||
Marshal.Copy(this.Address + ActorOffsets.CompanyTag, companyTagBytes, 0, companyTagBytes.Length);
|
|
||||||
this.CompanyTag = Encoding.UTF8.GetString(companyTagBytes.TakeWhile(c => c != 0x0).ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current <see cref="World">world</see> of the character.
|
/// Gets the current <see cref="WorldResolver">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public World CurrentWorld => new(this.ActorStruct.CurrentWorld, this.Dalamud);
|
public WorldResolver CurrentWorld => new(*(ushort*)(this.Address + ActorOffsets.CurrentWorld), this.Dalamud);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home <see cref="World">world</see> of the character.
|
/// Gets the home <see cref="WorldResolver">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public World HomeWorld => new(this.ActorStruct.HomeWorld, this.Dalamud);
|
public WorldResolver HomeWorld => new(*(ushort*)(this.Address + ActorOffsets.HomeWorld), this.Dalamud);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Free Company tag of this player.
|
/// Gets the Free Company tag of this player.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CompanyTag { get; private set; }
|
public SeString CompanyTag => MemoryHelper.ReadSeString(this.Address + ActorOffsets.CompanyTag, 6);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target of the PlayerCharacter.
|
/// Gets the target actor ID of the PlayerCharacter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override int TargetActorID => this.ActorStruct.PlayerCharacterTargetActorId;
|
public override uint TargetActorID => *(uint*)(this.Address + ActorOffsets.PlayerCharacterTargetActorId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enum describing possible status flags.
|
/// Enum describing possible status flags.
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors;
|
using Dalamud.Game.ClientState.Actors;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
|
using Dalamud.Game.ClientState.Fates;
|
||||||
using Dalamud.Game.Internal;
|
using Dalamud.Game.Internal;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
|
@ -17,56 +18,6 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ClientState : INotifyPropertyChanged, IDisposable
|
public sealed class ClientState : INotifyPropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The table of all present actors.
|
|
||||||
/// </summary>
|
|
||||||
public readonly ActorTable Actors;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the language of the client.
|
|
||||||
/// </summary>
|
|
||||||
public readonly ClientLanguage ClientLanguage;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current Territory the player resides in.
|
|
||||||
/// </summary>
|
|
||||||
public ushort TerritoryType;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The class facilitating Job Gauge data access.
|
|
||||||
/// </summary>
|
|
||||||
public JobGauges JobGauges;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The class facilitating party list data access.
|
|
||||||
/// </summary>
|
|
||||||
public PartyList PartyList;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides access to the keypress state of keyboard keys in game.
|
|
||||||
/// </summary>
|
|
||||||
public KeyState KeyState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides access to the button state of gamepad buttons in game.
|
|
||||||
/// </summary>
|
|
||||||
public GamepadState GamepadState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Provides access to client conditions/player state. Allows you to check if a player is in a duty, mounted, etc.
|
|
||||||
/// </summary>
|
|
||||||
public Condition Condition;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The class facilitating target data access.
|
|
||||||
/// </summary>
|
|
||||||
public Targets Targets;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event that gets fired when the current Territory changes.
|
|
||||||
/// </summary>
|
|
||||||
public EventHandler<ushort> TerritoryChanged;
|
|
||||||
|
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
private readonly ClientStateAddressResolver address;
|
private readonly ClientStateAddressResolver address;
|
||||||
private readonly Hook<SetupTerritoryTypeDelegate> setupTerritoryTypeHook;
|
private readonly Hook<SetupTerritoryTypeDelegate> setupTerritoryTypeHook;
|
||||||
|
|
@ -92,6 +43,8 @@ namespace Dalamud.Game.ClientState
|
||||||
|
|
||||||
this.Actors = new ActorTable(dalamud, this.address);
|
this.Actors = new ActorTable(dalamud, this.address);
|
||||||
|
|
||||||
|
this.Fates = new FateTable(dalamud, this.address);
|
||||||
|
|
||||||
this.PartyList = new PartyList(dalamud, this.address);
|
this.PartyList = new PartyList(dalamud, this.address);
|
||||||
|
|
||||||
this.JobGauges = new JobGauges(this.address);
|
this.JobGauges = new JobGauges(this.address);
|
||||||
|
|
@ -122,6 +75,11 @@ namespace Dalamud.Game.ClientState
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
#pragma warning restore
|
#pragma warning restore
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that gets fired when the current Territory changes.
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<ushort> TerritoryChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that fires when a character is logging in.
|
/// Event that fires when a character is logging in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -137,22 +95,61 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler<ContentFinderCondition> CfPop;
|
public event EventHandler<ContentFinderCondition> CfPop;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the table of all present actors.
|
||||||
|
/// </summary>
|
||||||
|
public ActorTable Actors { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the table of all present fates.
|
||||||
|
/// </summary>
|
||||||
|
public FateTable Fates { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the language of the client.
|
||||||
|
/// </summary>
|
||||||
|
public ClientLanguage ClientLanguage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the class facilitating Job Gauge data access.
|
||||||
|
/// </summary>
|
||||||
|
public JobGauges JobGauges { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the class facilitating party list data access.
|
||||||
|
/// </summary>
|
||||||
|
public PartyList PartyList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets access to the keypress state of keyboard keys in game.
|
||||||
|
/// </summary>
|
||||||
|
public KeyState KeyState { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets access to the button state of gamepad buttons in game.
|
||||||
|
/// </summary>
|
||||||
|
public GamepadState GamepadState { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets access to client conditions/player state. Allows you to check if a player is in a duty, mounted, etc.
|
||||||
|
/// </summary>
|
||||||
|
public Condition Condition { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the class facilitating target data access.
|
||||||
|
/// </summary>
|
||||||
|
public Targets Targets { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current Territory the player resides in.
|
||||||
|
/// </summary>
|
||||||
|
public ushort TerritoryType { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the local player character, if one is present.
|
/// Gets the local player character, if one is present.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
public PlayerCharacter LocalPlayer
|
public PlayerCharacter LocalPlayer => this.Actors[0] as PlayerCharacter;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var actor = this.Actors[0];
|
|
||||||
|
|
||||||
if (actor is PlayerCharacter pc)
|
|
||||||
return pc;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content ID of the local character.
|
/// Gets the content ID of the local character.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Game.Internal;
|
using Dalamud.Game.Internal;
|
||||||
|
|
||||||
|
|
@ -16,6 +17,14 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr ActorTable { get; private set; }
|
public IntPtr ActorTable { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the fate table pointer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a static address to a pointer, not the address of the table itself.
|
||||||
|
/// </remarks>
|
||||||
|
public IntPtr FateTablePtr { get; private set; }
|
||||||
|
|
||||||
// public IntPtr ViewportActorTable { get; private set; }
|
// public IntPtr ViewportActorTable { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -50,9 +59,6 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr SetupTerritoryType { get; private set; }
|
public IntPtr SetupTerritoryType { get; private set; }
|
||||||
|
|
||||||
// public IntPtr SomeActorTableAccess { get; private set; }
|
|
||||||
// public IntPtr PartyListUpdate { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the method which polls the gamepads for data.
|
/// Gets the address of the method which polls the gamepads for data.
|
||||||
/// Called every frame, even when `Enable Gamepad` is off in the settings.
|
/// Called every frame, even when `Enable Gamepad` is off in the settings.
|
||||||
|
|
@ -68,14 +74,18 @@ namespace Dalamud.Game.ClientState
|
||||||
// We don't need those anymore, but maybe someone else will - let's leave them here for good measure
|
// We don't need those anymore, but maybe someone else will - let's leave them here for good measure
|
||||||
// ViewportActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148;
|
// ViewportActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 85 ED", 0) + 0x148;
|
||||||
// SomeActorTableAccess = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 55 A0 48 8D 8E ?? ?? ?? ??");
|
// SomeActorTableAccess = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 55 A0 48 8D 8E ?? ?? ?? ??");
|
||||||
|
|
||||||
this.ActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 44 0F B6 83");
|
this.ActorTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 44 0F B6 83");
|
||||||
|
|
||||||
|
this.FateTablePtr = sig.GetStaticAddressFromSig("48 8B 15 ?? ?? ?? ?? 48 8B F9 44 0F B7 41 ??");
|
||||||
|
|
||||||
this.LocalContentId = sig.GetStaticAddressFromSig("48 0F 44 05 ?? ?? ?? ?? 48 39 07");
|
this.LocalContentId = sig.GetStaticAddressFromSig("48 0F 44 05 ?? ?? ?? ?? 48 39 07");
|
||||||
this.JobGaugeData = sig.GetStaticAddressFromSig("E8 ?? ?? ?? ?? FF C6 48 8D 5B 0C", 0xB9) + 0x10;
|
this.JobGaugeData = sig.GetStaticAddressFromSig("E8 ?? ?? ?? ?? FF C6 48 8D 5B 0C", 0xB9) + 0x10;
|
||||||
|
|
||||||
this.SetupTerritoryType = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 66 89 91 ?? ?? ?? ??");
|
this.SetupTerritoryType = sig.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B F9 66 89 91 ?? ?? ?? ??");
|
||||||
|
|
||||||
// This resolves to a fixed offset only, without the base address added in, so GetStaticAddressFromSig() can't be used
|
// This resolves to a fixed offset only, without the base address added in,
|
||||||
|
// so GetStaticAddressFromSig() can't be used. lea rcx, ds:1DB9F74h[rax*4]
|
||||||
this.KeyboardState = sig.ScanText("48 8D 0C 85 ?? ?? ?? ?? 8B 04 31 85 C2 0F 85") + 0x4;
|
this.KeyboardState = sig.ScanText("48 8D 0C 85 ?? ?? ?? ?? 8B 04 31 85 C2 0F 85") + 0x4;
|
||||||
|
|
||||||
// PartyListUpdate = sig.ScanText("E8 ?? ?? ?? ?? 49 8B D7 4C 8D 86 ?? ?? ?? ??");
|
// PartyListUpdate = sig.ScanText("E8 ?? ?? ?? ?? 49 8B D7 4C 8D 86 ?? ?? ?? ??");
|
||||||
|
|
|
||||||
178
Dalamud/Game/ClientState/Fates/FateTable.cs
Normal file
178
Dalamud/Game/ClientState/Fates/FateTable.cs
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Fates.Types;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Fates
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the currently available Fate events.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class FateTable
|
||||||
|
{
|
||||||
|
// If the pointer at this offset is 0, do not scan the table
|
||||||
|
private const int CheckPtrOffset = 0x80;
|
||||||
|
private const int FirstPtrOffset = 0x90;
|
||||||
|
private const int LastPtrOffset = 0x98;
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="FateTable"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
/// <param name="addressResolver">Client state address resolver.</param>
|
||||||
|
internal FateTable(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.address = addressResolver;
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
|
||||||
|
Log.Verbose($"Fate table address 0x{this.address.FateTablePtr.ToInt64():X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of currently active Fates.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe int Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var fateTable = this.FateTableAddress;
|
||||||
|
if (fateTable == IntPtr.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var check = *(long*)(fateTable + CheckPtrOffset);
|
||||||
|
if (check == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var start = *(long*)(fateTable + FirstPtrOffset);
|
||||||
|
var end = *(long*)(fateTable + LastPtrOffset);
|
||||||
|
if (start == 0 || end == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (int)((end - start) / 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe IntPtr FateTableAddress
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this.address.FateTablePtr == IntPtr.Zero)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return *(IntPtr*)this.address.FateTablePtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an actor at the specified spawn index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Spawn index.</param>
|
||||||
|
/// <returns>A <see cref="Fate"/> at the specified spawn index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public Fate this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var address = this.GetFateAddress(index);
|
||||||
|
return this[address];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a Fate at the specified address.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The Fate address.</param>
|
||||||
|
/// <returns>A <see cref="Fate"/> at the specified address.</returns>
|
||||||
|
public Fate this[IntPtr address]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return this.CreateFateReference(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the Fate at the specified index of the fate table.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the Fate.</param>
|
||||||
|
/// <returns>The memory address of the Fate.</returns>
|
||||||
|
public unsafe IntPtr GetFateAddress(int index)
|
||||||
|
{
|
||||||
|
if (index >= this.Length)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
var fateTable = this.FateTableAddress;
|
||||||
|
if (fateTable == IntPtr.Zero)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
var firstFate = *(IntPtr*)(fateTable + FirstPtrOffset);
|
||||||
|
return *(IntPtr*)(firstFate + (8 * index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to a FFXIV actor.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">The offset of the actor in memory.</param>
|
||||||
|
/// <returns><see cref="Fate"/> object containing requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
internal unsafe Fate CreateFateReference(IntPtr offset)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (offset == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new Fate(offset, this.dalamud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the currently available Fate events.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class FateTable : IReadOnlyCollection<Fate>, ICollection
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IReadOnlyCollection<Fate>.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int ICollection.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
bool ICollection.IsSynchronized => false;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerator<Fate> GetEnumerator()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.Length; i++)
|
||||||
|
{
|
||||||
|
yield return this[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
void ICollection.CopyTo(Array array, int index)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.Length; i++)
|
||||||
|
{
|
||||||
|
array.SetValue(this[i], index);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
138
Dalamud/Game/ClientState/Fates/Types/Fate.cs
Normal file
138
Dalamud/Game/ClientState/Fates/Types/Fate.cs
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Fates.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents an FFXIV Fate.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe partial class Fate : IEquatable<Fate>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Fate"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of this fate in memory.</param>
|
||||||
|
/// <param name="dalamud">Dalamud instance.</param>
|
||||||
|
internal Fate(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.Address = address;
|
||||||
|
this.Dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of this Fate in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets Dalamud itself.
|
||||||
|
/// </summary>
|
||||||
|
private protected Dalamud Dalamud { get; }
|
||||||
|
|
||||||
|
public static bool operator ==(Fate fate1, Fate fate2)
|
||||||
|
{
|
||||||
|
if (fate1 is null || fate2 is null)
|
||||||
|
return Equals(fate1, fate2);
|
||||||
|
|
||||||
|
return fate1.Equals(fate2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Fate fate1, Fate fate2) => !(fate1 == fate2);
|
||||||
|
|
||||||
|
/// <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 static bool IsValid(Fate fate)
|
||||||
|
{
|
||||||
|
if (fate == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (fate.Dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this actor is still valid in memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public bool IsValid() => IsValid(this);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
bool IEquatable<Fate>.Equals(Fate other) => this.FateId == other?.FateId;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object obj) => ((IEquatable<Fate>)this).Equals(obj as Fate);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode() => this.FateId.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents an FFXIV Fate.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe partial class Fate
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Fate ID of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
public ushort FateId => *(ushort*)(this.Address + FateOffsets.FateId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets game data linked to this Fate.
|
||||||
|
/// </summary>
|
||||||
|
public Lumina.Excel.GeneratedSheets.Fate GameData => this.Dalamud.Data.GetExcelSheet<Lumina.Excel.GeneratedSheets.Fate>().GetRow(this.FateId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time this <see cref="Fate"/> started.
|
||||||
|
/// </summary>
|
||||||
|
public int StartTimeEpoch => *(int*)(this.Address + FateOffsets.StartTimeEpoch);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets how long this <see cref="Fate"/> will run.
|
||||||
|
/// </summary>
|
||||||
|
public short Duration => *(short*)(this.Address + FateOffsets.Duration);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the remaining time in seconds for this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
public long TimeRemaining => this.StartTimeEpoch + this.Duration - DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the displayname of this <see cref="Fate" />.
|
||||||
|
/// </summary>
|
||||||
|
public SeString Name => MemoryHelper.ReadSeString((Utf8String*)(this.Address + FateOffsets.Name));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the state of this <see cref="Fate"/> (Running, Ended, Failed, Preparation, WaitingForEnd).
|
||||||
|
/// </summary>
|
||||||
|
public FateState State => *(FateState*)(this.Address + FateOffsets.State);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the progress amount of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
public byte Progress => *(byte*)(this.Address + FateOffsets.Progress);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
public byte Level => *(byte*)(this.Address + FateOffsets.Level);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of this <see cref="Fate"/>.
|
||||||
|
/// </summary>
|
||||||
|
public Position3 Position => *(Position3*)(this.Address + FateOffsets.Position);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the territory this <see cref="Fate"/> is located in.
|
||||||
|
/// </summary>
|
||||||
|
public TerritoryTypeResolver TerritoryType => new(*(ushort*)(this.Address + FateOffsets.Territory), this.Dalamud);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Dalamud/Game/ClientState/Fates/Types/FateOffsets.cs
Normal file
21
Dalamud/Game/ClientState/Fates/Types/FateOffsets.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Fates.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Memory offsets for the <see cref="Fate"/> type.
|
||||||
|
/// </summary>
|
||||||
|
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.")]
|
||||||
|
public static class FateOffsets
|
||||||
|
{
|
||||||
|
public const int FateId = 0x18;
|
||||||
|
public const int StartTimeEpoch = 0x20;
|
||||||
|
public const int Duration = 0x28;
|
||||||
|
public const int Name = 0xC0;
|
||||||
|
public const int State = 0x3AC;
|
||||||
|
public const int Progress = 0x3B8;
|
||||||
|
public const int Level = 0x3F9;
|
||||||
|
public const int Position = 0x450;
|
||||||
|
public const int Territory = 0x74E;
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Dalamud/Game/ClientState/Fates/Types/FateState.cs
Normal file
33
Dalamud/Game/ClientState/Fates/Types/FateState.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
namespace Dalamud.Game.ClientState.Fates.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This represents the state of a single Fate.
|
||||||
|
/// </summary>
|
||||||
|
public enum FateState : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Fate is active.
|
||||||
|
/// </summary>
|
||||||
|
Running = 0x02,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Fate has ended.
|
||||||
|
/// </summary>
|
||||||
|
Ended = 0x04,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The player failed the Fate.
|
||||||
|
/// </summary>
|
||||||
|
Failed = 0x05,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Fate is preparing to run.
|
||||||
|
/// </summary>
|
||||||
|
Preparation = 0x07,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Fate is preparing to end.
|
||||||
|
/// </summary>
|
||||||
|
WaitingForEnd = 0x08,
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Dalamud/Game/ClientState/Resolvers/BaseResolver{T}.cs
Normal file
34
Dalamud/Game/ClientState/Resolvers/BaseResolver{T}.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
using Lumina.Excel;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Resolvers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This object represents a class or job.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of Lumina sheet to resolve.</typeparam>
|
||||||
|
public class BaseResolver<T> where T : ExcelRow
|
||||||
|
{
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BaseResolver{T}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the classJob.</param>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal BaseResolver(uint id, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID to be resolved.
|
||||||
|
/// </summary>
|
||||||
|
public uint Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets GameData linked to this excel row.
|
||||||
|
/// </summary>
|
||||||
|
public T GameData => this.dalamud.Data.GetExcelSheet<T>().GetRow(this.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Dalamud/Game/ClientState/Resolvers/ClassJobResolver.cs
Normal file
19
Dalamud/Game/ClientState/Resolvers/ClassJobResolver.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace Dalamud.Game.ClientState.Resolvers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This object represents a class or job.
|
||||||
|
/// </summary>
|
||||||
|
public class ClassJobResolver : BaseResolver<Lumina.Excel.GeneratedSheets.ClassJob>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ClassJobResolver"/> class.
|
||||||
|
/// Set up the ClassJob resolver with the provided ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the classJob.</param>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal ClassJobResolver(ushort id, Dalamud dalamud)
|
||||||
|
: base(id, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Dalamud/Game/ClientState/Resolvers/FateResolver.cs
Normal file
19
Dalamud/Game/ClientState/Resolvers/FateResolver.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace Dalamud.Game.ClientState.Resolvers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This object represents a Fate a character can participate in.
|
||||||
|
/// </summary>
|
||||||
|
public class FateResolver : BaseResolver<Lumina.Excel.GeneratedSheets.Fate>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="FateResolver"/> class.
|
||||||
|
/// Set up the Fate resolver with the provided ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the Fate.</param>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal FateResolver(ushort id, Dalamud dalamud)
|
||||||
|
: base(id, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Dalamud/Game/ClientState/Resolvers/TerritoryTypeResolver.cs
Normal file
19
Dalamud/Game/ClientState/Resolvers/TerritoryTypeResolver.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace Dalamud.Game.ClientState.Resolvers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This object represents a territory a character can be in.
|
||||||
|
/// </summary>
|
||||||
|
public class TerritoryTypeResolver : BaseResolver<Lumina.Excel.GeneratedSheets.TerritoryType>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="TerritoryTypeResolver"/> class.
|
||||||
|
/// Set up the territory type resolver with the provided ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the territory type.</param>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal TerritoryTypeResolver(ushort id, Dalamud dalamud)
|
||||||
|
: base(id, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
Dalamud/Game/ClientState/Resolvers/WorldResolver.cs
Normal file
19
Dalamud/Game/ClientState/Resolvers/WorldResolver.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
namespace Dalamud.Game.ClientState.Resolvers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This object represents a world a character can reside on.
|
||||||
|
/// </summary>
|
||||||
|
public class WorldResolver : BaseResolver<Lumina.Excel.GeneratedSheets.World>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WorldResolver"/> class.
|
||||||
|
/// Set up the world resolver with the provided ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the world.</param>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal WorldResolver(ushort id, Dalamud dalamud)
|
||||||
|
: base(id, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,296 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Native memory representation of an FFXIV actor.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit, Pack = 2)]
|
|
||||||
public struct Actor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The actor name.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.Name)]
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
|
|
||||||
public byte[] Name;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The actor's internal id.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.ActorId)]
|
|
||||||
public int ActorId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The actor's data id.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.DataId)]
|
|
||||||
public int DataId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The actor's owner id. This is useful for pets, summons, and the like.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.OwnerId)]
|
|
||||||
public int OwnerId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The type or kind of actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.ObjectKind)]
|
|
||||||
public ObjectKind ObjectKind;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The sub-type or sub-kind of actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.SubKind)]
|
|
||||||
public byte SubKind;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the actor is friendly.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.IsFriendly)]
|
|
||||||
public bool IsFriendly;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The horizontal distance in game units from the player.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.YalmDistanceFromPlayerX)]
|
|
||||||
public byte YalmDistanceFromPlayerX;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The player target status.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This is some kind of enum.
|
|
||||||
/// </remarks>
|
|
||||||
[FieldOffset(ActorOffsets.PlayerTargetStatus)]
|
|
||||||
public byte PlayerTargetStatus;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The vertical distance in game units from the player.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.YalmDistanceFromPlayerY)]
|
|
||||||
public byte YalmDistanceFromPlayerY;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The (X,Z,Y) position of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.Position)]
|
|
||||||
public Position3 Position;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The rotation of the actor.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// The rotation is around the vertical axis (yaw), from -pi to pi radians.
|
|
||||||
/// </remarks>
|
|
||||||
[FieldOffset(ActorOffsets.Rotation)]
|
|
||||||
public float Rotation;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The hitbox radius of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.HitboxRadius)]
|
|
||||||
public float HitboxRadius;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current HP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentHp)]
|
|
||||||
public int CurrentHp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max HP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.MaxHp)]
|
|
||||||
public int MaxHp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current MP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentMp)]
|
|
||||||
public int CurrentMp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max MP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.MaxMp)]
|
|
||||||
public short MaxMp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current GP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentGp)]
|
|
||||||
public short CurrentGp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max GP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.MaxGp)]
|
|
||||||
public short MaxGp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current CP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentCp)]
|
|
||||||
public short CurrentCp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The max CP of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.MaxCp)]
|
|
||||||
public short MaxCp;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The class-job of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.ClassJob)]
|
|
||||||
public byte ClassJob;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The level of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.Level)]
|
|
||||||
public byte Level;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The (player character) actor ID being targeted by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.PlayerCharacterTargetActorId)]
|
|
||||||
public int PlayerCharacterTargetActorId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The customization byte/bitfield of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.Customize)]
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
|
|
||||||
public byte[] Customize;
|
|
||||||
|
|
||||||
// Normally pack=2 should work, but ByTVal or Injection breaks this.
|
|
||||||
// [FieldOffset(ActorOffsets.CompanyTag)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public string CompanyTag;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The (battle npc) actor ID being targeted by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.BattleNpcTargetActorId)]
|
|
||||||
public int BattleNpcTargetActorId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The name ID of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.NameId)]
|
|
||||||
public int NameId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current world ID of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentWorld)]
|
|
||||||
public ushort CurrentWorld;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The home world ID of the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.HomeWorld)]
|
|
||||||
public ushort HomeWorld;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the actor is currently casting.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.IsCasting)]
|
|
||||||
public bool IsCasting;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether the actor is currently casting (dup?).
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.IsCasting2)]
|
|
||||||
public bool IsCasting2;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The spell action ID currently being cast by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentCastSpellActionId)]
|
|
||||||
public uint CurrentCastSpellActionId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The actor ID of the target currently being cast at by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentCastTargetActorId)]
|
|
||||||
public uint CurrentCastTargetActorId;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The current casting time of the spell being cast by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.CurrentCastTime)]
|
|
||||||
public float CurrentCastTime;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The total casting time of the spell being cast by the actor.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.TotalCastTime)]
|
|
||||||
public float TotalCastTime;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Actor status flags.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.StatusFlags)]
|
|
||||||
public StatusFlags StatusFlags;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The array of status effects that the actor is currently affected by.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(ActorOffsets.UIStatusEffects)]
|
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
|
|
||||||
public StatusEffect[] UIStatusEffects;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Memory offsets for the <see cref="Actor"/> type.
|
|
||||||
/// </summary>
|
|
||||||
public static class ActorOffsets
|
|
||||||
{
|
|
||||||
// Reference https://github.com/FFXIVAPP/sharlayan-resources/blob/master/structures/5.4/x64.json for more
|
|
||||||
public const int Name = 48; // 0x0030
|
|
||||||
public const int ActorId = 116; // 0x0074
|
|
||||||
// public const int ??? = 120; // 0x0078 NPCID1
|
|
||||||
public const int DataId = 128; // 0x0080 NPCID2
|
|
||||||
public const int OwnerId = 132; // 0x0084
|
|
||||||
public const int ObjectKind = 140; // 0x008C Type
|
|
||||||
public const int SubKind = 141; // 0x008D
|
|
||||||
public const int IsFriendly = 142; // 0x008E
|
|
||||||
public const int YalmDistanceFromPlayerX = 144; // 0x0090
|
|
||||||
public const int PlayerTargetStatus = 145; // 0x0091
|
|
||||||
public const int YalmDistanceFromPlayerY = 146; // 0x0092 Distance
|
|
||||||
public const int Position = 160; // 0x00A0 (X,Z,Y)
|
|
||||||
public const int Rotation = 176; // 0x00B0 Heading
|
|
||||||
public const int HitboxRadius = 192; // 0x00C0
|
|
||||||
public const int CurrentHp = 452; // 0x01C4 HPCurrent
|
|
||||||
public const int MaxHp = 456; // 0x01C8 HPMax
|
|
||||||
public const int CurrentMp = 460; // 0x01CC MPCurrent
|
|
||||||
public const int MaxMp = 464; // 0x01D0 MPMax
|
|
||||||
public const int CurrentGp = 468; // 0x01D4 GPCurrent
|
|
||||||
public const int MaxGp = 470; // 0x01D6 GPMax
|
|
||||||
public const int CurrentCp = 472; // 0x01D8 CPCurrent
|
|
||||||
public const int MaxCp = 474; // 0x01DA CPMax
|
|
||||||
public const int ClassJob = 482; // 0x01E2 Job
|
|
||||||
public const int Level = 483; // 0x01E3 Level
|
|
||||||
public const int PlayerCharacterTargetActorId = 560; // 0x01F0 TargetID
|
|
||||||
|
|
||||||
public const int Customize = 0x1898; // Needs verification
|
|
||||||
public const int CompanyTag = 0x18B2;
|
|
||||||
public const int BattleNpcTargetActorId = 0x18D8; // Needs verification
|
|
||||||
public const int NameId = 0x1940; // Needs verification
|
|
||||||
public const int CurrentWorld = 0x195C;
|
|
||||||
public const int HomeWorld = 0x195E;
|
|
||||||
|
|
||||||
public const int IsCasting = 0x1B80;
|
|
||||||
public const int IsCasting2 = 0x1B82;
|
|
||||||
public const int CurrentCastSpellActionId = 0x1B84;
|
|
||||||
public const int CurrentCastTargetActorId = 0x1B90;
|
|
||||||
public const int CurrentCastTime = 0x1BB4;
|
|
||||||
public const int TotalCastTime = 0x1BB8;
|
|
||||||
public const int StatusFlags = 0x19A0;
|
|
||||||
public const int UIStatusEffects = 0x19F8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs
|
namespace Dalamud.Game.ClientState.Structs
|
||||||
{
|
{
|
||||||
|
|
@ -40,25 +40,37 @@ namespace Dalamud.Game.ClientState.Structs
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raw input, set the whole time while a button is held. See <see cref="GamepadButtons"/> for the mapping.
|
/// Raw input, set the whole time while a button is held. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a bitfield.
|
||||||
|
/// </remarks>
|
||||||
[FieldOffset(0x98)]
|
[FieldOffset(0x98)]
|
||||||
public ushort ButtonsRaw; // bitfield
|
public ushort ButtonsRaw;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Button pressed, set once when the button is pressed. See <see cref="GamepadButtons"/> for the mapping.
|
/// Button pressed, set once when the button is pressed. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a bitfield.
|
||||||
|
/// </remarks>
|
||||||
[FieldOffset(0x9C)]
|
[FieldOffset(0x9C)]
|
||||||
public ushort ButtonsPressed; // bitfield
|
public ushort ButtonsPressed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Button released input, set once right after the button is not hold anymore. See <see cref="GamepadButtons"/> for the mapping.
|
/// Button released input, set once right after the button is not hold anymore. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a bitfield.
|
||||||
|
/// </remarks>
|
||||||
[FieldOffset(0xA0)]
|
[FieldOffset(0xA0)]
|
||||||
public ushort ButtonsReleased; // bitfield
|
public ushort ButtonsReleased;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Repeatedly emits the held button input in fixed intervals. See <see cref="GamepadButtons"/> for the mapping.
|
/// Repeatedly emits the held button input in fixed intervals. See <see cref="GamepadButtons"/> for the mapping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a bitfield.
|
||||||
|
/// </remarks>
|
||||||
[FieldOffset(0xA4)]
|
[FieldOffset(0xA4)]
|
||||||
public ushort ButtonsRepeat; // bitfield
|
public ushort ButtonsRepeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,35 +8,43 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct BLMGauge
|
public struct BLMGauge
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the time until the next Polyglot stack in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public short TimeUntilNextPolyglot; // enochian timer
|
private short timeUntilNextPolyglot; // enochian timer
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time remaining for Astral Fire or Umbral Ice in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(2)]
|
[FieldOffset(2)]
|
||||||
public short ElementTimeRemaining; // umbral ice and astral fire timer
|
private short elementTimeRemaining; // umbral ice and astral fire timer
|
||||||
|
|
||||||
[FieldOffset(4)]
|
[FieldOffset(4)]
|
||||||
private byte elementStance; // umbral ice or astral fire
|
private byte elementStance; // umbral ice or astral fire
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of Umbral Hearts remaining.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(5)]
|
[FieldOffset(5)]
|
||||||
public byte NumUmbralHearts;
|
private byte numUmbralHearts;
|
||||||
|
|
||||||
|
[FieldOffset(6)]
|
||||||
|
private byte numPolyglotStacks;
|
||||||
|
|
||||||
|
[FieldOffset(7)]
|
||||||
|
private byte enochianState;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time until the next Polyglot stack in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short TimeUntilNextPolyglot => this.timeUntilNextPolyglot;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for Astral Fire or Umbral Ice in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short ElementTimeRemaining => this.elementTimeRemaining;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of Polyglot stacks remaining.
|
/// Gets the number of Polyglot stacks remaining.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(6)]
|
public byte NumPolyglotStacks => this.numPolyglotStacks;
|
||||||
public byte NumPolyglotStacks;
|
|
||||||
|
|
||||||
[FieldOffset(7)]
|
/// <summary>
|
||||||
private byte enochianState;
|
/// Gets the number of Umbral Hearts remaining.
|
||||||
|
/// </summary>
|
||||||
|
public byte NumUmbralHearts => this.numUmbralHearts;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if the player is in Umbral Ice.
|
/// Gets if the player is in Umbral Ice.
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,36 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct BRDGauge
|
public struct BRDGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private short songTimer;
|
||||||
|
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private byte numSongStacks;
|
||||||
|
|
||||||
|
[FieldOffset(3)]
|
||||||
|
private byte soulVoiceValue;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private CurrentSong activeSong;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current song timer in milliseconds.
|
/// Gets the current song timer in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public short SongTimer => this.songTimer;
|
||||||
public short SongTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of stacks for the current song.
|
/// Gets the number of stacks for the current song.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public byte NumSongStacks => this.numSongStacks;
|
||||||
public byte NumSongStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of Soul Voice accumulated.
|
/// Gets the amount of Soul Voice accumulated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(3)]
|
public byte SoulVoiceValue => this.soulVoiceValue;
|
||||||
public byte SoulVoiceValue;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type of song that is active.
|
/// Gets the type of song that is active.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public CurrentSong ActiveSong => this.activeSong;
|
||||||
public CurrentSong ActiveSong;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,32 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public unsafe struct DNCGauge
|
public unsafe struct DNCGauge
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of feathers available.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public byte NumFeathers;
|
private byte numFeathers;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Espirit available.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(1)]
|
[FieldOffset(1)]
|
||||||
public byte Esprit;
|
private byte esprit;
|
||||||
|
|
||||||
[FieldOffset(2)]
|
[FieldOffset(2)]
|
||||||
private fixed byte stepOrder[4];
|
private fixed byte stepOrder[4];
|
||||||
|
|
||||||
|
[FieldOffset(6)]
|
||||||
|
private byte numCompleteSteps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of feathers available.
|
||||||
|
/// </summary>
|
||||||
|
public byte NumFeathers => this.numFeathers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Espirit available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Esprit => this.esprit;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of steps completed for the current dance.
|
/// Gets the number of steps completed for the current dance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(6)]
|
public byte NumCompleteSteps => this.numCompleteSteps;
|
||||||
public byte NumCompleteSteps;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the next step in the current dance.
|
/// Gets the next step in the current dance.
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,28 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct DRGGauge
|
public struct DRGGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private short botdTimer;
|
||||||
|
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private BOTDState botdState;
|
||||||
|
|
||||||
|
[FieldOffset(3)]
|
||||||
|
private byte eyeCount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time remaining for Blood of the Dragon in milliseconds.
|
/// Gets the time remaining for Blood of the Dragon in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public short BOTDTimer => this.botdTimer;
|
||||||
public short BOTDTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current state of Blood of the Dragon.
|
/// Gets the current state of Blood of the Dragon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public BOTDState BOTDState => this.botdState;
|
||||||
public BOTDState BOTDState;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the count of eyes opened during Blood of the Dragon.
|
/// Gets the count of eyes opened during Blood of the Dragon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(3)]
|
public byte EyeCount => this.eyeCount;
|
||||||
public byte EyeCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,32 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct DRKGauge
|
public struct DRKGauge
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of blood accumulated.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public byte Blood;
|
private byte blood;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Darkside time remaining in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
[FieldOffset(2)]
|
[FieldOffset(2)]
|
||||||
public ushort DarksideTimeRemaining;
|
private ushort darksideTimeRemaining;
|
||||||
|
|
||||||
[FieldOffset(4)]
|
[FieldOffset(4)]
|
||||||
private byte darkArtsState;
|
private byte darkArtsState;
|
||||||
|
|
||||||
|
[FieldOffset(6)]
|
||||||
|
private ushort shadowTimeRemaining;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of blood accumulated.
|
||||||
|
/// </summary>
|
||||||
|
public byte Blood => this.blood;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Darkside time remaining in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public ushort DarksideTimeRemaining => this.darksideTimeRemaining;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Shadow time remaining in milliseconds.
|
/// Gets the Shadow time remaining in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(6)]
|
public ushort ShadowTimeRemaining => this.shadowTimeRemaining;
|
||||||
public ushort ShadowTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if the player has Dark Arts or not.
|
/// Gets if the player has Dark Arts or not.
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,28 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct GNBGauge
|
public struct GNBGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private byte numAmmo;
|
||||||
|
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private short maxTimerDuration;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte ammoComboStepNumber;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of ammo available.
|
/// Gets the amount of ammo available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public byte NumAmmo => this.numAmmo;
|
||||||
public byte NumAmmo;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the max combo time of the Gnashing Fang combo.
|
/// Gets the max combo time of the Gnashing Fang combo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public short MaxTimerDuration => this.maxTimerDuration;
|
||||||
public short MaxTimerDuration;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current step of the Gnashing Fang combo.
|
/// Gets the current step of the Gnashing Fang combo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte AmmoComboStepNumber => this.ammoComboStepNumber;
|
||||||
public byte AmmoComboStepNumber;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,38 +8,48 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct MCHGauge
|
public struct MCHGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private short overheatTimeRemaining;
|
||||||
|
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private short robotTimeRemaining;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte heat;
|
||||||
|
|
||||||
|
[FieldOffset(5)]
|
||||||
|
private byte battery;
|
||||||
|
|
||||||
|
[FieldOffset(6)]
|
||||||
|
private byte lastRobotBatteryPower;
|
||||||
|
|
||||||
|
[FieldOffset(7)]
|
||||||
|
private byte timerActive;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time time remaining for Overheat in milliseconds.
|
/// Gets the time time remaining for Overheat in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public short OverheatTimeRemaining => this.overheatTimeRemaining;
|
||||||
public short OverheatTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time remaining for the Rook or Queen in milliseconds.
|
/// Gets the time remaining for the Rook or Queen in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public short RobotTimeRemaining => this.robotTimeRemaining;
|
||||||
public short RobotTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current Heat level.
|
/// Gets the current Heat level.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte Heat => this.heat;
|
||||||
public byte Heat;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current Battery level.
|
/// Gets the current Battery level.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(5)]
|
public byte Battery => this.battery;
|
||||||
public byte Battery;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the battery level of the last Robot.
|
/// Gets the battery level of the last Robot.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(6)]
|
public byte LastRobotBatteryPower => this.lastRobotBatteryPower;
|
||||||
public byte LastRobotBatteryPower;
|
|
||||||
|
|
||||||
[FieldOffset(7)]
|
|
||||||
private byte timerActive;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if the player is currently Overheated.
|
/// Gets if the player is currently Overheated.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
|
|
@ -9,35 +8,12 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct MNKGauge
|
public struct MNKGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private byte numChakra;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of Chakra available.
|
/// Gets the number of Chakra available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public byte NumChakra => this.numChakra;
|
||||||
public byte NumChakra;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Greased Lightning timer in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("GL has been removed from the game")]
|
|
||||||
[FieldOffset(0)]
|
|
||||||
public byte GLTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Greased Lightning stacks.
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("GL has been removed from the game")]
|
|
||||||
[FieldOffset(2)]
|
|
||||||
public byte NumGLStacks;
|
|
||||||
|
|
||||||
[Obsolete("GL has been removed from the game")]
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte glTimerFreezeState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the Greased Lightning timer has been frozen.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>><c>true</c> or <c>false</c>.</returns>
|
|
||||||
[Obsolete("GL has been removed from the game")]
|
|
||||||
public bool IsGLTimerFroze() => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,30 +9,28 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct NINGauge
|
public struct NINGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private int hutonTimeLeft;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte ninki;
|
||||||
|
|
||||||
|
[FieldOffset(5)]
|
||||||
|
private byte numHutonManualCasts;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time left on Huton in milliseconds.
|
/// Gets the time left on Huton in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
// TODO: Probably a short, confirm.
|
public int HutonTimeLeft => this.hutonTimeLeft;
|
||||||
[FieldOffset(0)]
|
|
||||||
public int HutonTimeLeft;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of Ninki available.
|
/// Gets the amount of Ninki available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte Ninki => this.ninki;
|
||||||
public byte Ninki;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Obsolete.
|
|
||||||
/// </summary>
|
|
||||||
[Obsolete("Does not appear to be used")]
|
|
||||||
[FieldOffset(4)]
|
|
||||||
public byte TCJMudrasUsed;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of times Huton has been cast manually.
|
/// Gets the number of times Huton has been cast manually.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(5)]
|
public byte NumHutonManualCasts => this.numHutonManualCasts;
|
||||||
public byte NumHutonManualCasts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct PLDGauge
|
public struct PLDGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private byte gaugeAmount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current level of the Oath gauge.
|
/// Gets the current level of the Oath gauge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public byte GaugeAmount => this.gaugeAmount;
|
||||||
public byte GaugeAmount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,20 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct RDMGauge
|
public struct RDMGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private byte whiteGauge;
|
||||||
|
|
||||||
|
[FieldOffset(1)]
|
||||||
|
private byte blackGauge;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of the White gauge.
|
/// Gets the level of the White gauge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public byte WhiteGauge => this.whiteGauge;
|
||||||
public byte WhiteGauge;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the level of the Black gauge.
|
/// Gets the level of the Black gauge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(1)]
|
public byte BlackGauge => this.blackGauge;
|
||||||
public byte BlackGauge;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,23 +8,29 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct SAMGauge
|
public struct SAMGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(3)]
|
||||||
|
private byte kenki;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte meditationStacks;
|
||||||
|
|
||||||
|
[FieldOffset(5)]
|
||||||
|
private Sen sen;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current amount of Kenki available.
|
/// Gets the current amount of Kenki available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(3)]
|
public byte Kenki => this.kenki;
|
||||||
public byte Kenki;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of Meditation stacks.
|
/// Gets the amount of Meditation stacks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte MeditationStacks => this.meditationStacks;
|
||||||
public byte MeditationStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the active Sen.
|
/// Gets the active Sen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(5)]
|
public Sen Sen => this.sen;
|
||||||
public Sen Sen;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if the Setsu Sen is active.
|
/// Gets if the Setsu Sen is active.
|
||||||
|
|
|
||||||
|
|
@ -8,28 +8,36 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct SCHGauge
|
public struct SCHGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private byte numAetherflowStacks;
|
||||||
|
|
||||||
|
[FieldOffset(3)]
|
||||||
|
private byte fairyGaugeAmount;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private short seraphTimer;
|
||||||
|
|
||||||
|
[FieldOffset(6)]
|
||||||
|
private DismissedFairy dismissedFairy;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of Aetherflow stacks available.
|
/// Gets the amount of Aetherflow stacks available.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public byte NumAetherflowStacks => this.numAetherflowStacks;
|
||||||
public byte NumAetherflowStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current level of the Fairy Gauge.
|
/// Gets the current level of the Fairy Gauge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(3)]
|
public byte FairyGaugeAmount => this.fairyGaugeAmount;
|
||||||
public byte FairyGaugeAmount;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the Seraph time remaining in milliseconds.
|
/// Gets the Seraph time remaining in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public short SeraphTimer => this.seraphTimer;
|
||||||
public short SeraphTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the last dismissed fairy.
|
/// Gets the last dismissed fairy.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(6)]
|
public DismissedFairy DismissedFairy => this.dismissedFairy;
|
||||||
public DismissedFairy DismissedFairy;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,30 +8,38 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct SMNGauge
|
public struct SMNGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private short timerRemaining;
|
||||||
|
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private SummonPet returnSummon;
|
||||||
|
|
||||||
|
[FieldOffset(3)]
|
||||||
|
private PetGlam returnSummonGlam;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte numStacks;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time remaining for the current summon.
|
/// Gets the time remaining for the current summon.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public short TimerRemaining => this.timerRemaining;
|
||||||
public short TimerRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the summon that will return after the current summon expires.
|
/// Gets the summon that will return after the current summon expires.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public SummonPet ReturnSummon => this.returnSummon;
|
||||||
public SummonPet ReturnSummon;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(3)]
|
public PetGlam ReturnSummonGlam => this.returnSummonGlam;
|
||||||
public PetGlam ReturnSummonGlam;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current stacks.
|
/// Gets the current stacks.
|
||||||
/// Use the summon accessors instead.
|
/// Use the summon accessors instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte NumStacks => this.numStacks;
|
||||||
public byte NumStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets if Phoenix is ready to be summoned.
|
/// Gets if Phoenix is ready to be summoned.
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,12 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct WARGauge
|
public struct WARGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
private byte beastGaugeAmount;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the amount of wrath in the Beast gauge.
|
/// Gets the amount of wrath in the Beast gauge.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(0)]
|
public byte BeastGaugeAmount => this.beastGaugeAmount;
|
||||||
public byte BeastGaugeAmount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,28 @@ namespace Dalamud.Game.ClientState.Structs.JobGauge
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public struct WHMGauge
|
public struct WHMGauge
|
||||||
{
|
{
|
||||||
|
[FieldOffset(2)]
|
||||||
|
private short lilyTimer;
|
||||||
|
|
||||||
|
[FieldOffset(4)]
|
||||||
|
private byte numLilies;
|
||||||
|
|
||||||
|
[FieldOffset(5)]
|
||||||
|
private byte numBloodLily;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the time to next lily in milliseconds.
|
/// Gets the time to next lily in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(2)]
|
public short LilyTimer => this.lilyTimer;
|
||||||
public short LilyTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of Lilies.
|
/// Gets the number of Lilies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(4)]
|
public byte NumLilies => this.numLilies;
|
||||||
public byte NumLilies;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the number of times the blood lily has been nourished.
|
/// Gets the number of times the blood lily has been nourished.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[FieldOffset(5)]
|
public byte NumBloodLily => this.numBloodLily;
|
||||||
public byte NumBloodLily;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors;
|
using Dalamud.Game.ClientState.Actors.Types;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs
|
namespace Dalamud.Game.ClientState.Structs
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
namespace Dalamud.Game
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A game native equivalent of a Vector3.
|
/// A game native equivalent of a Vector3.
|
||||||
|
|
@ -37,10 +37,8 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
// <type>Offsets.cs
|
// <type>Offsets.cs
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:Static elements should appear before instance elements", Justification = "Offset classes goto the end of file.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:Static elements should appear before instance elements", Justification = "Offset classes goto the end of file.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group offset classes with the relevant class.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group offset classes with the relevant class.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group offset classes with the relevant class.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Structs.ActorOffsets")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group offset classes with the relevant class.", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.AddonOffsets")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group offset classes with the relevant class.", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.AddonOffsets")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.TargetOffsets")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Structs.ActorOffsets")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.AddonOffsets")]
|
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "Document the offset usage instead.", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.AddonOffsets")]
|
||||||
|
|
||||||
// Breaking api changes: these should be split into a PartyFinder subdirectory
|
// Breaking api changes: these should be split into a PartyFinder subdirectory
|
||||||
|
|
@ -57,33 +55,15 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "breaking api change", Scope = "member", Target = "~E:Dalamud.Game.Internal.Gui.PartyFinderGui.ReceiveListing")]
|
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "breaking api change", Scope = "member", Target = "~E:Dalamud.Game.Internal.Gui.PartyFinderGui.ReceiveListing")]
|
||||||
|
|
||||||
// Breaking api changes
|
// Breaking api changes
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Actors.Resolvers.ClassJob.Id")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Actors.Resolvers.World.Id")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Actors.Types.Actor.Address")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.BaseAddressResolver.DebugScannedValues")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.BaseAddressResolver.DebugScannedValues")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.Addon.Addon.Address")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.Addon.Addon.Address")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.Addon.Addon.addonStruct")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.Addon.Addon.addonStruct")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.GameGui.GetBaseUIObject")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Gui.GameGui.GetBaseUIObject")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.DataResolver")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.DataResolver")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.Actors")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.TerritoryType")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.TerritoryChanged")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.ClientLanguage")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.JobGauges")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.PartyList")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.KeyState")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.GamepadState")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.Condition")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.ClientState.Targets")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.Types.PartyMember")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Actors.Types.PartyMember")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Actors.Types.Actor.Address")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Structs.JobGauge.BLMGauge.NumUmbralHearts")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Structs.JobGauge.DNCGauge.NumCompleteSteps")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.ClientState.Structs.JobGauge.DRKGauge.ShadowTimeRemaining")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.START_BYTE")]
|
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.START_BYTE")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.END_BYTE")]
|
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Text.SeStringHandling.Payload.END_BYTE")]
|
||||||
[assembly: SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Unused, but eventually, maybe.", Scope = "member", Target = "~F:Dalamud.Game.ClientState.PartyList.address")]
|
[assembly: SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "Unused, but eventually, maybe.", Scope = "member", Target = "~F:Dalamud.Game.ClientState.PartyList.address")]
|
||||||
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "breaking api change", Scope = "member", Target = "~E:Dalamud.Game.ClientState.ClientState.CfPop")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:Static elements should appear before instance elements", Justification = "breaking api change, move to util", Scope = "type", Target = "~T:Dalamud.Game.Text.EnumExtensions")]
|
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:Static elements should appear before instance elements", Justification = "breaking api change, move to util", Scope = "type", Target = "~T:Dalamud.Game.Text.EnumExtensions")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change, move to util", Scope = "type", Target = "~T:Dalamud.Game.Text.EnumExtensions")]
|
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change, move to util", Scope = "type", Target = "~T:Dalamud.Game.Text.EnumExtensions")]
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Framework.StatsHistory")]
|
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:Elements should appear in the correct order", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Framework.StatsHistory")]
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,11 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
internal class DataWindow : Window
|
internal class DataWindow : Window
|
||||||
{
|
{
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly string[] dataKindNames = Enum.GetNames(typeof(DataKind)).Select(k => k.Replace("_", " ")).ToArray();
|
||||||
private readonly string[] dataKinds = new[]
|
|
||||||
{
|
|
||||||
"ServerOpCode", "Address", "Actor Table", "Font Test", "Party List", "Plugin IPC", "Condition",
|
|
||||||
"Gauge", "Command", "Addon", "Addon Inspector", "StartInfo", "Target", "Toast", "ImGui", "Tex", "Gamepad",
|
|
||||||
};
|
|
||||||
|
|
||||||
private bool wasReady;
|
private bool wasReady;
|
||||||
private string serverOpString;
|
private string serverOpString;
|
||||||
private int currentKind;
|
private DataKind currentKind;
|
||||||
|
|
||||||
private bool drawActors = false;
|
private bool drawActors = false;
|
||||||
private float maxActorDrawDistance = 20;
|
private float maxActorDrawDistance = 20;
|
||||||
|
|
@ -86,6 +81,28 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
this.Load();
|
this.Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum DataKind
|
||||||
|
{
|
||||||
|
Server_OpCode,
|
||||||
|
Address,
|
||||||
|
Actor_Table,
|
||||||
|
Fate_Table,
|
||||||
|
Font_Test,
|
||||||
|
Party_List,
|
||||||
|
Plugin_IPC,
|
||||||
|
Condition,
|
||||||
|
Gauge,
|
||||||
|
Command,
|
||||||
|
Addon,
|
||||||
|
Addon_Inspector,
|
||||||
|
StartInfo,
|
||||||
|
Target,
|
||||||
|
Toast,
|
||||||
|
ImGui,
|
||||||
|
Tex,
|
||||||
|
Gamepad,
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set the DataKind dropdown menu.
|
/// Set the DataKind dropdown menu.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -98,12 +115,15 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
if (dataKind == "ai")
|
if (dataKind == "ai")
|
||||||
dataKind = "Addon Inspector";
|
dataKind = "Addon Inspector";
|
||||||
|
|
||||||
int index;
|
|
||||||
dataKind = dataKind.Replace(" ", string.Empty).ToLower();
|
dataKind = dataKind.Replace(" ", string.Empty).ToLower();
|
||||||
var dataKinds = this.dataKinds.Select(k => k.Replace(" ", string.Empty).ToLower()).ToList();
|
var dataKinds = Enum.GetValues(typeof(DataKind))
|
||||||
if ((index = dataKinds.IndexOf(dataKind)) != -1)
|
.Cast<DataKind>()
|
||||||
|
.Where(k => nameof(k).Replace("_", string.Empty).ToLower() == dataKind)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (dataKinds.Count > 0)
|
||||||
{
|
{
|
||||||
this.currentKind = index;
|
this.currentKind = dataKinds.First();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -125,7 +145,11 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
var copy = ImGui.Button("Copy all");
|
var copy = ImGui.Button("Copy all");
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
ImGui.Combo("Data kind", ref this.currentKind, this.dataKinds, this.dataKinds.Length);
|
var currentKindIndex = (int)this.currentKind;
|
||||||
|
if (ImGui.Combo("Data kind", ref currentKindIndex, this.dataKindNames, this.dataKindNames.Length))
|
||||||
|
{
|
||||||
|
this.currentKind = (DataKind)currentKindIndex;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
ImGui.Checkbox("Resolve GameData", ref this.resolveGameData);
|
||||||
|
|
||||||
|
|
@ -142,309 +166,76 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
{
|
{
|
||||||
switch (this.currentKind)
|
switch (this.currentKind)
|
||||||
{
|
{
|
||||||
case 0:
|
case DataKind.Server_OpCode:
|
||||||
ImGui.TextUnformatted(this.serverOpString);
|
this.DrawServerOpCode();
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
|
|
||||||
ImGui.InputText(".text sig", ref this.inputSig, 400);
|
|
||||||
if (ImGui.Button("Resolve"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.sigResult = this.dalamud.SigScanner.ScanText(this.inputSig);
|
|
||||||
}
|
|
||||||
catch (KeyNotFoundException)
|
|
||||||
{
|
|
||||||
this.sigResult = new IntPtr(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Text($"Result: {this.sigResult.ToInt64():X}");
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (ImGui.Button($"C{this.copyButtonIndex++}"))
|
|
||||||
ImGui.SetClipboardText(this.sigResult.ToInt64().ToString("x"));
|
|
||||||
|
|
||||||
foreach (var debugScannedValue in BaseAddressResolver.DebugScannedValues)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted($"{debugScannedValue.Key}");
|
|
||||||
foreach (var valueTuple in debugScannedValue.Value)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted(
|
|
||||||
$" {valueTuple.Item1} - 0x{valueTuple.Item2.ToInt64():x}");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
if (ImGui.Button($"C##copyAddress{this.copyButtonIndex++}"))
|
|
||||||
ImGui.SetClipboardText(valueTuple.Item2.ToInt64().ToString("x"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AT
|
case DataKind.Address:
|
||||||
case 2:
|
this.DrawAddress();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DataKind.Actor_Table:
|
||||||
this.DrawActorTable();
|
this.DrawActorTable();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Font
|
case DataKind.Fate_Table:
|
||||||
case 3:
|
this.DrawFateTable();
|
||||||
var specialChars = string.Empty;
|
|
||||||
for (var i = 0xE020; i <= 0xE0DB; i++)
|
|
||||||
specialChars += $"0x{i:X} - {(SeIconChar)i} - {(char)i}\n";
|
|
||||||
|
|
||||||
ImGui.TextUnformatted(specialChars);
|
|
||||||
|
|
||||||
foreach (var fontAwesomeIcon in Enum.GetValues(typeof(FontAwesomeIcon))
|
|
||||||
.Cast<FontAwesomeIcon>())
|
|
||||||
{
|
|
||||||
ImGui.Text(((int)fontAwesomeIcon.ToIconChar()).ToString("X") + " - ");
|
|
||||||
ImGui.SameLine();
|
|
||||||
|
|
||||||
ImGui.PushFont(UiBuilder.IconFont);
|
|
||||||
ImGui.Text(fontAwesomeIcon.ToIconString());
|
|
||||||
ImGui.PopFont();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Party
|
case DataKind.Font_Test:
|
||||||
case 4:
|
this.DrawFontTest();
|
||||||
var partyString = string.Empty;
|
|
||||||
|
|
||||||
if (this.dalamud.ClientState.PartyList.Length == 0)
|
|
||||||
{
|
|
||||||
ImGui.TextUnformatted("Data not ready.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
partyString += $"{this.dalamud.ClientState.PartyList.Count} Members\n";
|
|
||||||
for (var i = 0; i < this.dalamud.ClientState.PartyList.Count; i++)
|
|
||||||
{
|
|
||||||
var member = this.dalamud.ClientState.PartyList[i];
|
|
||||||
if (member == null)
|
|
||||||
{
|
|
||||||
partyString +=
|
|
||||||
$"[{i}] was null\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
partyString +=
|
|
||||||
$"[{i}] {member.CharacterName} - {member.ObjectKind} - {member.Actor.ActorId}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.TextUnformatted(partyString);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Subscriptions
|
case DataKind.Party_List:
|
||||||
case 5:
|
this.DrawPartyList();
|
||||||
this.DrawIpcDebug();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Condition
|
case DataKind.Plugin_IPC:
|
||||||
case 6:
|
this.DrawPluginIPC();
|
||||||
#if DEBUG
|
|
||||||
ImGui.Text($"ptr: 0x{this.dalamud.ClientState.Condition.ConditionArrayBase.ToInt64():X}");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGui.Text("Current Conditions:");
|
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
var didAny = false;
|
|
||||||
|
|
||||||
for (var i = 0; i < Condition.MaxConditionEntries; i++)
|
|
||||||
{
|
|
||||||
var typedCondition = (ConditionFlag)i;
|
|
||||||
var cond = this.dalamud.ClientState.Condition[typedCondition];
|
|
||||||
|
|
||||||
if (!cond) continue;
|
|
||||||
|
|
||||||
didAny = true;
|
|
||||||
|
|
||||||
ImGui.Text($"ID: {i} Enum: {typedCondition}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!didAny)
|
|
||||||
ImGui.Text("None. Talk to a shop NPC or visit a market board to find out more!!!!!!!");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Gauge
|
case DataKind.Condition:
|
||||||
case 7:
|
this.DrawCondition();
|
||||||
var gauge = this.dalamud.ClientState.JobGauges.Get<ASTGauge>();
|
|
||||||
ImGui.Text($"Moon: {gauge.ContainsSeal(SealType.MOON)} Drawn: {gauge.DrawnCard()}");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Command
|
case DataKind.Gauge:
|
||||||
case 8:
|
this.DrawGauge();
|
||||||
foreach (var command in this.dalamud.CommandManager.Commands)
|
|
||||||
ImGui.Text($"{command.Key}\n -> {command.Value.HelpMessage}\n -> In help: {command.Value.ShowInHelp}\n\n");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Addon
|
case DataKind.Command:
|
||||||
case 9:
|
this.DrawCommand();
|
||||||
this.DrawAddonDebug();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Addon Inspector
|
case DataKind.Addon:
|
||||||
case 10:
|
this.DrawAddon();
|
||||||
this.addonInspector ??= new UIDebug(this.dalamud);
|
|
||||||
this.addonInspector.Draw();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// StartInfo
|
case DataKind.Addon_Inspector:
|
||||||
case 11:
|
this.DrawAddonInspector();
|
||||||
ImGui.Text(JsonConvert.SerializeObject(this.dalamud.StartInfo, Formatting.Indented));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Target
|
case DataKind.StartInfo:
|
||||||
case 12:
|
this.DrawStartInfo();
|
||||||
this.DrawTargetDebug();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Toast
|
case DataKind.Target:
|
||||||
case 13:
|
this.DrawTarget();
|
||||||
ImGui.InputText("Toast text", ref this.inputTextToast, 200);
|
|
||||||
|
|
||||||
ImGui.Combo("Toast Position", ref this.toastPosition, new[] { "Bottom", "Top", }, 2);
|
|
||||||
ImGui.Combo("Toast Speed", ref this.toastSpeed, new[] { "Slow", "Fast", }, 2);
|
|
||||||
ImGui.Combo("Quest Toast Position", ref this.questToastPosition, new[] { "Centre", "Right", "Left" }, 3);
|
|
||||||
ImGui.Checkbox("Quest Checkmark", ref this.questToastCheckmark);
|
|
||||||
ImGui.Checkbox("Quest Play Sound", ref this.questToastSound);
|
|
||||||
ImGui.InputInt("Quest Icon ID", ref this.questToastIconId);
|
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(new Vector2(10, 10));
|
|
||||||
|
|
||||||
if (ImGui.Button("Show toast"))
|
|
||||||
{
|
|
||||||
this.dalamud.Framework.Gui.Toast.ShowNormal(this.inputTextToast, new ToastOptions
|
|
||||||
{
|
|
||||||
Position = (ToastPosition)this.toastPosition,
|
|
||||||
Speed = (ToastSpeed)this.toastSpeed,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.Button("Show Quest toast"))
|
|
||||||
{
|
|
||||||
this.dalamud.Framework.Gui.Toast.ShowQuest(this.inputTextToast, new QuestToastOptions
|
|
||||||
{
|
|
||||||
Position = (QuestToastPosition)this.questToastPosition,
|
|
||||||
DisplayCheckmark = this.questToastCheckmark,
|
|
||||||
IconId = (uint)this.questToastIconId,
|
|
||||||
PlaySound = this.questToastSound,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.Button("Show Error toast"))
|
|
||||||
{
|
|
||||||
this.dalamud.Framework.Gui.Toast.ShowError(this.inputTextToast);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ImGui
|
case DataKind.Toast:
|
||||||
case 14:
|
this.DrawToast();
|
||||||
ImGui.Text("Monitor count: " + ImGui.GetPlatformIO().Monitors.Size);
|
|
||||||
ImGui.Text("OverrideGameCursor: " + this.dalamud.InterfaceManager.OverrideGameCursor);
|
|
||||||
|
|
||||||
ImGui.Button("THIS IS A BUTTON###hoverTestButton");
|
|
||||||
this.dalamud.InterfaceManager.OverrideGameCursor = !ImGui.IsItemHovered();
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Tex
|
case DataKind.ImGui:
|
||||||
case 15:
|
this.DrawImGui();
|
||||||
ImGui.InputText("Tex Path", ref this.inputTexPath, 255);
|
|
||||||
ImGui.InputFloat2("UV0", ref this.inputTexUv0);
|
|
||||||
ImGui.InputFloat2("UV1", ref this.inputTexUv1);
|
|
||||||
ImGui.InputFloat4("Tint", ref this.inputTintCol);
|
|
||||||
ImGui.InputFloat2("Scale", ref this.inputTexScale);
|
|
||||||
|
|
||||||
if (ImGui.Button("Load Tex"))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
this.debugTex = this.dalamud.Data.GetImGuiTexture(this.inputTexPath);
|
|
||||||
this.inputTexScale = new Vector2(this.debugTex.Width, this.debugTex.Height);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Log.Error(ex, "Could not load tex.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(10);
|
|
||||||
|
|
||||||
if (this.debugTex != null)
|
|
||||||
{
|
|
||||||
ImGui.Image(this.debugTex.ImGuiHandle, this.inputTexScale, this.inputTexUv0, this.inputTexUv1, this.inputTintCol);
|
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
|
||||||
Util.ShowObject(this.debugTex);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Gamepad
|
case DataKind.Tex:
|
||||||
case 16:
|
this.DrawTex();
|
||||||
Action<string, uint, Func<GamepadButtons, float>> helper = (text, mask, resolve) =>
|
break;
|
||||||
{
|
|
||||||
ImGui.Text($"{text} {mask:X4}");
|
|
||||||
ImGui.Text($"DPadLeft {resolve(GamepadButtons.DpadLeft)} " +
|
|
||||||
$"DPadUp {resolve(GamepadButtons.DpadUp)} " +
|
|
||||||
$"DPadRight {resolve(GamepadButtons.DpadRight)} " +
|
|
||||||
$"DPadDown {resolve(GamepadButtons.DpadDown)} ");
|
|
||||||
ImGui.Text($"West {resolve(GamepadButtons.West)} " +
|
|
||||||
$"North {resolve(GamepadButtons.North)} " +
|
|
||||||
$"East {resolve(GamepadButtons.East)} " +
|
|
||||||
$"South {resolve(GamepadButtons.South)} ");
|
|
||||||
ImGui.Text($"L1 {resolve(GamepadButtons.L1)} " +
|
|
||||||
$"L2 {resolve(GamepadButtons.L2)} " +
|
|
||||||
$"R1 {resolve(GamepadButtons.R1)} " +
|
|
||||||
$"R2 {resolve(GamepadButtons.R2)} ");
|
|
||||||
ImGui.Text($"Select {resolve(GamepadButtons.Select)} " +
|
|
||||||
$"Start {resolve(GamepadButtons.Start)} " +
|
|
||||||
$"L3 {resolve(GamepadButtons.L3)} " +
|
|
||||||
$"R3 {resolve(GamepadButtons.R3)} ");
|
|
||||||
};
|
|
||||||
#if DEBUG
|
|
||||||
ImGui.Text($"GamepadInput 0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
|
|
||||||
|
|
||||||
if (ImGui.IsItemHovered())
|
case DataKind.Gamepad:
|
||||||
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
this.DrawGamepad();
|
||||||
|
|
||||||
if (ImGui.IsItemClicked())
|
|
||||||
ImGui.SetClipboardText($"0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
helper(
|
|
||||||
"Buttons Raw",
|
|
||||||
this.dalamud.ClientState.GamepadState.ButtonsRaw,
|
|
||||||
this.dalamud.ClientState.GamepadState.Raw);
|
|
||||||
helper(
|
|
||||||
"Buttons Pressed",
|
|
||||||
this.dalamud.ClientState.GamepadState.ButtonsPressed,
|
|
||||||
this.dalamud.ClientState.GamepadState.Pressed);
|
|
||||||
helper(
|
|
||||||
"Buttons Repeat",
|
|
||||||
this.dalamud.ClientState.GamepadState.ButtonsRepeat,
|
|
||||||
this.dalamud.ClientState.GamepadState.Repeat);
|
|
||||||
helper(
|
|
||||||
"Buttons Released",
|
|
||||||
this.dalamud.ClientState.GamepadState.ButtonsReleased,
|
|
||||||
this.dalamud.ClientState.GamepadState.Released);
|
|
||||||
ImGui.Text($"LeftStickLeft {this.dalamud.ClientState.GamepadState.LeftStickLeft:0.00} " +
|
|
||||||
$"LeftStickUp {this.dalamud.ClientState.GamepadState.LeftStickUp:0.00} " +
|
|
||||||
$"LeftStickRight {this.dalamud.ClientState.GamepadState.LeftStickRight:0.00} " +
|
|
||||||
$"LeftStickDown {this.dalamud.ClientState.GamepadState.LeftStickDown:0.00} ");
|
|
||||||
ImGui.Text($"RightStickLeft {this.dalamud.ClientState.GamepadState.RightStickLeft:0.00} " +
|
|
||||||
$"RightStickUp {this.dalamud.ClientState.GamepadState.RightStickUp:0.00} " +
|
|
||||||
$"RightStickRight {this.dalamud.ClientState.GamepadState.RightStickRight:0.00} " +
|
|
||||||
$"RightStickDown {this.dalamud.ClientState.GamepadState.RightStickDown:0.00} ");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -463,6 +254,46 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawServerOpCode()
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted(this.serverOpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawAddress()
|
||||||
|
{
|
||||||
|
ImGui.InputText(".text sig", ref this.inputSig, 400);
|
||||||
|
if (ImGui.Button("Resolve"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.sigResult = this.dalamud.SigScanner.ScanText(this.inputSig);
|
||||||
|
}
|
||||||
|
catch (KeyNotFoundException)
|
||||||
|
{
|
||||||
|
this.sigResult = new IntPtr(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Text($"Result: {this.sigResult.ToInt64():X}");
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.Button($"C{this.copyButtonIndex++}"))
|
||||||
|
ImGui.SetClipboardText(this.sigResult.ToInt64().ToString("x"));
|
||||||
|
|
||||||
|
foreach (var debugScannedValue in BaseAddressResolver.DebugScannedValues)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted($"{debugScannedValue.Key}");
|
||||||
|
foreach (var valueTuple in debugScannedValue.Value)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted(
|
||||||
|
$" {valueTuple.Item1} - 0x{valueTuple.Item2.ToInt64():x}");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Button($"C##copyAddress{this.copyButtonIndex++}"))
|
||||||
|
ImGui.SetClipboardText(valueTuple.Item2.ToInt64().ToString("x"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawActorTable()
|
private void DrawActorTable()
|
||||||
{
|
{
|
||||||
var stateString = string.Empty;
|
var stateString = string.Empty;
|
||||||
|
|
@ -545,9 +376,98 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
private void DrawFateTable()
|
||||||
private void DrawIpcDebug()
|
|
||||||
{
|
{
|
||||||
|
var stateString = string.Empty;
|
||||||
|
if (this.dalamud.ClientState.Fates.Length == 0)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("No fates or data not ready.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stateString += $"FrameworkBase: {this.dalamud.Framework.Address.BaseAddress.ToInt64():X}\n";
|
||||||
|
stateString += $"FateTableLen: {this.dalamud.ClientState.Fates.Length}\n";
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(stateString);
|
||||||
|
|
||||||
|
for (var i = 0; i < this.dalamud.ClientState.Fates.Length; i++)
|
||||||
|
{
|
||||||
|
var fate = this.dalamud.ClientState.Fates[i];
|
||||||
|
if (fate == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var fateString = $"{fate.Address.ToInt64():X}:[{i}]" +
|
||||||
|
$" - Lv.{fate.Level} {fate.Name} ({fate.Progress}%)" +
|
||||||
|
$" - X{fate.Position.X} Y{fate.Position.Y} Z{fate.Position.Z}" +
|
||||||
|
$" - Territory {(this.resolveGameData ? (fate.TerritoryType.GameData?.Name ?? fate.TerritoryType.Id.ToString()) : fate.TerritoryType.Id.ToString())}\n";
|
||||||
|
|
||||||
|
fateString += $" StartTimeEpoch: {fate.StartTimeEpoch}" +
|
||||||
|
$" - Duration: {fate.Duration}" +
|
||||||
|
$" - State: {fate.State}" +
|
||||||
|
$" - GameData name: {(this.resolveGameData ? (fate.GameData?.Name ?? fate.FateId.ToString()) : fate.FateId.ToString())}";
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(fateString);
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.Button("C"))
|
||||||
|
{
|
||||||
|
ImGui.SetClipboardText(fate.Address.ToString("X"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawFontTest()
|
||||||
|
{
|
||||||
|
var specialChars = string.Empty;
|
||||||
|
|
||||||
|
for (var i = 0xE020; i <= 0xE0DB; i++)
|
||||||
|
specialChars += $"0x{i:X} - {(SeIconChar)i} - {(char)i}\n";
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(specialChars);
|
||||||
|
|
||||||
|
foreach (var fontAwesomeIcon in Enum.GetValues(typeof(FontAwesomeIcon)).Cast<FontAwesomeIcon>())
|
||||||
|
{
|
||||||
|
ImGui.Text(((int)fontAwesomeIcon.ToIconChar()).ToString("X") + " - ");
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
ImGui.PushFont(UiBuilder.IconFont);
|
||||||
|
ImGui.Text(fontAwesomeIcon.ToIconString());
|
||||||
|
ImGui.PopFont();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawPartyList()
|
||||||
|
{
|
||||||
|
var partyString = string.Empty;
|
||||||
|
|
||||||
|
if (this.dalamud.ClientState.PartyList.Length == 0)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Data not ready.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
partyString += $"{this.dalamud.ClientState.PartyList.Count} Members\n";
|
||||||
|
for (var i = 0; i < this.dalamud.ClientState.PartyList.Count; i++)
|
||||||
|
{
|
||||||
|
var member = this.dalamud.ClientState.PartyList[i];
|
||||||
|
if (member == null)
|
||||||
|
{
|
||||||
|
partyString +=
|
||||||
|
$"[{i}] was null\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
partyString +=
|
||||||
|
$"[{i}] {member.CharacterName} - {member.ObjectKind} - {member.Actor.ActorId}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(partyString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawPluginIPC()
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
var i1 = new DalamudPluginInterface(this.dalamud, "DalamudTestSub", null, PluginLoadReason.Unknown);
|
var i1 = new DalamudPluginInterface(this.dalamud, "DalamudTestSub", null, PluginLoadReason.Unknown);
|
||||||
var i2 = new DalamudPluginInterface(this.dalamud, "DalamudTestPub", null, PluginLoadReason.Unknown);
|
var i2 = new DalamudPluginInterface(this.dalamud, "DalamudTestPub", null, PluginLoadReason.Unknown);
|
||||||
|
|
||||||
|
|
@ -592,10 +512,49 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
|
|
||||||
foreach (var ipc in this.dalamud.PluginManager.IpcSubscriptions)
|
foreach (var ipc in this.dalamud.PluginManager.IpcSubscriptions)
|
||||||
ImGui.Text($"Source:{ipc.SourcePluginName} Sub:{ipc.SubPluginName}");
|
ImGui.Text($"Source:{ipc.SourcePluginName} Sub:{ipc.SubPluginName}");
|
||||||
}
|
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawAddonDebug()
|
private void DrawCondition()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
ImGui.Text($"ptr: 0x{this.dalamud.ClientState.Condition.ConditionArrayBase.ToInt64():X}");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ImGui.Text("Current Conditions:");
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
var didAny = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < Condition.MaxConditionEntries; i++)
|
||||||
|
{
|
||||||
|
var typedCondition = (ConditionFlag)i;
|
||||||
|
var cond = this.dalamud.ClientState.Condition[typedCondition];
|
||||||
|
|
||||||
|
if (!cond) continue;
|
||||||
|
|
||||||
|
didAny = true;
|
||||||
|
|
||||||
|
ImGui.Text($"ID: {i} Enum: {typedCondition}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!didAny)
|
||||||
|
ImGui.Text("None. Talk to a shop NPC or visit a market board to find out more!!!!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGauge()
|
||||||
|
{
|
||||||
|
var gauge = this.dalamud.ClientState.JobGauges.Get<ASTGauge>();
|
||||||
|
ImGui.Text($"Moon: {gauge.ContainsSeal(SealType.MOON)} Drawn: {gauge.DrawnCard()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawCommand()
|
||||||
|
{
|
||||||
|
foreach (var command in this.dalamud.CommandManager.Commands)
|
||||||
|
ImGui.Text($"{command.Key}\n -> {command.Value.HelpMessage}\n -> In help: {command.Value.ShowInHelp}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawAddon()
|
||||||
{
|
{
|
||||||
ImGui.InputText("Addon name", ref this.inputAddonName, 256);
|
ImGui.InputText("Addon name", ref this.inputAddonName, 256);
|
||||||
ImGui.InputInt("Addon Index", ref this.inputAddonIndex);
|
ImGui.InputInt("Addon Index", ref this.inputAddonIndex);
|
||||||
|
|
@ -634,7 +593,18 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawTargetDebug()
|
private void DrawAddonInspector()
|
||||||
|
{
|
||||||
|
this.addonInspector ??= new UIDebug(this.dalamud);
|
||||||
|
this.addonInspector.Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawStartInfo()
|
||||||
|
{
|
||||||
|
ImGui.Text(JsonConvert.SerializeObject(this.dalamud.StartInfo, Formatting.Indented));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTarget()
|
||||||
{
|
{
|
||||||
var targetMgr = this.dalamud.ClientState.Targets;
|
var targetMgr = this.dalamud.ClientState.Targets;
|
||||||
|
|
||||||
|
|
@ -678,6 +648,143 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawToast()
|
||||||
|
{
|
||||||
|
ImGui.InputText("Toast text", ref this.inputTextToast, 200);
|
||||||
|
|
||||||
|
ImGui.Combo("Toast Position", ref this.toastPosition, new[] { "Bottom", "Top", }, 2);
|
||||||
|
ImGui.Combo("Toast Speed", ref this.toastSpeed, new[] { "Slow", "Fast", }, 2);
|
||||||
|
ImGui.Combo("Quest Toast Position", ref this.questToastPosition, new[] { "Centre", "Right", "Left" }, 3);
|
||||||
|
ImGui.Checkbox("Quest Checkmark", ref this.questToastCheckmark);
|
||||||
|
ImGui.Checkbox("Quest Play Sound", ref this.questToastSound);
|
||||||
|
ImGui.InputInt("Quest Icon ID", ref this.questToastIconId);
|
||||||
|
|
||||||
|
ImGuiHelpers.ScaledDummy(new Vector2(10, 10));
|
||||||
|
|
||||||
|
if (ImGui.Button("Show toast"))
|
||||||
|
{
|
||||||
|
this.dalamud.Framework.Gui.Toast.ShowNormal(this.inputTextToast, new ToastOptions
|
||||||
|
{
|
||||||
|
Position = (ToastPosition)this.toastPosition,
|
||||||
|
Speed = (ToastSpeed)this.toastSpeed,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.Button("Show Quest toast"))
|
||||||
|
{
|
||||||
|
this.dalamud.Framework.Gui.Toast.ShowQuest(this.inputTextToast, new QuestToastOptions
|
||||||
|
{
|
||||||
|
Position = (QuestToastPosition)this.questToastPosition,
|
||||||
|
DisplayCheckmark = this.questToastCheckmark,
|
||||||
|
IconId = (uint)this.questToastIconId,
|
||||||
|
PlaySound = this.questToastSound,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.Button("Show Error toast"))
|
||||||
|
{
|
||||||
|
this.dalamud.Framework.Gui.Toast.ShowError(this.inputTextToast);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawImGui()
|
||||||
|
{
|
||||||
|
ImGui.Text("Monitor count: " + ImGui.GetPlatformIO().Monitors.Size);
|
||||||
|
ImGui.Text("OverrideGameCursor: " + this.dalamud.InterfaceManager.OverrideGameCursor);
|
||||||
|
|
||||||
|
ImGui.Button("THIS IS A BUTTON###hoverTestButton");
|
||||||
|
this.dalamud.InterfaceManager.OverrideGameCursor = !ImGui.IsItemHovered();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawTex()
|
||||||
|
{
|
||||||
|
ImGui.InputText("Tex Path", ref this.inputTexPath, 255);
|
||||||
|
ImGui.InputFloat2("UV0", ref this.inputTexUv0);
|
||||||
|
ImGui.InputFloat2("UV1", ref this.inputTexUv1);
|
||||||
|
ImGui.InputFloat4("Tint", ref this.inputTintCol);
|
||||||
|
ImGui.InputFloat2("Scale", ref this.inputTexScale);
|
||||||
|
|
||||||
|
if (ImGui.Button("Load Tex"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.debugTex = this.dalamud.Data.GetImGuiTexture(this.inputTexPath);
|
||||||
|
this.inputTexScale = new Vector2(this.debugTex.Width, this.debugTex.Height);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Could not load tex.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiHelpers.ScaledDummy(10);
|
||||||
|
|
||||||
|
if (this.debugTex != null)
|
||||||
|
{
|
||||||
|
ImGui.Image(this.debugTex.ImGuiHandle, this.inputTexScale, this.inputTexUv0, this.inputTexUv1, this.inputTintCol);
|
||||||
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
Util.ShowObject(this.debugTex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGamepad()
|
||||||
|
{
|
||||||
|
static void DrawHelper(string text, uint mask, Func<GamepadButtons, float> resolve)
|
||||||
|
{
|
||||||
|
ImGui.Text($"{text} {mask:X4}");
|
||||||
|
ImGui.Text($"DPadLeft {resolve(GamepadButtons.DpadLeft)} " +
|
||||||
|
$"DPadUp {resolve(GamepadButtons.DpadUp)} " +
|
||||||
|
$"DPadRight {resolve(GamepadButtons.DpadRight)} " +
|
||||||
|
$"DPadDown {resolve(GamepadButtons.DpadDown)} ");
|
||||||
|
ImGui.Text($"West {resolve(GamepadButtons.West)} " +
|
||||||
|
$"North {resolve(GamepadButtons.North)} " +
|
||||||
|
$"East {resolve(GamepadButtons.East)} " +
|
||||||
|
$"South {resolve(GamepadButtons.South)} ");
|
||||||
|
ImGui.Text($"L1 {resolve(GamepadButtons.L1)} " +
|
||||||
|
$"L2 {resolve(GamepadButtons.L2)} " +
|
||||||
|
$"R1 {resolve(GamepadButtons.R1)} " +
|
||||||
|
$"R2 {resolve(GamepadButtons.R2)} ");
|
||||||
|
ImGui.Text($"Select {resolve(GamepadButtons.Select)} " +
|
||||||
|
$"Start {resolve(GamepadButtons.Start)} " +
|
||||||
|
$"L3 {resolve(GamepadButtons.L3)} " +
|
||||||
|
$"R3 {resolve(GamepadButtons.R3)} ");
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
ImGui.Text($"GamepadInput 0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
||||||
|
|
||||||
|
if (ImGui.IsItemClicked())
|
||||||
|
ImGui.SetClipboardText($"0x{this.dalamud.ClientState.GamepadState.GamepadInput.ToInt64():X}");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DrawHelper(
|
||||||
|
"Buttons Raw",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsRaw,
|
||||||
|
this.dalamud.ClientState.GamepadState.Raw);
|
||||||
|
DrawHelper(
|
||||||
|
"Buttons Pressed",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsPressed,
|
||||||
|
this.dalamud.ClientState.GamepadState.Pressed);
|
||||||
|
DrawHelper(
|
||||||
|
"Buttons Repeat",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsRepeat,
|
||||||
|
this.dalamud.ClientState.GamepadState.Repeat);
|
||||||
|
DrawHelper(
|
||||||
|
"Buttons Released",
|
||||||
|
this.dalamud.ClientState.GamepadState.ButtonsReleased,
|
||||||
|
this.dalamud.ClientState.GamepadState.Released);
|
||||||
|
ImGui.Text($"LeftStickLeft {this.dalamud.ClientState.GamepadState.LeftStickLeft:0.00} " +
|
||||||
|
$"LeftStickUp {this.dalamud.ClientState.GamepadState.LeftStickUp:0.00} " +
|
||||||
|
$"LeftStickRight {this.dalamud.ClientState.GamepadState.LeftStickRight:0.00} " +
|
||||||
|
$"LeftStickDown {this.dalamud.ClientState.GamepadState.LeftStickDown:0.00} ");
|
||||||
|
ImGui.Text($"RightStickLeft {this.dalamud.ClientState.GamepadState.RightStickLeft:0.00} " +
|
||||||
|
$"RightStickUp {this.dalamud.ClientState.GamepadState.RightStickUp:0.00} " +
|
||||||
|
$"RightStickRight {this.dalamud.ClientState.GamepadState.RightStickRight:0.00} " +
|
||||||
|
$"RightStickDown {this.dalamud.ClientState.GamepadState.RightStickDown:0.00} ");
|
||||||
|
}
|
||||||
|
|
||||||
private void Load()
|
private void Load()
|
||||||
{
|
{
|
||||||
if (this.dalamud.Data.IsDataReady)
|
if (this.dalamud.Data.IsDataReady)
|
||||||
|
|
@ -693,7 +800,7 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
$"{actor.Address.ToInt64():X}:{actor.ActorId: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.TargetActorID:X}\n";
|
$"{actor.Address.ToInt64():X}:{actor.ActorId: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.TargetActorID:X}\n";
|
||||||
|
|
||||||
if (actor is Npc npc)
|
if (actor is Npc npc)
|
||||||
actorString += $" DataId: {npc.DataId} NameId:{npc.NameId}\n";
|
actorString += $" DataId: {npc.BaseId} NameId:{npc.NameId}\n";
|
||||||
|
|
||||||
if (actor is Chara chara)
|
if (actor is Chara chara)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using System.Text;
|
||||||
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using Dalamud.Memory.Exceptions;
|
using Dalamud.Memory.Exceptions;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||||
|
|
||||||
using static Dalamud.NativeFunctions;
|
using static Dalamud.NativeFunctions;
|
||||||
|
|
||||||
|
|
@ -79,7 +80,7 @@ namespace Dalamud.Memory
|
||||||
/// <returns>The read in struct array.</returns>
|
/// <returns>The read in struct array.</returns>
|
||||||
public static T[] Read<T>(IntPtr memoryAddress, int arrayLength, bool marshal)
|
public static T[] Read<T>(IntPtr memoryAddress, int arrayLength, bool marshal)
|
||||||
{
|
{
|
||||||
var structSize = SizeOf<T>();
|
var structSize = SizeOf<T>(marshal);
|
||||||
var value = new T[arrayLength];
|
var value = new T[arrayLength];
|
||||||
|
|
||||||
for (var i = 0; i < arrayLength; i++)
|
for (var i = 0; i < arrayLength; i++)
|
||||||
|
|
@ -223,7 +224,37 @@ namespace Dalamud.Memory
|
||||||
public static SeString ReadSeString(IntPtr memoryAddress, int maxLength)
|
public static SeString ReadSeString(IntPtr memoryAddress, int maxLength)
|
||||||
{
|
{
|
||||||
ReadRaw(memoryAddress, maxLength, out var buffer);
|
ReadRaw(memoryAddress, maxLength, out var buffer);
|
||||||
return seStringManager.Parse(buffer);
|
|
||||||
|
var eos = Array.IndexOf(buffer, (byte)0);
|
||||||
|
if (eos < 0)
|
||||||
|
{
|
||||||
|
return seStringManager.Parse(buffer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newBuffer = new byte[eos];
|
||||||
|
Buffer.BlockCopy(buffer, 0, newBuffer, 0, eos);
|
||||||
|
return seStringManager.Parse(newBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read an SeString from a specified Utf8String structure.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="utf8String">The memory address to read from.</param>
|
||||||
|
/// <returns>The read in string.</returns>
|
||||||
|
public static unsafe SeString ReadSeString(Utf8String* utf8String)
|
||||||
|
{
|
||||||
|
if (utf8String == null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var ptr = utf8String->StringPtr;
|
||||||
|
if (ptr == null)
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
var len = Math.Max(utf8String->BufUsed, utf8String->StringLength);
|
||||||
|
|
||||||
|
return ReadSeString((IntPtr)ptr, (int)len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -295,6 +326,14 @@ namespace Dalamud.Memory
|
||||||
public static void ReadSeString(IntPtr memoryAddress, int maxLength, out SeString value)
|
public static void ReadSeString(IntPtr memoryAddress, int maxLength, out SeString value)
|
||||||
=> value = ReadSeString(memoryAddress, maxLength);
|
=> value = ReadSeString(memoryAddress, maxLength);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read an SeString from a specified Utf8String structure.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="utf8String">The memory address to read from.</param>
|
||||||
|
/// <param name="value">The read in string.</param>
|
||||||
|
public static unsafe void ReadSeString(Utf8String* utf8String, out SeString value)
|
||||||
|
=> value = ReadSeString(utf8String);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Write
|
#region Write
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue