mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-30 20:33:40 +01:00
Merge branch 'master' into flytext
This commit is contained in:
commit
4bf1e0f679
127 changed files with 5204 additions and 2348 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
|
@ -3,4 +3,4 @@
|
||||||
url = https://github.com/goatcorp/ImGuiScene
|
url = https://github.com/goatcorp/ImGuiScene
|
||||||
[submodule "lib/FFXIVClientStructs"]
|
[submodule "lib/FFXIVClientStructs"]
|
||||||
path = lib/FFXIVClientStructs
|
path = lib/FFXIVClientStructs
|
||||||
url = https://github.com/goatcorp/FFXIVClientStructs.git
|
url = https://github.com/aers/FFXIVClientStructs.git
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@
|
||||||
<NoWarn>IDE0003</NoWarn>
|
<NoWarn>IDE0003</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Label="Documentation">
|
||||||
|
<DocumentationFile></DocumentationFile>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Label="Build">
|
<PropertyGroup Label="Build">
|
||||||
<OutputPath>$(AppData)\XIVLauncher\devPlugins\Dalamud.CorePlugin</OutputPath>
|
<OutputPath>$(AppData)\XIVLauncher\devPlugins\Dalamud.CorePlugin</OutputPath>
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ namespace Dalamud.CorePlugin
|
||||||
|
|
||||||
this.windowSystem.AddWindow(new PluginWindow(Dalamud.Instance));
|
this.windowSystem.AddWindow(new PluginWindow(Dalamud.Instance));
|
||||||
|
|
||||||
this.Interface.UiBuilder.OnBuildUi += this.OnDraw;
|
this.Interface.UiBuilder.Draw += this.OnDraw;
|
||||||
this.Interface.UiBuilder.OnOpenConfigUi += this.OnOpenConfigUi;
|
this.Interface.UiBuilder.OpenConfigUi += this.OnOpenConfigUi;
|
||||||
|
|
||||||
this.Interface.CommandManager.AddHandler("/di", new(this.OnCommand) { HelpMessage = $"Access the {this.Name} plugin." });
|
this.Interface.CommandManager.AddHandler("/di", new(this.OnCommand) { HelpMessage = $"Access the {this.Name} plugin." });
|
||||||
}
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ namespace Dalamud.CorePlugin
|
||||||
{
|
{
|
||||||
this.Interface.CommandManager.RemoveHandler("/di");
|
this.Interface.CommandManager.RemoveHandler("/di");
|
||||||
|
|
||||||
this.Interface.UiBuilder.OnBuildUi -= this.OnDraw;
|
this.Interface.UiBuilder.Draw -= this.OnDraw;
|
||||||
|
|
||||||
this.windowSystem.RemoveAllWindows();
|
this.windowSystem.RemoveAllWindows();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
|
|
@ -11,6 +12,7 @@ namespace Dalamud.CorePlugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class PluginWindow : Window, IDisposable
|
internal class PluginWindow : Window, IDisposable
|
||||||
{
|
{
|
||||||
|
[SuppressMessage("CodeQuality", "IDE0052:Remove unread private members", Justification = "This is a placeholder.")]
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Dalamud.Data;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
|
using Dalamud.Game.Gui.Internal;
|
||||||
using Dalamud.Game.Internal;
|
using Dalamud.Game.Internal;
|
||||||
using Dalamud.Game.Network.Internal;
|
using Dalamud.Game.Network.Internal;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
|
@ -100,6 +101,11 @@ namespace Dalamud
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal InterfaceManager InterfaceManager { get; private set; }
|
internal InterfaceManager InterfaceManager { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Input Method subsystem.
|
||||||
|
/// </summary>
|
||||||
|
internal DalamudIME IME { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets ClientState subsystem.
|
/// Gets ClientState subsystem.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -293,6 +299,16 @@ namespace Dalamud
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.IME = new DalamudIME(this);
|
||||||
|
Log.Information("[T2] IME OK!");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Information(e, "Could not init IME.");
|
||||||
|
}
|
||||||
|
|
||||||
this.Data = new DataManager(this.StartInfo.Language, this.InterfaceManager);
|
this.Data = new DataManager(this.StartInfo.Language, this.InterfaceManager);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -415,6 +431,11 @@ namespace Dalamud
|
||||||
{
|
{
|
||||||
this.hasDisposedPlugins = true;
|
this.hasDisposedPlugins = true;
|
||||||
|
|
||||||
|
// this must be done before unloading interface manager, in order to do rebuild
|
||||||
|
// the correct cascaded WndProc (IME -> RawDX11Scene -> Game). Otherwise the game
|
||||||
|
// will not receive any windows messages
|
||||||
|
this.IME?.Dispose();
|
||||||
|
|
||||||
// this must be done before unloading plugins, or it can cause a race condition
|
// this must be done before unloading plugins, or it can cause a race condition
|
||||||
// due to rendering happening on another thread, where a plugin might receive
|
// due to rendering happening on another thread, where a plugin might receive
|
||||||
// a render call after it has been disposed, which can crash if it attempts to
|
// a render call after it has been disposed, which can crash if it attempts to
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,9 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Label="Warnings">
|
<PropertyGroup Label="Warnings">
|
||||||
<NoWarn>IDE0003;IDE0044;IDE1006;CS1591;CS1701;CS1702</NoWarn>
|
<NoWarn>IDE0003;IDE0044;IDE1006;CA1822;CS1591;CS1701;CS1702</NoWarn>
|
||||||
<!-- IDE1006 - Naming violation -->
|
<!-- IDE1006 - Naming violation -->
|
||||||
|
<!-- CA1822 - Can be marked as static -->
|
||||||
<!-- 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 -->
|
||||||
<!-- CS1702 - Runtime policy may be needed -->
|
<!-- CS1702 - Runtime policy may be needed -->
|
||||||
|
|
@ -67,9 +68,6 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
<PackageReference Include="McMaster.NETCore.Plugins" Version="1.4.0" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.10.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.10.0" />
|
||||||
<PackageReference Include="PropertyChanged.Fody" Version="3.4.0">
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
|
||||||
<PropertyChanged />
|
|
||||||
</Weavers>
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
|
||||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
|
||||||
<xs:element name="Weavers">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:all>
|
|
||||||
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
|
|
||||||
<xs:complexType>
|
|
||||||
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="EventInvokerNames" type="xs:string">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="CheckForEquality" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="SuppressWarnings" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:all>
|
|
||||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
</xs:schema>
|
|
||||||
|
|
@ -2,7 +2,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -105,8 +104,8 @@ namespace Dalamud.Game
|
||||||
{
|
{
|
||||||
this.dalamud = dalamud;
|
this.dalamud = dalamud;
|
||||||
|
|
||||||
dalamud.Framework.Gui.Chat.OnCheckMessageHandled += this.OnCheckMessageHandled;
|
dalamud.Framework.Gui.Chat.CheckMessageHandled += this.OnCheckMessageHandled;
|
||||||
dalamud.Framework.Gui.Chat.OnChatMessage += this.OnChatMessage;
|
dalamud.Framework.Gui.Chat.ChatMessage += this.OnChatMessage;
|
||||||
|
|
||||||
this.openInstallerWindowLink = this.dalamud.Framework.Gui.Chat.AddChatLinkHandler("Dalamud", 1001, (i, m) =>
|
this.openInstallerWindowLink = this.dalamud.Framework.Gui.Chat.AddChatLinkHandler("Dalamud", 1001, (i, m) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,149 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This collection represents the currently spawned FFXIV actors.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class ActorTable
|
|
||||||
{
|
|
||||||
private const int ActorTableLength = 424;
|
|
||||||
|
|
||||||
private readonly Dalamud dalamud;
|
|
||||||
private readonly ClientStateAddressResolver address;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="ActorTable"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
|
||||||
/// <param name="addressResolver">Client state address resolver.</param>
|
|
||||||
internal ActorTable(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
|
||||||
{
|
|
||||||
this.dalamud = dalamud;
|
|
||||||
this.address = addressResolver;
|
|
||||||
|
|
||||||
Log.Verbose($"Actor table address 0x{this.address.ActorTable.ToInt64():X}");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of currently spawned actors.
|
|
||||||
/// </summary>
|
|
||||||
public int Length
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var count = 0;
|
|
||||||
for (var i = 0; i < ActorTableLength; i++)
|
|
||||||
{
|
|
||||||
var ptr = this.GetActorAddress(i);
|
|
||||||
if (ptr != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <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/>
|
|
||||||
int IReadOnlyCollection<Actor>.Count => this.Length;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
int ICollection.Count => this.Length;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
bool ICollection.IsSynchronized => false;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
object ICollection.SyncRoot => this;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public IEnumerator<Actor> GetEnumerator()
|
|
||||||
{
|
|
||||||
for (var i = 0; i < ActorTableLength; 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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,125 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get and set various kinds of targets for the player.
|
|
||||||
/// </summary>
|
|
||||||
public sealed class Targets
|
|
||||||
{
|
|
||||||
private readonly Dalamud dalamud;
|
|
||||||
private readonly ClientStateAddressResolver address;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Targets"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dalamud">The Dalamud instance.</param>
|
|
||||||
/// <param name="addressResolver">The ClientStateAddressResolver instance.</param>
|
|
||||||
internal Targets(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
|
||||||
{
|
|
||||||
this.dalamud = dalamud;
|
|
||||||
this.address = addressResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current target.
|
|
||||||
/// </summary>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor CurrentTarget => this.GetActorByOffset(TargetOffsets.CurrentTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the mouseover target.
|
|
||||||
/// </summary>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor MouseOverTarget => this.GetActorByOffset(TargetOffsets.MouseOverTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the focus target.
|
|
||||||
/// </summary>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor FocusTarget => this.GetActorByOffset(TargetOffsets.FocusTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the previous target.
|
|
||||||
/// </summary>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor PreviousTarget => this.GetActorByOffset(TargetOffsets.PreviousTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the soft target.
|
|
||||||
/// </summary>
|
|
||||||
[CanBeNull]
|
|
||||||
public Actor SoftTarget => this.GetActorByOffset(TargetOffsets.SoftTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the current target.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="actor">Actor to target.</param>
|
|
||||||
public void SetCurrentTarget(Actor actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero, TargetOffsets.CurrentTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the current target.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="actorAddress">Actor (address) to target.</param>
|
|
||||||
public void SetCurrentTarget(IntPtr actorAddress) => this.SetTarget(actorAddress, TargetOffsets.CurrentTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the focus target.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="actor">Actor to focus.</param>
|
|
||||||
public void SetFocusTarget(Actor actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero, TargetOffsets.FocusTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sets the focus target.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="actorAddress">Actor (address) to focus.</param>
|
|
||||||
public void SetFocusTarget(IntPtr actorAddress) => this.SetTarget(actorAddress, TargetOffsets.FocusTarget);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the current target.
|
|
||||||
/// </summary>
|
|
||||||
public void ClearCurrentTarget() => this.SetCurrentTarget(IntPtr.Zero);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clears the focus target.
|
|
||||||
/// </summary>
|
|
||||||
public void ClearFocusTarget() => this.SetFocusTarget(IntPtr.Zero);
|
|
||||||
|
|
||||||
private void SetTarget(IntPtr actorAddress, int offset)
|
|
||||||
{
|
|
||||||
if (this.address.TargetManager == IntPtr.Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Marshal.WriteIntPtr(this.address.TargetManager, offset, actorAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
[CanBeNull]
|
|
||||||
private Actor GetActorByOffset(int offset)
|
|
||||||
{
|
|
||||||
if (this.address.TargetManager == IntPtr.Zero)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var actorAddress = Marshal.ReadIntPtr(this.address.TargetManager + offset);
|
|
||||||
if (actorAddress == IntPtr.Zero)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return this.dalamud.ClientState.Actors.CreateActorReference(actorAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Memory offsets for the <see cref="Targets"/> type.
|
|
||||||
/// </summary>
|
|
||||||
public static class TargetOffsets
|
|
||||||
{
|
|
||||||
public const int CurrentTarget = 0x80;
|
|
||||||
public const int SoftTarget = 0x88;
|
|
||||||
public const int MouseOverTarget = 0xD0;
|
|
||||||
public const int FocusTarget = 0xF8;
|
|
||||||
public const int PreviousTarget = 0x110;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Structs;
|
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
using Dalamud.Memory;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents a basic actor (GameObject) in FFXIV.
|
|
||||||
/// </summary>
|
|
||||||
public unsafe partial class Actor : IEquatable<Actor>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Actor"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
internal Actor(IntPtr address, Dalamud dalamud)
|
|
||||||
{
|
|
||||||
this.Dalamud = dalamud;
|
|
||||||
this.Address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the address of the actor in memory.
|
|
||||||
/// </summary>
|
|
||||||
public IntPtr Address { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets Dalamud itself.
|
|
||||||
/// </summary>
|
|
||||||
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>
|
|
||||||
/// Gets the displayname of this <see cref="Actor" />.
|
|
||||||
/// </summary>
|
|
||||||
public SeString Name => MemoryHelper.ReadSeString(this.Address + ActorOffsets.Name, 32);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the actor ID of this <see cref="Actor" />.
|
|
||||||
/// </summary>
|
|
||||||
public uint ActorId => *(uint*)(this.Address + ActorOffsets.ActorId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the data ID for linking to other respective game data.
|
|
||||||
/// </summary>
|
|
||||||
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>
|
|
||||||
/// Gets the entity kind of this <see cref="Actor" />.
|
|
||||||
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
|
||||||
/// </summary>
|
|
||||||
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>
|
|
||||||
/// Gets the X distance from the local player in yalms.
|
|
||||||
/// </summary>
|
|
||||||
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>
|
|
||||||
/// Gets the Y distance from the local player in yalms.
|
|
||||||
/// </summary>
|
|
||||||
public byte YalmDistanceY => *(byte*)(this.Address + ActorOffsets.YalmDistanceFromObjectY);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the position of this <see cref="Actor" />.
|
|
||||||
/// </summary>
|
|
||||||
public Position3 Position => *(Position3*)(this.Address + ActorOffsets.Position);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the rotation of this <see cref="Actor" />.
|
|
||||||
/// This ranges from -pi to pi radians.
|
|
||||||
/// </summary>
|
|
||||||
public float Rotation => *(float*)(this.Address + ActorOffsets.Rotation);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the hitbox radius of this <see cref="Actor" />.
|
|
||||||
/// </summary>
|
|
||||||
public float HitboxRadius => *(float*)(this.Address + ActorOffsets.HitboxRadius);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current target of the Actor.
|
|
||||||
/// </summary>
|
|
||||||
public virtual uint TargetActorID => 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
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,124 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
|
||||||
using Dalamud.Game.ClientState.Structs;
|
|
||||||
using Dalamud.Memory;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents the base for non-static entities.
|
|
||||||
/// </summary>
|
|
||||||
public unsafe class Chara : Actor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Chara"/> class.
|
|
||||||
/// This represents a non-static entity.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
internal Chara(IntPtr address, Dalamud dalamud)
|
|
||||||
: base(address, dalamud)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current HP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentHp => *(uint*)(this.Address + ActorOffsets.CurrentHp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the maximum HP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxHp => *(uint*)(this.Address + ActorOffsets.MaxHp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current MP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentMp => *(uint*)(this.Address + ActorOffsets.CurrentMp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the maximum MP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxMp => *(uint*)(this.Address + ActorOffsets.MaxMp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current GP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentGp => *(uint*)(this.Address + ActorOffsets.CurrentGp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the maximum GP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxGp => *(uint*)(this.Address + ActorOffsets.MaxGp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current CP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint CurrentCp => *(uint*)(this.Address + ActorOffsets.CurrentCp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the maximum CP of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public uint MaxCp => *(uint*)(this.Address + ActorOffsets.MaxCp);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the ClassJob of this Chara.
|
|
||||||
/// </summary>
|
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> 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>
|
|
||||||
/// Gets a byte array describing the visual appearance of this Chara.
|
|
||||||
/// Indexed by <see cref="CustomizeIndex"/>.
|
|
||||||
/// </summary>
|
|
||||||
public byte[] Customize => MemoryHelper.Read<byte>(this.Address + ActorOffsets.Customize, 28);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the status flags.
|
|
||||||
/// </summary>
|
|
||||||
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, 30, 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,26 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents an EventObj.
|
|
||||||
/// </summary>
|
|
||||||
public unsafe class EventObj : Actor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
|
||||||
/// Set up a new EventObj with the provided memory representation.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="address">The address of this actor in memory.</param>
|
|
||||||
/// <param name="dalamud">A dalamud reference needed to access game data in Resolvers.</param>
|
|
||||||
internal EventObj(IntPtr address, Dalamud dalamud)
|
|
||||||
: base(address, dalamud)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the event object ID of the linking to their respective game data.
|
|
||||||
/// </summary>
|
|
||||||
public uint EventObjectId => *(uint*)(this.Address + ActorOffsets.DataId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
using Dalamud.Memory;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents a party member.
|
|
||||||
/// </summary>
|
|
||||||
public class PartyMember
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="table">The ActorTable instance.</param>
|
|
||||||
/// <param name="rawData">The interop data struct.</param>
|
|
||||||
public PartyMember(ActorTable table, Structs.PartyMember rawData)
|
|
||||||
{
|
|
||||||
this.CharacterName = MemoryHelper.ReadSeString(rawData.namePtr);
|
|
||||||
this.Unknown = rawData.unknown;
|
|
||||||
this.Actor = null;
|
|
||||||
|
|
||||||
for (var i = 0; i < table.Length; i++)
|
|
||||||
{
|
|
||||||
if (table[i] != null && table[i].ActorId == rawData.actorId)
|
|
||||||
{
|
|
||||||
this.Actor = table[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
188
Dalamud/Game/ClientState/Buddy/BuddyList.cs
Normal file
188
Dalamud/Game/ClientState/Buddy/BuddyList.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Buddy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the buddies present in your squadron or trust party.
|
||||||
|
/// It does not include the local player.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class BuddyList
|
||||||
|
{
|
||||||
|
private const uint InvalidObjectID = 0xE0000000;
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BuddyList"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
/// <param name="addressResolver">Client state address resolver.</param>
|
||||||
|
internal BuddyList(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.address = addressResolver;
|
||||||
|
|
||||||
|
Log.Verbose($"Buddy list address 0x{this.address.BuddyList.ToInt64():X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of battle buddies the local player has.
|
||||||
|
/// </summary>
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
for (; i < 3; i++)
|
||||||
|
{
|
||||||
|
var addr = this.GetBattleBuddyMemberAddress(i);
|
||||||
|
var member = this.CreateBuddyMemberReference(addr);
|
||||||
|
if (member == null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the local player's companion is present.
|
||||||
|
/// </summary>
|
||||||
|
public bool CompanionBuddyPresent => this.CompanionBuddy != null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the local player's pet is present.
|
||||||
|
/// </summary>
|
||||||
|
public bool PetBuddyPresent => this.PetBuddy != null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the active companion buddy.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public BuddyMember CompanionBuddy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var addr = this.GetCompanionBuddyMemberAddress();
|
||||||
|
return this.CreateBuddyMemberReference(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the active pet buddy.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public BuddyMember PetBuddy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var addr = this.GetPetBuddyMemberAddress();
|
||||||
|
return this.CreateBuddyMemberReference(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the buddy list.
|
||||||
|
/// </summary>
|
||||||
|
internal IntPtr BuddyListAddress => this.address.BuddyList;
|
||||||
|
|
||||||
|
private static int BuddyMemberSize { get; } = Marshal.SizeOf<FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy>();
|
||||||
|
|
||||||
|
private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy*)this.BuddyListAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a battle buddy at the specified spawn index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Spawn index.</param>
|
||||||
|
/// <returns>A <see cref="BuddyMember"/> at the specified spawn index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public BuddyMember this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var address = this.GetBattleBuddyMemberAddress(index);
|
||||||
|
return this.CreateBuddyMemberReference(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the companion buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The memory address of the companion buddy.</returns>
|
||||||
|
public unsafe IntPtr GetCompanionBuddyMemberAddress()
|
||||||
|
{
|
||||||
|
return (IntPtr)(&this.BuddyListStruct->Companion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the pet buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The memory address of the pet buddy.</returns>
|
||||||
|
public unsafe IntPtr GetPetBuddyMemberAddress()
|
||||||
|
{
|
||||||
|
return (IntPtr)(&this.BuddyListStruct->Pet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the battle buddy at the specified index of the buddy list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the battle buddy.</param>
|
||||||
|
/// <returns>The memory address of the battle buddy.</returns>
|
||||||
|
public unsafe IntPtr GetBattleBuddyMemberAddress(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= 3)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return (IntPtr)(this.BuddyListStruct->BattleBuddies + (index * BuddyMemberSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to a buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the buddy in memory.</param>
|
||||||
|
/// <returns><see cref="BuddyMember"/> object containing the requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public BuddyMember CreateBuddyMemberReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var buddy = new BuddyMember(address, this.dalamud);
|
||||||
|
if (buddy.ObjectId == InvalidObjectID)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return buddy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the buddies present in your squadron or trust party.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class BuddyList : IReadOnlyCollection<BuddyMember>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IReadOnlyCollection<BuddyMember>.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerator<BuddyMember> GetEnumerator()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < this.Length; i++)
|
||||||
|
{
|
||||||
|
yield return this[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
78
Dalamud/Game/ClientState/Buddy/BuddyMember.cs
Normal file
78
Dalamud/Game/ClientState/Buddy/BuddyMember.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Buddy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a buddy such as the chocobo companion, summoned pets, squadron groups and trust parties.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class BuddyMember
|
||||||
|
{
|
||||||
|
private Dalamud dalamud;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BuddyMember"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Buddy address.</param>
|
||||||
|
/// <param name="dalamud">Dalamud instance.</param>
|
||||||
|
internal BuddyMember(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.Address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the buddy in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the object ID of this buddy.
|
||||||
|
/// </summary>
|
||||||
|
public uint ObjectId => this.Struct->ObjectID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor associated with this buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject Actor => this.dalamud.ClientState.Objects.SearchByID(this.ObjectId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current health of this buddy.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentHP => this.Struct->CurrentHealth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum health of this buddy.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxHP => this.Struct->MaxHealth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the data ID of this buddy.
|
||||||
|
/// </summary>
|
||||||
|
public uint DataID => this.Struct->DataID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Mount data related to this buddy. It should only be used with companion buddies.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.Mount> MountData => new(this.DataID, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Pet data related to this buddy. It should only be used with pet buddies.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.Pet> PetData => new(this.DataID, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Trust data related to this buddy. It should only be used with battle buddies.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.DawnGrowMember> TrustData => new(this.DataID, this.dalamud);
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors;
|
using Dalamud.Game.ClientState.Buddy;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Fates;
|
using Dalamud.Game.ClientState.Fates;
|
||||||
using Dalamud.Game.ClientState.GamePad;
|
using Dalamud.Game.ClientState.GamePad;
|
||||||
|
using Dalamud.Game.ClientState.JobGauge;
|
||||||
using Dalamud.Game.ClientState.Keys;
|
using Dalamud.Game.ClientState.Keys;
|
||||||
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using Dalamud.Game.ClientState.Party;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
@ -18,7 +19,7 @@ namespace Dalamud.Game.ClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents the state of the game client at the time of access.
|
/// This class represents the state of the game client at the time of access.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class ClientState : INotifyPropertyChanged, IDisposable
|
public sealed class ClientState : IDisposable
|
||||||
{
|
{
|
||||||
private readonly Dalamud dalamud;
|
private readonly Dalamud dalamud;
|
||||||
private readonly ClientStateAddressResolver address;
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
@ -43,12 +44,14 @@ namespace Dalamud.Game.ClientState
|
||||||
|
|
||||||
this.ClientLanguage = startInfo.Language;
|
this.ClientLanguage = startInfo.Language;
|
||||||
|
|
||||||
this.Actors = new ActorTable(dalamud, this.address);
|
this.Objects = new ObjectTable(dalamud, this.address);
|
||||||
|
|
||||||
this.Fates = new FateTable(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.BuddyList = new BuddyList(dalamud, this.address);
|
||||||
|
|
||||||
this.JobGauges = new JobGauges(this.address);
|
this.JobGauges = new JobGauges(this.address);
|
||||||
|
|
||||||
this.KeyState = new KeyState(this.address, scanner.Module.BaseAddress);
|
this.KeyState = new KeyState(this.address, scanner.Module.BaseAddress);
|
||||||
|
|
@ -70,13 +73,6 @@ namespace Dalamud.Game.ClientState
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
private delegate IntPtr SetupTerritoryTypeDelegate(IntPtr manager, ushort terriType);
|
private delegate IntPtr SetupTerritoryTypeDelegate(IntPtr manager, ushort terriType);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Event that fires when a property changes.
|
|
||||||
/// </summary>
|
|
||||||
#pragma warning disable CS0067
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
|
||||||
#pragma warning restore
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that gets fired when the current Territory changes.
|
/// Event that gets fired when the current Territory changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -85,12 +81,12 @@ namespace Dalamud.Game.ClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that fires when a character is logging in.
|
/// Event that fires when a character is logging in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnLogin;
|
public event EventHandler Login;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that fires when a character is logging out.
|
/// Event that fires when a character is logging out.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler OnLogout;
|
public event EventHandler Logout;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that gets fired when a duty is ready.
|
/// Event that gets fired when a duty is ready.
|
||||||
|
|
@ -100,7 +96,7 @@ namespace Dalamud.Game.ClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the table of all present actors.
|
/// Gets the table of all present actors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ActorTable Actors { get; }
|
public ObjectTable Objects { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the table of all present fates.
|
/// Gets the table of all present fates.
|
||||||
|
|
@ -122,6 +118,11 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PartyList PartyList { get; }
|
public PartyList PartyList { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the class facilitating buddy list data access.
|
||||||
|
/// </summary>
|
||||||
|
public BuddyList BuddyList { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets access to the keypress state of keyboard keys in game.
|
/// Gets access to the keypress state of keyboard keys in game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -151,7 +152,7 @@ namespace Dalamud.Game.ClientState
|
||||||
/// 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 => this.Actors[0] as PlayerCharacter;
|
public PlayerCharacter LocalPlayer => this.Objects[0] as PlayerCharacter;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the content ID of the local character.
|
/// Gets the content ID of the local character.
|
||||||
|
|
@ -169,7 +170,6 @@ namespace Dalamud.Game.ClientState
|
||||||
public void Enable()
|
public void Enable()
|
||||||
{
|
{
|
||||||
this.GamepadState.Enable();
|
this.GamepadState.Enable();
|
||||||
this.PartyList.Enable();
|
|
||||||
this.setupTerritoryTypeHook.Enable();
|
this.setupTerritoryTypeHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,7 +178,6 @@ namespace Dalamud.Game.ClientState
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
this.PartyList.Dispose();
|
|
||||||
this.setupTerritoryTypeHook.Dispose();
|
this.setupTerritoryTypeHook.Dispose();
|
||||||
this.GamepadState.Dispose();
|
this.GamepadState.Dispose();
|
||||||
|
|
||||||
|
|
@ -208,7 +207,7 @@ namespace Dalamud.Game.ClientState
|
||||||
Log.Debug("Is login");
|
Log.Debug("Is login");
|
||||||
this.lastConditionNone = false;
|
this.lastConditionNone = false;
|
||||||
this.IsLoggedIn = true;
|
this.IsLoggedIn = true;
|
||||||
this.OnLogin?.Invoke(this, null);
|
this.Login?.Invoke(this, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.Condition.Any() && this.lastConditionNone == false)
|
if (!this.Condition.Any() && this.lastConditionNone == false)
|
||||||
|
|
@ -216,7 +215,7 @@ namespace Dalamud.Game.ClientState
|
||||||
Log.Debug("Is logout");
|
Log.Debug("Is logout");
|
||||||
this.lastConditionNone = true;
|
this.lastConditionNone = true;
|
||||||
this.IsLoggedIn = false;
|
this.IsLoggedIn = false;
|
||||||
this.OnLogout?.Invoke(this, null);
|
this.Logout?.Invoke(this, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.Internal;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState
|
namespace Dalamud.Game.ClientState
|
||||||
{
|
{
|
||||||
|
|
@ -15,17 +12,25 @@ namespace Dalamud.Game.ClientState
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the actor table.
|
/// Gets the address of the actor table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr ActorTable { get; private set; }
|
public IntPtr ObjectTable { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the fate table pointer.
|
/// Gets the address of the buddy list.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr BuddyList { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of a pointer to the fate table.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This is a static address to a pointer, not the address of the table itself.
|
/// This is a static address to a pointer, not the address of the table itself.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public IntPtr FateTablePtr { get; private set; }
|
public IntPtr FateTablePtr { get; private set; }
|
||||||
|
|
||||||
// public IntPtr ViewportActorTable { get; private set; }
|
/// <summary>
|
||||||
|
/// Gets the address of the Group Manager.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr GroupManager { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the local content id.
|
/// Gets the address of the local content id.
|
||||||
|
|
@ -75,12 +80,16 @@ namespace Dalamud.Game.ClientState
|
||||||
// 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.ObjectTable = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 44 0F B6 83");
|
||||||
|
|
||||||
|
this.BuddyList = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 45 84 E4 75 1A F6 45 12 04");
|
||||||
|
|
||||||
this.FateTablePtr = sig.GetStaticAddressFromSig("48 8B 15 ?? ?? ?? ?? 48 8B F9 44 0F B7 41 ??");
|
this.FateTablePtr = sig.GetStaticAddressFromSig("48 8B 15 ?? ?? ?? ?? 48 8B F9 44 0F B7 41 ??");
|
||||||
|
|
||||||
|
this.GroupManager = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 80 B8 ?? ?? ?? ?? ?? 76 50");
|
||||||
|
|
||||||
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("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 43") + 0x8;
|
||||||
|
|
||||||
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 ?? ?? ?? ??");
|
||||||
|
|
||||||
|
|
@ -88,11 +97,9 @@ namespace Dalamud.Game.ClientState
|
||||||
// so GetStaticAddressFromSig() can't be used. lea rcx, ds:1DB9F74h[rax*4]
|
// 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 ?? ?? ?? ??");
|
|
||||||
|
|
||||||
this.ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01 48 83 C4 30");
|
this.ConditionFlags = sig.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? BA ?? ?? ?? ?? E8 ?? ?? ?? ?? B0 01 48 83 C4 30");
|
||||||
|
|
||||||
this.TargetManager = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? FF 50 ?? 48 85 DB", 3);
|
this.TargetManager = sig.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 8D 0D ?? ?? ?? ?? FF 50 ?? 48 85 DB");
|
||||||
|
|
||||||
this.GamepadPoll = sig.ScanText("40 ?? 57 41 ?? 48 81 EC ?? ?? ?? ?? 44 0F ?? ?? ?? ?? ?? ?? ?? 48 8B");
|
this.GamepadPoll = sig.ScanText("40 ?? 57 41 ?? 48 81 EC ?? ?? ?? ?? 44 0F ?? ?? ?? ?? ?? ?? ?? 48 8B");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
Dalamud/Game/ClientState/JobGauge/Enums/BOTDState.cs
Normal file
23
Dalamud/Game/ClientState/JobGauge/Enums/BOTDState.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DRG Blood of the Dragon state types.
|
||||||
|
/// </summary>
|
||||||
|
public enum BOTDState : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Inactive type.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blood of the Dragon is active.
|
||||||
|
/// </summary>
|
||||||
|
BOTD = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Life of the Dragon is active.
|
||||||
|
/// </summary>
|
||||||
|
LOTD = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
53
Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs
Normal file
53
Dalamud/Game/ClientState/JobGauge/Enums/CardType.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// AST Arcanum (card) types.
|
||||||
|
/// </summary>
|
||||||
|
public enum CardType : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No card.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Balance card.
|
||||||
|
/// </summary>
|
||||||
|
BALANCE = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Bole card.
|
||||||
|
/// </summary>
|
||||||
|
BOLE = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Arrow card.
|
||||||
|
/// </summary>
|
||||||
|
ARROW = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Spear card.
|
||||||
|
/// </summary>
|
||||||
|
SPEAR = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Ewer card.
|
||||||
|
/// </summary>
|
||||||
|
EWER = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Spire card.
|
||||||
|
/// </summary>
|
||||||
|
SPIRE = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Lord of Crowns card.
|
||||||
|
/// </summary>
|
||||||
|
LORD = 0x70,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Lady of Crowns card.
|
||||||
|
/// </summary>
|
||||||
|
LADY = 0x80,
|
||||||
|
}
|
||||||
|
}
|
||||||
18
Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs
Normal file
18
Dalamud/Game/ClientState/JobGauge/Enums/DismissedFairy.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SCH Dismissed fairy types.
|
||||||
|
/// </summary>
|
||||||
|
public enum DismissedFairy : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dismissed fairy is Eos.
|
||||||
|
/// </summary>
|
||||||
|
EOS = 6,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dismissed fairy is Selene.
|
||||||
|
/// </summary>
|
||||||
|
SELENE = 7,
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs
Normal file
23
Dalamud/Game/ClientState/JobGauge/Enums/Mudras.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// NIN Mudra types.
|
||||||
|
/// </summary>
|
||||||
|
public enum Mudras : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Ten mudra.
|
||||||
|
/// </summary>
|
||||||
|
TEN = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chi mudra.
|
||||||
|
/// </summary>
|
||||||
|
CHI = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Jin mudra.
|
||||||
|
/// </summary>
|
||||||
|
JIN = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs
Normal file
28
Dalamud/Game/ClientState/JobGauge/Enums/PetGlam.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SMN summoned pet glam types.
|
||||||
|
/// </summary>
|
||||||
|
public enum PetGlam : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No pet glam.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Emerald carbuncle pet glam.
|
||||||
|
/// </summary>
|
||||||
|
EMERALD = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Topaz carbuncle pet glam.
|
||||||
|
/// </summary>
|
||||||
|
TOPAZ = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ruby carbuncle pet glam.
|
||||||
|
/// </summary>
|
||||||
|
RUBY = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Dalamud/Game/ClientState/JobGauge/Enums/SealType.cs
Normal file
28
Dalamud/Game/ClientState/JobGauge/Enums/SealType.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// AST Divination seal types.
|
||||||
|
/// </summary>
|
||||||
|
public enum SealType : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No seal.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sun seal.
|
||||||
|
/// </summary>
|
||||||
|
SUN = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Moon seal.
|
||||||
|
/// </summary>
|
||||||
|
MOON = 2,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Celestial seal.
|
||||||
|
/// </summary>
|
||||||
|
CELESTIAL = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
31
Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs
Normal file
31
Dalamud/Game/ClientState/JobGauge/Enums/Sen.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Samurai Sen types.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
public enum Sen : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No Sen.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setsu Sen type.
|
||||||
|
/// </summary>
|
||||||
|
SETSU = 1 << 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Getsu Sen type.
|
||||||
|
/// </summary>
|
||||||
|
GETSU = 1 << 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ka Sen type.
|
||||||
|
/// </summary>
|
||||||
|
KA = 1 << 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Dalamud/Game/ClientState/JobGauge/Enums/Song.cs
Normal file
28
Dalamud/Game/ClientState/JobGauge/Enums/Song.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// BRD Song types.
|
||||||
|
/// </summary>
|
||||||
|
public enum Song : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No song is active type.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mage's Ballad type.
|
||||||
|
/// </summary>
|
||||||
|
MAGE = 5,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Army's Paeon type.
|
||||||
|
/// </summary>
|
||||||
|
ARMY = 10,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Wanderer's Minuet type.
|
||||||
|
/// </summary>
|
||||||
|
WANDERER = 15,
|
||||||
|
}
|
||||||
|
}
|
||||||
28
Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs
Normal file
28
Dalamud/Game/ClientState/JobGauge/Enums/SummonPet.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Enums
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SMN summoned pet types.
|
||||||
|
/// </summary>
|
||||||
|
public enum SummonPet : byte
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// No pet.
|
||||||
|
/// </summary>
|
||||||
|
NONE = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The summoned pet Ifrit.
|
||||||
|
/// </summary>
|
||||||
|
IFRIT = 3,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The summoned pet Titan.
|
||||||
|
/// </summary>
|
||||||
|
TITAN = 4,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The summoned pet Garuda.
|
||||||
|
/// </summary>
|
||||||
|
GARUDA = 5,
|
||||||
|
}
|
||||||
|
}
|
||||||
50
Dalamud/Game/ClientState/JobGauge/JobGauges.cs
Normal file
50
Dalamud/Game/ClientState/JobGauge/JobGauges.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class converts in-memory Job gauge data to structs.
|
||||||
|
/// </summary>
|
||||||
|
public class JobGauges
|
||||||
|
{
|
||||||
|
private Dictionary<Type, JobGaugeBase> cache = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="JobGauges"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="addressResolver">Address resolver with the JobGauge memory location(s).</param>
|
||||||
|
public JobGauges(ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.Address = addressResolver.JobGaugeData;
|
||||||
|
|
||||||
|
Log.Verbose($"JobGaugeData address 0x{this.Address.ToInt64():X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the JobGauge data.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the JobGauge for a given job.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">A JobGauge struct from ClientState.Structs.JobGauge.</typeparam>
|
||||||
|
/// <returns>A JobGauge.</returns>
|
||||||
|
public T Get<T>() where T : JobGaugeBase
|
||||||
|
{
|
||||||
|
// This is cached to mitigate the effects of using activator for instantiation.
|
||||||
|
// Since the gauge itself reads from live memory, there isn't much downside to doing this.
|
||||||
|
if (!this.cache.TryGetValue(typeof(T), out var gauge))
|
||||||
|
{
|
||||||
|
gauge = this.cache[typeof(T)] = (T)Activator.CreateInstance(typeof(T), BindingFlags.NonPublic | BindingFlags.Instance, null, new object[] { this.Address }, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (T)gauge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs
Normal file
40
Dalamud/Game/ClientState/JobGauge/Types/ASTGauge.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory AST job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class ASTGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.AstrologianGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ASTGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal ASTGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the currently drawn <see cref="CardType"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Currently drawn <see cref="CardType"/>.</returns>
|
||||||
|
public CardType DrawnCard => (CardType)this.Struct->Card;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if a <see cref="SealType"/> is currently active on the divination gauge.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="seal">The <see cref="SealType"/> to check for.</param>
|
||||||
|
/// <returns>If the given Seal is currently divined.</returns>
|
||||||
|
public unsafe bool ContainsSeal(SealType seal)
|
||||||
|
{
|
||||||
|
if (this.Struct->Seals[0] == (byte)seal) return true;
|
||||||
|
if (this.Struct->Seals[1] == (byte)seal) return true;
|
||||||
|
if (this.Struct->Seals[2] == (byte)seal) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs
Normal file
67
Dalamud/Game/ClientState/JobGauge/Types/BLMGauge.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory BLM job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class BLMGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.BlackMageGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BLMGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal BLMGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for the Enochian time in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short EnochianTimer => this.Struct->EnochianTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for Astral Fire or Umbral Ice in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short ElementTimeRemaining => this.Struct->ElementTimeRemaining;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of Polyglot stacks remaining.
|
||||||
|
/// </summary>
|
||||||
|
public byte PolyglotStacks => this.Struct->PolyglotStacks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of Umbral Hearts remaining.
|
||||||
|
/// </summary>
|
||||||
|
public byte UmbralHearts => this.Struct->UmbralHearts;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Umbral Ice stacks.
|
||||||
|
/// </summary>
|
||||||
|
public byte UmbralIceStacks => (byte)(this.InUmbralIce ? -this.Struct->ElementStance : 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Astral Fire stacks.
|
||||||
|
/// </summary>
|
||||||
|
public byte AstralFireStacks => (byte)(this.InAstralFire ? this.Struct->ElementStance : 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether if the player is in Umbral Ice.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool InUmbralIce => this.Struct->ElementStance < 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether if the player is in Astral fire.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool InAstralFire => this.Struct->ElementStance > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether if Enochian is active.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsEnochianActive => this.Struct->Enochian != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs
Normal file
41
Dalamud/Game/ClientState/JobGauge/Types/BRDGauge.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory BRD job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class BRDGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.BardGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BRDGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal BRDGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current song timer in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short SongTimer => this.Struct->SongTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Repertoire accumulated.
|
||||||
|
/// </summary>
|
||||||
|
public byte Repertoire => this.Struct->Repertoire;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Soul Voice accumulated.
|
||||||
|
/// </summary>
|
||||||
|
public byte SoulVoice => this.Struct->SoulVoice;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the type of song that is active.
|
||||||
|
/// </summary>
|
||||||
|
public Song Song => (Song)this.Struct->Song;
|
||||||
|
}
|
||||||
|
}
|
||||||
46
Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs
Normal file
46
Dalamud/Game/ClientState/JobGauge/Types/DNCGauge.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory DNC job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class DNCGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.DancerGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DNCGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal DNCGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of feathers available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Feathers => this.Struct->Feathers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Espirit available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Esprit => this.Struct->Esprit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of steps completed for the current dance.
|
||||||
|
/// </summary>
|
||||||
|
public byte CompletedSteps => this.Struct->StepIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the next step in the current dance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The next dance step action ID.</returns>
|
||||||
|
public ulong NextStep => (ulong)(15999 + this.Struct->DanceSteps[this.Struct->StepIndex] - 1);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the player is dancing or not.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsDancing => this.Struct->DanceSteps[0] != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs
Normal file
36
Dalamud/Game/ClientState/JobGauge/Types/DRGGauge.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory DRG job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class DRGGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.DragoonGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DRGGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal DRGGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for Blood of the Dragon in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short BOTDTimer => this.Struct->BotdTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current state of Blood of the Dragon.
|
||||||
|
/// </summary>
|
||||||
|
public BOTDState BOTDState => (BOTDState)this.Struct->BotdState;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the count of eyes opened during Blood of the Dragon.
|
||||||
|
/// </summary>
|
||||||
|
public byte EyeCount => this.Struct->EyeCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs
Normal file
40
Dalamud/Game/ClientState/JobGauge/Types/DRKGauge.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory DRK job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class DRKGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.DarkKnightGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DRKGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal DRKGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of blood accumulated.
|
||||||
|
/// </summary>
|
||||||
|
public byte Blood => this.Struct->Blood;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Darkside time remaining in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public ushort DarksideTimeRemaining => this.Struct->DarksideTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Shadow time remaining in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public ushort ShadowTimeRemaining => this.Struct->ShadowTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the player has Dark Arts or not.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool HasDarkArts => this.Struct->DarkArtsState > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs
Normal file
34
Dalamud/Game/ClientState/JobGauge/Types/GNBGauge.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory GNB job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class GNBGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.GunbreakerGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GNBGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal GNBGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of ammo available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Ammo => this.Struct->Ammo;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the max combo time of the Gnashing Fang combo.
|
||||||
|
/// </summary>
|
||||||
|
public short MaxTimerDuration => this.Struct->MaxTimerDuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current step of the Gnashing Fang combo.
|
||||||
|
/// </summary>
|
||||||
|
public byte AmmoComboStep => this.Struct->AmmoComboStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs
Normal file
24
Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base job gauge class.
|
||||||
|
/// </summary>
|
||||||
|
public abstract unsafe class JobGaugeBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="JobGaugeBase"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal JobGaugeBase(IntPtr address)
|
||||||
|
{
|
||||||
|
this.Address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of this job gauge in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs
Normal file
25
Dalamud/Game/ClientState/JobGauge/Types/JobGaugeBase{T}.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base job gauge class.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The underlying FFXIVClientStructs type.</typeparam>
|
||||||
|
public unsafe class JobGaugeBase<T> : JobGaugeBase where T : unmanaged
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="JobGaugeBase{T}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal JobGaugeBase(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an unsafe struct pointer of this job gauge.
|
||||||
|
/// </summary>
|
||||||
|
private protected T* Struct => (T*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
56
Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs
Normal file
56
Dalamud/Game/ClientState/JobGauge/Types/MCHGauge.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory MCH job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class MCHGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.MachinistGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MCHGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal MCHGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time time remaining for Overheat in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short OverheatTimeRemaining => this.Struct->OverheatTimeRemaining;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for the Rook or Queen in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short SummonTimeRemaining => this.Struct->SummonTimeRemaining;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current Heat level.
|
||||||
|
/// </summary>
|
||||||
|
public byte Heat => this.Struct->Heat;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current Battery level.
|
||||||
|
/// </summary>
|
||||||
|
public byte Battery => this.Struct->Battery;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the battery level of the last summon (robot).
|
||||||
|
/// </summary>
|
||||||
|
public byte LastSummonBatteryPower => this.Struct->LastSummonBatteryPower;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the player is currently Overheated.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsOverheated => (this.Struct->TimerActive & 1) != 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the player has an active Robot.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsRobotActive => (this.Struct->TimerActive & 2) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs
Normal file
24
Dalamud/Game/ClientState/JobGauge/Types/MNKGauge.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory MNK job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class MNKGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.MonkGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="MNKGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal MNKGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of Chakra available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Chakra => this.Struct->Chakra;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs
Normal file
34
Dalamud/Game/ClientState/JobGauge/Types/NINGauge.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory NIN job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class NINGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.NinjaGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="NINGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the gauge.</param>
|
||||||
|
internal NINGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time left on Huton in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public int HutonTimer => this.Struct->HutonTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Ninki available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Ninki => this.Struct->Ninki;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of times Huton has been cast manually.
|
||||||
|
/// </summary>
|
||||||
|
public byte HutonManualCasts => this.Struct->HutonManualCasts;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs
Normal file
24
Dalamud/Game/ClientState/JobGauge/Types/PLDGauge.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory PLD job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class PLDGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.PaladinGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PLDGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal PLDGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current level of the Oath gauge.
|
||||||
|
/// </summary>
|
||||||
|
public byte OathGauge => this.Struct->OathGauge;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs
Normal file
29
Dalamud/Game/ClientState/JobGauge/Types/RDMGauge.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory RDM job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class RDMGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.RedMageGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="RDMGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal RDMGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of the White gauge.
|
||||||
|
/// </summary>
|
||||||
|
public byte WhiteMana => this.Struct->WhiteMana;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of the Black gauge.
|
||||||
|
/// </summary>
|
||||||
|
public byte BlackMana => this.Struct->BlackMana;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs
Normal file
54
Dalamud/Game/ClientState/JobGauge/Types/SAMGauge.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory SAM job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class SAMGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.SamuraiGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SAMGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal SAMGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current amount of Kenki available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Kenki => this.Struct->Kenki;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Meditation stacks.
|
||||||
|
/// </summary>
|
||||||
|
public byte MeditationStacks => this.Struct->MeditationStacks;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the active Sen.
|
||||||
|
/// </summary>
|
||||||
|
public Sen Sen => (Sen)this.Struct->SenFlags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the Setsu Sen is active.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool HasSetsu => (this.Sen & Sen.SETSU) != 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the Getsu Sen is active.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool HasGetsu => (this.Sen & Sen.GETSU) != 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the Ka Sen is active.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool HasKa => (this.Sen & Sen.KA) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs
Normal file
41
Dalamud/Game/ClientState/JobGauge/Types/SCHGauge.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory SCH job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class SCHGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.ScholarGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SCHGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal SCHGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of Aetherflow stacks available.
|
||||||
|
/// </summary>
|
||||||
|
public byte Aetherflow => this.Struct->Aetherflow;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current level of the Fairy Gauge.
|
||||||
|
/// </summary>
|
||||||
|
public byte FairyGauge => this.Struct->FairyGauge;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Seraph time remaiSCHg in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short SeraphTimer => this.Struct->SeraphTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the last dismissed fairy.
|
||||||
|
/// </summary>
|
||||||
|
public DismissedFairy DismissedFairy => (DismissedFairy)this.Struct->DismissedFairy;
|
||||||
|
}
|
||||||
|
}
|
||||||
60
Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs
Normal file
60
Dalamud/Game/ClientState/JobGauge/Types/SMNGauge.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.JobGauge.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory SMN job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class SMNGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.SummonerGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="SMNGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal SMNGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining for the current summon.
|
||||||
|
/// </summary>
|
||||||
|
public short TimerRemaining => this.Struct->TimerRemaining;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the summon that will return after the current summon expires.
|
||||||
|
/// </summary>
|
||||||
|
public SummonPet ReturnSummon => (SummonPet)this.Struct->ReturnSummon;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
||||||
|
/// </summary>
|
||||||
|
public PetGlam ReturnSummonGlam => (PetGlam)this.Struct->ReturnSummonGlam;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current aether flags.
|
||||||
|
/// Use the summon accessors instead.
|
||||||
|
/// </summary>
|
||||||
|
public byte AetherFlags => this.Struct->AetherFlags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether if Phoenix is ready to be summoned.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsPhoenixReady => (this.AetherFlags & 0x10) > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether Bahamut is ready to be summoned.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool IsBahamutReady => (this.AetherFlags & 8) > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether there are any Aetherflow stacks available.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><c>true</c> or <c>false</c>.</returns>
|
||||||
|
public bool HasAetherflowStacks => (this.AetherFlags & 3) > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs
Normal file
24
Dalamud/Game/ClientState/JobGauge/Types/WARGauge.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory WAR job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class WARGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.WarriorGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WARGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal WARGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of wrath in the Beast gauge.
|
||||||
|
/// </summary>
|
||||||
|
public byte BeastGauge => this.Struct->BeastGauge;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs
Normal file
34
Dalamud/Game/ClientState/JobGauge/Types/WHMGauge.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.JobGauge.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// In-memory WHM job gauge.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class WHMGauge : JobGaugeBase<FFXIVClientStructs.FFXIV.Client.Game.Gauge.WhiteMageGauge>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WHMGauge"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the job gauge.</param>
|
||||||
|
internal WHMGauge(IntPtr address)
|
||||||
|
: base(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time to next lily in milliseconds.
|
||||||
|
/// </summary>
|
||||||
|
public short LilyTimer => this.Struct->LilyTimer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of Lilies.
|
||||||
|
/// </summary>
|
||||||
|
public byte Lily => this.Struct->Lily;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of times the blood lily has been nourished.
|
||||||
|
/// </summary>
|
||||||
|
public byte BloodLily => this.Struct->BloodLily;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class converts in-memory Job gauge data to structs.
|
|
||||||
/// </summary>
|
|
||||||
public class JobGauges
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="JobGauges"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="addressResolver">Address resolver with the JobGauge memory location(s).</param>
|
|
||||||
public JobGauges(ClientStateAddressResolver addressResolver)
|
|
||||||
{
|
|
||||||
this.Address = addressResolver;
|
|
||||||
|
|
||||||
Log.Verbose($"JobGaugeData address 0x{this.Address.JobGaugeData.ToInt64():X}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private ClientStateAddressResolver Address { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the JobGauge for a given job.
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">A JobGauge struct from ClientState.Structs.JobGauge.</typeparam>
|
|
||||||
/// <returns>A JobGauge.</returns>
|
|
||||||
public T Get<T>()
|
|
||||||
{
|
|
||||||
return Marshal.PtrToStructure<T>(this.Address.JobGaugeData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
namespace Dalamud.Game.ClientState.Objects.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An Enum describing possible BattleNpc kinds.
|
/// An Enum describing possible BattleNpc kinds.
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Objects.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This enum describes the indices of the Customize array.
|
/// This enum describes the indices of the Customize array.
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Objects.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enum describing possible entity kinds.
|
/// Enum describing possible entity kinds.
|
||||||
|
|
@ -6,7 +6,7 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
public enum ObjectKind : byte
|
public enum ObjectKind : byte
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invalid actor.
|
/// Invalid character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
None = 0x00,
|
None = 0x00,
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Objects.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enum describing possible status flags.
|
/// Enum describing possible status flags.
|
||||||
|
|
@ -14,42 +14,42 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
None = 0,
|
None = 0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hostile actor.
|
/// Hostile character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Hostile = 1,
|
Hostile = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor in combat.
|
/// Character in combat.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
InCombat = 2,
|
InCombat = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor weapon is out.
|
/// Character weapon is out.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
WeaponOut = 4,
|
WeaponOut = 4,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor offhand is out.
|
/// Character offhand is out.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
OffhandOut = 8,
|
OffhandOut = 8,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor is a party member.
|
/// Character is a party member.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
PartyMember = 16,
|
PartyMember = 16,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor is a alliance member.
|
/// Character is a alliance member.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
AllianceMember = 32,
|
AllianceMember = 32,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor is in friend list.
|
/// Character is in friend list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Friend = 64,
|
Friend = 64,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Actor is casting.
|
/// Character is casting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IsCasting = 128,
|
IsCasting = 128,
|
||||||
}
|
}
|
||||||
146
Dalamud/Game/ClientState/Objects/ObjectTable.cs
Normal file
146
Dalamud/Game/ClientState/Objects/ObjectTable.cs
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the currently spawned FFXIV game objects.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ObjectTable
|
||||||
|
{
|
||||||
|
private const int ObjectTableLength = 424;
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ObjectTable"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
/// <param name="addressResolver">Client state address resolver.</param>
|
||||||
|
internal ObjectTable(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.address = addressResolver;
|
||||||
|
|
||||||
|
Log.Verbose($"Object table address 0x{this.address.ObjectTable.ToInt64():X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the object table.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address => this.address.ObjectTable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the length of the object table.
|
||||||
|
/// </summary>
|
||||||
|
public int Length => ObjectTableLength;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get an object at the specified spawn index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Spawn index.</param>
|
||||||
|
/// <returns>An <see cref="GameObject"/> at the specified spawn index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var address = this.GetObjectAddress(index);
|
||||||
|
return this.CreateObjectReference(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Search for a game object by their Object ID.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="objectID">Object ID to find.</param>
|
||||||
|
/// <returns>A game object or null.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject SearchByID(uint objectID)
|
||||||
|
{
|
||||||
|
foreach (var obj in this)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (obj.ObjectId == objectID)
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the game object at the specified index of the object table.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the object.</param>
|
||||||
|
/// <returns>The memory address of the object.</returns>
|
||||||
|
public unsafe IntPtr GetObjectAddress(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= ObjectTableLength)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return *(IntPtr*)(this.address.ObjectTable + (8 * index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to an FFXIV game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the object in memory.</param>
|
||||||
|
/// <returns><see cref="GameObject"/> object or inheritor containing the requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public unsafe GameObject CreateObjectReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var obj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)address;
|
||||||
|
var objKind = (ObjectKind)obj->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 GameObject(address, this.dalamud),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the currently spawned FFXIV game objects.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class ObjectTable : IReadOnlyCollection<GameObject>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IReadOnlyCollection<GameObject>.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerator<GameObject> GetEnumerator()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < ObjectTableLength; i++)
|
||||||
|
{
|
||||||
|
var obj = this[i];
|
||||||
|
|
||||||
|
if (obj == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.Types
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a battle NPC.
|
/// This class represents a battle NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class BattleNpc : Npc
|
public unsafe class BattleNpc : BattleChara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
/// Initializes a new instance of the <see cref="BattleNpc"/> class.
|
||||||
|
|
@ -21,11 +23,6 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
||||||
/// <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.Address + ActorOffsets.SubKind);
|
public BattleNpcSubKind BattleNpcKind => (BattleNpcSubKind)this.Struct->Character.GameObject.SubKind;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the target of the Battle NPC.
|
|
||||||
/// </summary>
|
|
||||||
public override uint TargetActorID => *(uint*)(this.Address + ActorOffsets.BattleNpcTargetActorId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
23
Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs
Normal file
23
Dalamud/Game/ClientState/Objects/SubKinds/EventObj.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.SubKinds
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents an EventObj.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class EventObj : GameObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="EventObj"/> class.
|
||||||
|
/// Set up a new EventObj with the provided memory representation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of this event object in memory.</param>
|
||||||
|
/// <param name="dalamud">A dalamud reference.</param>
|
||||||
|
internal EventObj(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.SubKinds
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a NPC.
|
/// This class represents a NPC.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class Npc : Chara
|
public unsafe class Npc : Character
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Npc"/> class.
|
/// Initializes a new instance of the <see cref="Npc"/> class.
|
||||||
|
|
@ -18,14 +20,9 @@ namespace Dalamud.Game.ClientState.Actors.Types.NonPlayer
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the data ID of the NPC linking to their assoicated BNpcBase data.
|
|
||||||
/// </summary>
|
|
||||||
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 uint NameId => *(uint*)(this.Address + ActorOffsets.NameId);
|
public uint NameId => this.Struct->NameID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Resolvers;
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
using Dalamud.Game.Text.SeStringHandling;
|
|
||||||
using Dalamud.Memory;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Actors.Types
|
namespace Dalamud.Game.ClientState.Objects.SubKinds
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class represents a player character.
|
/// This class represents a player character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe class PlayerCharacter : Chara
|
public unsafe class PlayerCharacter : BattleChara
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
/// Initializes a new instance of the <see cref="PlayerCharacter"/> class.
|
||||||
|
|
@ -25,21 +24,16 @@ namespace Dalamud.Game.ClientState.Actors.Types
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
|
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(*(ushort*)(this.Address + ActorOffsets.CurrentWorld), this.Dalamud);
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(this.Struct->Character.CurrentWorld, this.Dalamud);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
|
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(*(ushort*)(this.Address + ActorOffsets.HomeWorld), this.Dalamud);
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(this.Struct->Character.HomeWorld, this.Dalamud);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Free Company tag of this player.
|
|
||||||
/// </summary>
|
|
||||||
public SeString CompanyTag => MemoryHelper.ReadSeString(this.Address + ActorOffsets.CompanyTag, 6);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the target actor ID of the PlayerCharacter.
|
/// Gets the target actor ID of the PlayerCharacter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override uint TargetActorID => *(uint*)(this.Address + ActorOffsets.PlayerCharacterTargetActorId);
|
public override uint TargetObjectId => this.Struct->Character.GameObject.TargetObjectID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
169
Dalamud/Game/ClientState/Objects/Targets.cs
Normal file
169
Dalamud/Game/ClientState/Objects/Targets.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get and set various kinds of targets for the player.
|
||||||
|
/// </summary>
|
||||||
|
public sealed unsafe class Targets
|
||||||
|
{
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Targets"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
/// <param name="addressResolver">The ClientStateAddressResolver instance.</param>
|
||||||
|
internal Targets(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.address = addressResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the target manager.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address => this.address.TargetManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the current target.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject Target
|
||||||
|
{
|
||||||
|
get => this.dalamud.ClientState.Objects.CreateObjectReference((IntPtr)Struct->Target);
|
||||||
|
set => this.SetTarget(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the mouseover target.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject MouseOverTarget
|
||||||
|
{
|
||||||
|
get => this.dalamud.ClientState.Objects.CreateObjectReference((IntPtr)Struct->MouseOverTarget);
|
||||||
|
set => this.SetMouseOverTarget(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the focus target.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject FocusTarget
|
||||||
|
{
|
||||||
|
get => this.dalamud.ClientState.Objects.CreateObjectReference((IntPtr)Struct->FocusTarget);
|
||||||
|
set => this.SetFocusTarget(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the previous target.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject PreviousTarget
|
||||||
|
{
|
||||||
|
get => this.dalamud.ClientState.Objects.CreateObjectReference((IntPtr)Struct->PreviousTarget);
|
||||||
|
set => this.SetPreviousTarget(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the soft target.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject SoftTarget
|
||||||
|
{
|
||||||
|
get => this.dalamud.ClientState.Objects.CreateObjectReference((IntPtr)Struct->SoftTarget);
|
||||||
|
set => this.SetSoftTarget(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.Control.TargetSystem* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Control.TargetSystem*)this.Address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the current target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">Actor to target.</param>
|
||||||
|
public void SetTarget(GameObject actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the mouseover target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">Actor to target.</param>
|
||||||
|
public void SetMouseOverTarget(GameObject actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">Actor to target.</param>
|
||||||
|
public void SetFocusTarget(GameObject actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the previous target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">Actor to target.</param>
|
||||||
|
public void SetPreviousTarget(GameObject actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the soft target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actor">Actor to target.</param>
|
||||||
|
public void SetSoftTarget(GameObject actor) => this.SetTarget(actor?.Address ?? IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the current target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorAddress">Actor (address) to target.</param>
|
||||||
|
public void SetTarget(IntPtr actorAddress) => Struct->Target = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the mouseover target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorAddress">Actor (address) to target.</param>
|
||||||
|
public void SetMouseOverTarget(IntPtr actorAddress) => Struct->MouseOverTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the focus target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorAddress">Actor (address) to target.</param>
|
||||||
|
public void SetFocusTarget(IntPtr actorAddress) => Struct->FocusTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the previous target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorAddress">Actor (address) to target.</param>
|
||||||
|
public void SetPreviousTarget(IntPtr actorAddress) => Struct->PreviousTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the soft target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="actorAddress">Actor (address) to target.</param>
|
||||||
|
public void SetSoftTarget(IntPtr actorAddress) => Struct->SoftTarget = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actorAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the current target.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearTarget() => this.SetTarget(IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the mouseover target.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearMouseOverTarget() => this.SetMouseOverTarget(IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the focus target.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearFocusTarget() => this.SetFocusTarget(IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the previous target.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearPreviousTarget() => this.SetPreviousTarget(IntPtr.Zero);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the soft target.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearSoftTarget() => this.SetSoftTarget(IntPtr.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
68
Dalamud/Game/ClientState/Objects/Types/BattleChara.cs
Normal file
68
Dalamud/Game/ClientState/Objects/Types/BattleChara.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Statuses;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the battle characters.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class BattleChara : Character
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BattleChara"/> class.
|
||||||
|
/// This represents a battle character.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of this character in memory.</param>
|
||||||
|
/// <param name="dalamud">Dalamud itself.</param>
|
||||||
|
internal BattleChara(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current status effects.
|
||||||
|
/// </summary>
|
||||||
|
public StatusList StatusList => new(&this.Struct->StatusManager, this.Dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the chara is currently casting.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCasting => this.Struct->SpellCastInfo.IsCasting > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the cast is interruptible.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsCastInterruptible => this.Struct->SpellCastInfo.Interruptible > 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the spell action type of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public byte CastActionType => (byte)this.Struct->SpellCastInfo.ActionType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the spell action ID of the spell being cast by the actor.
|
||||||
|
/// </summary>
|
||||||
|
public uint CastActionId => this.Struct->SpellCastInfo.ActionID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the object ID of the target currently being cast at by the chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CastTargetObjectId => this.Struct->SpellCastInfo.CastTargetID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current casting time of the spell being cast by the chara.
|
||||||
|
/// </summary>
|
||||||
|
public float CurrentCastTime => this.Struct->SpellCastInfo.CurrentCastTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total casting time of the spell being cast by the chara.
|
||||||
|
/// </summary>
|
||||||
|
public float TotalCastTime => this.Struct->SpellCastInfo.TotalCastTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the underlying structure.
|
||||||
|
/// </summary>
|
||||||
|
private protected new FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Character.BattleChara*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
103
Dalamud/Game/ClientState/Objects/Types/Character.cs
Normal file
103
Dalamud/Game/ClientState/Objects/Types/Character.cs
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents the base for non-static entities.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class Character : GameObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Character"/> class.
|
||||||
|
/// This represents a non-static entity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of this character in memory.</param>
|
||||||
|
/// <param name="dalamud">Dalamud itself.</param>
|
||||||
|
internal Character(IntPtr address, Dalamud dalamud)
|
||||||
|
: base(address, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current HP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentHp => this.Struct->Health;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum HP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxHp => this.Struct->MaxHealth;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current MP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentMp => this.Struct->Mana;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum MP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxMp => this.Struct->MaxMana;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current GP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentGp => this.Struct->GatheringPoints;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum GP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxGp => this.Struct->MaxGatheringPoints;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current CP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentCp => this.Struct->CraftingPoints;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum CP of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxCp => this.Struct->MaxCraftingPoints;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ClassJob of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> ClassJob => new(this.Struct->ClassJob, this.Dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this Chara.
|
||||||
|
/// </summary>
|
||||||
|
public byte Level => this.Struct->Level;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a byte array describing the visual appearance of this Chara.
|
||||||
|
/// Indexed by <see cref="CustomizeIndex"/>.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Customize => MemoryHelper.Read<byte>((IntPtr)this.Struct->CustomizeData, 28);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Free Company tag of this chara.
|
||||||
|
/// </summary>
|
||||||
|
public SeString CompanyTag => MemoryHelper.ReadSeString((IntPtr)this.Struct->FreeCompanyTag, 6);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the target object ID of the character.
|
||||||
|
/// </summary>
|
||||||
|
public override uint TargetObjectId => this.Struct->GameObject.TargetObjectID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the status flags.
|
||||||
|
/// </summary>
|
||||||
|
public StatusFlags StatusFlags => (StatusFlags)this.Struct->StatusFlags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the underlying structure.
|
||||||
|
/// </summary>
|
||||||
|
private protected new FFXIVClientStructs.FFXIV.Client.Game.Character.Character* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Character.Character*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
168
Dalamud/Game/ClientState/Objects/Types/GameObject.cs
Normal file
168
Dalamud/Game/ClientState/Objects/Types/GameObject.cs
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Objects.Types
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a GameObject in FFXIV.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe partial class GameObject : IEquatable<GameObject>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GameObject"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of this game object in memory.</param>
|
||||||
|
/// <param name="dalamud">Dalamud itself.</param>
|
||||||
|
internal GameObject(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.Address = address;
|
||||||
|
this.Dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the game object in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Dalamud instance.
|
||||||
|
/// </summary>
|
||||||
|
private protected Dalamud Dalamud { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This allows you to <c>if (obj) {...}</c> to check for validity.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="gameObject">The actor to check.</param>
|
||||||
|
/// <returns>True or false.</returns>
|
||||||
|
public static implicit operator bool(GameObject? gameObject) => IsValid(gameObject);
|
||||||
|
|
||||||
|
public static bool operator ==(GameObject? gameObject1, GameObject? gameObject2)
|
||||||
|
{
|
||||||
|
// Using == results in a stack overflow.
|
||||||
|
if (gameObject1 is null || gameObject2 is null)
|
||||||
|
return Equals(gameObject1, gameObject2);
|
||||||
|
|
||||||
|
return gameObject1.Equals(gameObject2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(GameObject? actor1, GameObject? 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(GameObject? actor)
|
||||||
|
{
|
||||||
|
if (actor is 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<GameObject>.Equals(GameObject other) => this.ObjectId == other?.ObjectId;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override bool Equals(object obj) => ((IEquatable<GameObject>)this).Equals(obj as GameObject);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public override int GetHashCode() => this.ObjectId.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a basic actor (GameObject) in FFXIV.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe partial class GameObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the name of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public SeString Name => MemoryHelper.ReadSeString((IntPtr)this.Struct->Name, 32);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the object ID of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public uint ObjectId => this.Struct->ObjectID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the data ID for linking to other respective game data.
|
||||||
|
/// </summary>
|
||||||
|
public uint DataId => this.Struct->DataID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of this GameObject's owner.
|
||||||
|
/// </summary>
|
||||||
|
public uint OwnerId => this.Struct->OwnerID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the entity kind of this <see cref="GameObject" />.
|
||||||
|
/// See <see cref="ObjectKind">the ObjectKind enum</see> for possible values.
|
||||||
|
/// </summary>
|
||||||
|
public ObjectKind ObjectKind => (ObjectKind)this.Struct->ObjectKind;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sub kind of this Actor.
|
||||||
|
/// </summary>
|
||||||
|
public byte SubKind => this.Struct->SubKind;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the X distance from the local player in yalms.
|
||||||
|
/// </summary>
|
||||||
|
public byte YalmDistanceX => this.Struct->YalmDistanceFromPlayerX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the Y distance from the local player in yalms.
|
||||||
|
/// </summary>
|
||||||
|
public byte YalmDistanceZ => this.Struct->YalmDistanceFromPlayerZ;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public Vector3 Position => new(this.Struct->Position.X, this.Struct->Position.Y, this.Struct->Position.Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the rotation of this <see cref="GameObject" />.
|
||||||
|
/// This ranges from -pi to pi radians.
|
||||||
|
/// </summary>
|
||||||
|
public float Rotation => this.Struct->Rotation;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hitbox radius of this <see cref="GameObject" />.
|
||||||
|
/// </summary>
|
||||||
|
public float HitboxRadius => this.Struct->HitboxRadius;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current target of the game object.
|
||||||
|
/// </summary>
|
||||||
|
public virtual uint TargetObjectId => 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the target object of the game object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
[CanBeNull]
|
||||||
|
public virtual GameObject TargetObject => this.Dalamud.ClientState.Objects.SearchByID(this.TargetObjectId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the underlying structure.
|
||||||
|
/// </summary>
|
||||||
|
private protected FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
183
Dalamud/Game/ClientState/Party/PartyList.cs
Normal file
183
Dalamud/Game/ClientState/Party/PartyList.cs
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Party
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the actors present in your party or alliance.
|
||||||
|
/// </summary>
|
||||||
|
public sealed unsafe partial class PartyList
|
||||||
|
{
|
||||||
|
private const int GroupLength = 8;
|
||||||
|
private const int AllianceLength = 20;
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
private readonly ClientStateAddressResolver address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PartyList"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
/// <param name="addressResolver">Client state address resolver.</param>
|
||||||
|
internal PartyList(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.address = addressResolver;
|
||||||
|
|
||||||
|
Log.Verbose($"Group manager address 0x{this.address.GroupManager.ToInt64():X}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of party members the local player has.
|
||||||
|
/// </summary>
|
||||||
|
public int Length => this.GroupManagerStruct->MemberCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the index of the party leader.
|
||||||
|
/// </summary>
|
||||||
|
public uint PartyLeaderIndex => this.GroupManagerStruct->PartyLeaderIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether this group is an alliance.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsAlliance => this.GroupManagerStruct->IsAlliance;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the Group Manager.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr GroupManagerAddress => this.address.GroupManager;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the party list within the group manager.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr GroupListAddress => (IntPtr)GroupManagerStruct->PartyMembers;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the alliance member list within the group manager.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr AllianceListAddress => (IntPtr)this.GroupManagerStruct->AllianceMembers;
|
||||||
|
|
||||||
|
private static int PartyMemberSize { get; } = Marshal.SizeOf<FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember>();
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager* GroupManagerStruct => (FFXIVClientStructs.FFXIV.Client.Game.Group.GroupManager*)this.GroupManagerAddress;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a party member at the specified spawn index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Spawn index.</param>
|
||||||
|
/// <returns>A <see cref="PartyMember"/> at the specified spawn index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public PartyMember this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Normally using Length results in a recursion crash, however we know the party size via ptr.
|
||||||
|
if (index < 0 || index >= this.Length)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (this.Length > GroupLength)
|
||||||
|
{
|
||||||
|
var addr = this.GetAllianceMemberAddress(index);
|
||||||
|
return this.CreateAllianceMemberReference(addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var addr = this.GetPartyMemberAddress(index);
|
||||||
|
return this.CreatePartyMemberReference(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the party member at the specified index of the party list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the party member.</param>
|
||||||
|
/// <returns>The memory address of the party member.</returns>
|
||||||
|
public IntPtr GetPartyMemberAddress(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= GroupLength)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return this.GroupListAddress + (index * PartyMemberSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to an FFXIV party member.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the party member in memory.</param>
|
||||||
|
/// <returns>The party member object containing the requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public PartyMember CreatePartyMemberReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new PartyMember(address, this.dalamud);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the alliance member at the specified index of the alliance list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the alliance member.</param>
|
||||||
|
/// <returns>The memory address of the alliance member.</returns>
|
||||||
|
public IntPtr GetAllianceMemberAddress(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= AllianceLength)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return this.AllianceListAddress + (index * PartyMemberSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to an FFXIV alliance member.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the alliance member in memory.</param>
|
||||||
|
/// <returns>The party member object containing the requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public PartyMember CreateAllianceMemberReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new PartyMember(address, this.dalamud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the party members present in your party or alliance.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class PartyList : IReadOnlyCollection<PartyMember>
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IReadOnlyCollection<PartyMember>.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerator<PartyMember> GetEnumerator()
|
||||||
|
{
|
||||||
|
// Normally using Length results in a recursion crash, however we know the party size via ptr.
|
||||||
|
for (var i = 0; i < this.Length; i++)
|
||||||
|
{
|
||||||
|
var member = this[i];
|
||||||
|
|
||||||
|
if (member == null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
yield return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
117
Dalamud/Game/ClientState/Party/PartyMember.cs
Normal file
117
Dalamud/Game/ClientState/Party/PartyMember.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using Dalamud.Game.ClientState.Statuses;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
|
using Dalamud.Memory;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Party
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a party member in the group manager.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class PartyMember
|
||||||
|
{
|
||||||
|
private Dalamud dalamud;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PartyMember"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the party member.</param>
|
||||||
|
/// <param name="dalamud">Dalamud itself.</param>
|
||||||
|
internal PartyMember(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.Address = address;
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of this party member in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a list of buffs or debuffs applied to this party member.
|
||||||
|
/// </summary>
|
||||||
|
public StatusList Statuses => new(&this.Struct->StatusManager, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the position of the party member.
|
||||||
|
/// </summary>
|
||||||
|
public Vector3 Position => new(this.Struct->X, this.Struct->Y, this.Struct->Z);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the content ID of the party member.
|
||||||
|
/// </summary>
|
||||||
|
public long ContentId => this.Struct->ContentID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor ID of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public uint ObjectId => this.Struct->ObjectID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the actor associated with this buddy.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject GameObject => this.dalamud.ClientState.Objects.SearchByID(this.ObjectId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current HP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public uint CurrentHP => this.Struct->CurrentHP;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum HP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public uint MaxHP => this.Struct->MaxHP;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current MP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public ushort CurrentMP => this.Struct->CurrentMP;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum MP of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public ushort MaxMP => this.Struct->MaxMP;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the territory this party member is located in.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.TerritoryType> Territory => new(this.Struct->TerritoryType, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the World this party member resides in.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> World => new(this.Struct->HomeWorld, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the displayname of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public SeString Name => MemoryHelper.ReadSeString((IntPtr)Struct->Name, 0x40);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the sex of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public byte Sex => this.Struct->Sex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the classjob of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public ExcelResolver<Lumina.Excel.GeneratedSheets.ClassJob> ClassJob => new(this.Struct->ClassJob, this.dalamud);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the level of this party member.
|
||||||
|
/// </summary>
|
||||||
|
public byte Level => this.Struct->Level;
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Group.PartyMember*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
// using Dalamud.Hooking;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This class represents the members of your party.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class PartyList
|
|
||||||
{
|
|
||||||
private readonly Dalamud dalamud;
|
|
||||||
private readonly ClientStateAddressResolver address;
|
|
||||||
|
|
||||||
// private bool isReady = false;
|
|
||||||
// private IntPtr partyListBegin;
|
|
||||||
// private Hook<PartyListUpdateDelegate> partyListUpdateHook;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="PartyList"/> class.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dalamud">The Dalamud instance.</param>
|
|
||||||
/// <param name="addressResolver">The ClientStateAddressResolver instance.</param>
|
|
||||||
internal PartyList(Dalamud dalamud, ClientStateAddressResolver addressResolver)
|
|
||||||
{
|
|
||||||
this.address = addressResolver;
|
|
||||||
this.dalamud = dalamud;
|
|
||||||
// this.partyListUpdateHook = new Hook<PartyListUpdateDelegate>(Address.PartyListUpdate, new PartyListUpdateDelegate(PartyListUpdateDetour), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private delegate long PartyListUpdateDelegate(IntPtr structBegin, long param2, char param3);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the length of the PartyList.
|
|
||||||
/// </summary>
|
|
||||||
public int Length => 0; // !this.isReady ? 0 : Marshal.ReadByte(this.partyListBegin + 0xF0);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the nth party member.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="index">Index of the party member.</param>
|
|
||||||
/// <returns>The party member.</returns>
|
|
||||||
public PartyMember this[int index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
// if (!this.isReady)
|
|
||||||
// return null;
|
|
||||||
// if (index >= this.Length)
|
|
||||||
// return null;
|
|
||||||
// var tblIndex = this.partyListBegin + (index * 24);
|
|
||||||
// var memberStruct = Marshal.PtrToStructure<Structs.PartyMember>(tblIndex);
|
|
||||||
// return new PartyMember(this.dalamud.ClientState.Actors, memberStruct);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Enable this module.
|
|
||||||
/// </summary>
|
|
||||||
public void Enable()
|
|
||||||
{
|
|
||||||
// TODO Fix for 5.3
|
|
||||||
// this.partyListUpdateHook.Enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dispose of managed and unmanaged resources.
|
|
||||||
/// </summary>
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
// if (!this.isReady)
|
|
||||||
// this.partyListUpdateHook.Dispose();
|
|
||||||
// this.isReady = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private long PartyListUpdateDetour(IntPtr structBegin, long param2, char param3)
|
|
||||||
// {
|
|
||||||
// var result = this.partyListUpdateHook.Original(structBegin, param2, param3);
|
|
||||||
// this.partyListBegin = structBegin + 0xB48;
|
|
||||||
// this.partyListUpdateHook.Dispose();
|
|
||||||
// this.isReady = true;
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implements IReadOnlyCollection, IEnumerable.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class PartyList : IReadOnlyCollection<PartyMember>
|
|
||||||
{
|
|
||||||
/// <inheritdoc/>
|
|
||||||
int IReadOnlyCollection<PartyMember>.Count => this.Length;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public IEnumerator<PartyMember> GetEnumerator()
|
|
||||||
{
|
|
||||||
for (var i = 0; i < this.Length; i++)
|
|
||||||
{
|
|
||||||
if (this[i] != null)
|
|
||||||
{
|
|
||||||
yield return this[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implements ICollection.
|
|
||||||
/// </summary>
|
|
||||||
public sealed partial class PartyList : ICollection
|
|
||||||
{
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public int Count => this.Length;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public object SyncRoot => this;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public bool IsSynchronized => false;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public void CopyTo(Array array, int index)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < this.Length; i++)
|
|
||||||
{
|
|
||||||
array.SetValue(this[i], index);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
73
Dalamud/Game/ClientState/Statuses/Status.cs
Normal file
73
Dalamud/Game/ClientState/Statuses/Status.cs
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Game.ClientState.Resolvers;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Statuses
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a status effect an actor is afflicted by.
|
||||||
|
/// </summary>
|
||||||
|
public unsafe class Status
|
||||||
|
{
|
||||||
|
private Dalamud dalamud;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="Status"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Status address.</param>
|
||||||
|
/// <param name="dalamud">Dalamud instance.</param>
|
||||||
|
internal Status(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
this.Address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the status in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the status ID of this status.
|
||||||
|
/// </summary>
|
||||||
|
public uint StatusID => this.Struct->StatusID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the GameData associated with this status.
|
||||||
|
/// </summary>
|
||||||
|
public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver<Lumina.Excel.GeneratedSheets.Status>(this.Struct->StatusID, this.dalamud).GameData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the parameter value of the status.
|
||||||
|
/// </summary>
|
||||||
|
public byte Param => this.Struct->Param;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stack count of this status.
|
||||||
|
/// </summary>
|
||||||
|
public byte StackCount => this.Struct->StackCount;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the time remaining of this status.
|
||||||
|
/// </summary>
|
||||||
|
public float RemainingTime => this.Struct->RemainingTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the source ID of this status.
|
||||||
|
/// </summary>
|
||||||
|
public uint SourceID => this.Struct->SourceID;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the source actor associated with this status.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This iterates the actor table, it should be used with care.
|
||||||
|
/// </remarks>
|
||||||
|
[CanBeNull]
|
||||||
|
public GameObject SourceActor => this.dalamud.ClientState.Objects.SearchByID(this.SourceID);
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.Status* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Status*)this.Address;
|
||||||
|
}
|
||||||
|
}
|
||||||
161
Dalamud/Game/ClientState/Statuses/StatusList.cs
Normal file
161
Dalamud/Game/ClientState/Statuses/StatusList.cs
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.ClientState.Statuses
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the status effects an actor is afflicted by.
|
||||||
|
/// </summary>
|
||||||
|
public sealed unsafe partial class StatusList
|
||||||
|
{
|
||||||
|
private const int StatusListLength = 30;
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StatusList"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">Address of the status list.</param>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
internal StatusList(IntPtr address, Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.Address = address;
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="StatusList"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pointer">Pointer to the status list.</param>
|
||||||
|
/// <param name="dalamud">The <see cref="dalamud"/> instance.</param>
|
||||||
|
internal unsafe StatusList(void* pointer, Dalamud dalamud)
|
||||||
|
: this((IntPtr)pointer, dalamud)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the status list in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr Address { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the amount of status effects the actor has.
|
||||||
|
/// </summary>
|
||||||
|
public int Length
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
for (; i < StatusListLength; i++)
|
||||||
|
{
|
||||||
|
var status = this[i];
|
||||||
|
if (status == null || status.StatusID == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int StatusSize { get; } = Marshal.SizeOf<FFXIVClientStructs.FFXIV.Client.Game.Status>();
|
||||||
|
|
||||||
|
private FFXIVClientStructs.FFXIV.Client.Game.StatusManager* Struct => (FFXIVClientStructs.FFXIV.Client.Game.StatusManager*)this.Address;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a status effect at the specified index.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">Status Index.</param>
|
||||||
|
/// <returns>The status at the specified index.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public Status this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (index < 0 || index > StatusListLength)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var addr = this.GetStatusAddress(index);
|
||||||
|
return this.CreateStatusReference(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the party member at the specified index of the party list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="index">The index of the party member.</param>
|
||||||
|
/// <returns>The memory address of the party member.</returns>
|
||||||
|
public IntPtr GetStatusAddress(int index)
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= StatusListLength)
|
||||||
|
return IntPtr.Zero;
|
||||||
|
|
||||||
|
return (IntPtr)(this.Struct->Status + (index * StatusSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a reference to an FFXIV actor status.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="address">The address of the status effect in memory.</param>
|
||||||
|
/// <returns>The status object containing the requested data.</returns>
|
||||||
|
[CanBeNull]
|
||||||
|
public Status CreateStatusReference(IntPtr address)
|
||||||
|
{
|
||||||
|
if (this.dalamud.ClientState.LocalContentId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (address == IntPtr.Zero)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new Status(address, this.dalamud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This collection represents the status effects an actor is afflicted by.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class StatusList : IReadOnlyCollection<Status>, ICollection
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int IReadOnlyCollection<Status>.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
int ICollection.Count => this.Length;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
bool ICollection.IsSynchronized => false;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IEnumerator<Status> GetEnumerator()
|
||||||
|
{
|
||||||
|
for (var i = 0; i < StatusListLength; i++)
|
||||||
|
{
|
||||||
|
var status = this[i];
|
||||||
|
|
||||||
|
if (status == null || status.StatusID == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory AST job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct ASTGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private CardType card;
|
|
||||||
|
|
||||||
[FieldOffset(5)]
|
|
||||||
private unsafe fixed byte seals[3];
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the currently drawn <see cref="CardType"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Currently drawn <see cref="CardType"/>.</returns>
|
|
||||||
public CardType DrawnCard() => this.card;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if a <see cref="SealType"/> is currently active on the divination gauge.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="seal">The <see cref="SealType"/> to check for.</param>
|
|
||||||
/// <returns>If the given Seal is currently divined.</returns>
|
|
||||||
public unsafe bool ContainsSeal(SealType seal)
|
|
||||||
{
|
|
||||||
if (this.seals[0] == (byte)seal) return true;
|
|
||||||
if (this.seals[1] == (byte)seal) return true;
|
|
||||||
if (this.seals[2] == (byte)seal) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory BLM job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct BLMGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private short timeUntilNextPolyglot; // enochian timer
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private short elementTimeRemaining; // umbral ice and astral fire timer
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte elementStance; // umbral ice or astral fire
|
|
||||||
|
|
||||||
[FieldOffset(5)]
|
|
||||||
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>
|
|
||||||
/// Gets the number of Polyglot stacks remaining.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumPolyglotStacks => this.numPolyglotStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of Umbral Hearts remaining.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumUmbralHearts => this.numUmbralHearts;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player is in Umbral Ice.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool InUmbralIce() => this.elementStance > 4;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player is in Astral fire.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool InAstralFire() => this.elementStance > 0 && this.elementStance < 4;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if Enochian is active.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsEnoActive() => this.enochianState > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory BRD job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct BRDGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private short songTimer;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private byte numSongStacks;
|
|
||||||
|
|
||||||
[FieldOffset(3)]
|
|
||||||
private byte soulVoiceValue;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private CurrentSong activeSong;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current song timer in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short SongTimer => this.songTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of stacks for the current song.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumSongStacks => this.numSongStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Soul Voice accumulated.
|
|
||||||
/// </summary>
|
|
||||||
public byte SoulVoiceValue => this.soulVoiceValue;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the type of song that is active.
|
|
||||||
/// </summary>
|
|
||||||
public CurrentSong ActiveSong => this.activeSong;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory DNC job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public unsafe struct DNCGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte numFeathers;
|
|
||||||
|
|
||||||
[FieldOffset(1)]
|
|
||||||
private byte esprit;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
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>
|
|
||||||
/// Gets the number of steps completed for the current dance.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumCompleteSteps => this.numCompleteSteps;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the next step in the current dance.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The next dance step action ID.</returns>
|
|
||||||
public ulong NextStep() => (ulong)(15999 + this.stepOrder[this.NumCompleteSteps] - 1);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player is dancing or not.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsDancing() => this.stepOrder[0] != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory DRG job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct DRGGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private short botdTimer;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private BOTDState botdState;
|
|
||||||
|
|
||||||
[FieldOffset(3)]
|
|
||||||
private byte eyeCount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time remaining for Blood of the Dragon in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short BOTDTimer => this.botdTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current state of Blood of the Dragon.
|
|
||||||
/// </summary>
|
|
||||||
public BOTDState BOTDState => this.botdState;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the count of eyes opened during Blood of the Dragon.
|
|
||||||
/// </summary>
|
|
||||||
public byte EyeCount => this.eyeCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory DRK job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct DRKGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte blood;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private ushort darksideTimeRemaining;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
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>
|
|
||||||
/// Gets the Shadow time remaining in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public ushort ShadowTimeRemaining => this.shadowTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player has Dark Arts or not.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool HasDarkArts() => this.darkArtsState > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory GNB job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct GNBGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte numAmmo;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private short maxTimerDuration;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte ammoComboStepNumber;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of ammo available.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumAmmo => this.numAmmo;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the max combo time of the Gnashing Fang combo.
|
|
||||||
/// </summary>
|
|
||||||
public short MaxTimerDuration => this.maxTimerDuration;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current step of the Gnashing Fang combo.
|
|
||||||
/// </summary>
|
|
||||||
public byte AmmoComboStepNumber => this.ammoComboStepNumber;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,276 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
#pragma warning disable SA1402 // File may only contain a single type
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
#region AST
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// AST Divination seal types.
|
|
||||||
/// </summary>
|
|
||||||
public enum SealType : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No seal.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sun seal.
|
|
||||||
/// </summary>
|
|
||||||
SUN = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Moon seal.
|
|
||||||
/// </summary>
|
|
||||||
MOON = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Celestial seal.
|
|
||||||
/// </summary>
|
|
||||||
CELESTIAL = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// AST Arcanum (card) types.
|
|
||||||
/// </summary>
|
|
||||||
public enum CardType : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No card.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Balance card.
|
|
||||||
/// </summary>
|
|
||||||
BALANCE = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Bole card.
|
|
||||||
/// </summary>
|
|
||||||
BOLE = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Arrow card.
|
|
||||||
/// </summary>
|
|
||||||
ARROW = 3,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Spear card.
|
|
||||||
/// </summary>
|
|
||||||
SPEAR = 4,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Ewer card.
|
|
||||||
/// </summary>
|
|
||||||
EWER = 5,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Spire card.
|
|
||||||
/// </summary>
|
|
||||||
SPIRE = 6,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Lord of Crowns card.
|
|
||||||
/// </summary>
|
|
||||||
LORD = 0x70,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Lady of Crowns card.
|
|
||||||
/// </summary>
|
|
||||||
LADY = 0x80,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region BRD
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// BRD Current Song types.
|
|
||||||
/// </summary>
|
|
||||||
public enum CurrentSong : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No song is active type.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Mage's Ballad type.
|
|
||||||
/// </summary>
|
|
||||||
MAGE = 5,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Army's Paeon type.
|
|
||||||
/// </summary>
|
|
||||||
ARMY = 0xA,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Wanderer's Minuet type.
|
|
||||||
/// </summary>
|
|
||||||
WANDERER = 0xF,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region DRG
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// DRG Blood of the Dragon state types.
|
|
||||||
/// </summary>
|
|
||||||
public enum BOTDState : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Inactive type.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Blood of the Dragon is active.
|
|
||||||
/// </summary>
|
|
||||||
BOTD = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Life of the Dragon is active.
|
|
||||||
/// </summary>
|
|
||||||
LOTD = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region NIN
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// NIN Mudra types.
|
|
||||||
/// </summary>
|
|
||||||
public enum Mudras : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Ten mudra.
|
|
||||||
/// </summary>
|
|
||||||
TEN = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Chi mudra.
|
|
||||||
/// </summary>
|
|
||||||
CHI = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Jin mudra.
|
|
||||||
/// </summary>
|
|
||||||
JIN = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region SAM
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Samurai Sen types.
|
|
||||||
/// </summary>
|
|
||||||
[Flags]
|
|
||||||
public enum Sen : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No Sen.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Setsu Sen type.
|
|
||||||
/// </summary>
|
|
||||||
SETSU = 1 << 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Getsu Sen type.
|
|
||||||
/// </summary>
|
|
||||||
GETSU = 1 << 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ka Sen type.
|
|
||||||
/// </summary>
|
|
||||||
KA = 1 << 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region SCH
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SCH Dismissed fairy types.
|
|
||||||
/// </summary>
|
|
||||||
public enum DismissedFairy : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Dismissed fairy is Eos.
|
|
||||||
/// </summary>
|
|
||||||
EOS = 6,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Dismissed fairy is Selene.
|
|
||||||
/// </summary>
|
|
||||||
SELENE = 7,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region SMN
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SMN summoned pet types.
|
|
||||||
/// </summary>
|
|
||||||
public enum SummonPet : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No pet.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The summoned pet Ifrit.
|
|
||||||
/// </summary>
|
|
||||||
IFRIT = 3,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The summoned pet Titan.
|
|
||||||
/// </summary>
|
|
||||||
TITAN = 4,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The summoned pet Garuda.
|
|
||||||
/// </summary>
|
|
||||||
GARUDA = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// SMN summoned pet glam types.
|
|
||||||
/// </summary>
|
|
||||||
public enum PetGlam : byte
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// No pet glam.
|
|
||||||
/// </summary>
|
|
||||||
NONE = 0,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Emerald carbuncle pet glam.
|
|
||||||
/// </summary>
|
|
||||||
EMERALD = 1,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Topaz carbuncle pet glam.
|
|
||||||
/// </summary>
|
|
||||||
TOPAZ = 2,
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ruby carbuncle pet glam.
|
|
||||||
/// </summary>
|
|
||||||
RUBY = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning restore SA1402 // File may only contain a single type
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory MCH job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
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>
|
|
||||||
/// Gets the time time remaining for Overheat in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short OverheatTimeRemaining => this.overheatTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time remaining for the Rook or Queen in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short RobotTimeRemaining => this.robotTimeRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current Heat level.
|
|
||||||
/// </summary>
|
|
||||||
public byte Heat => this.heat;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current Battery level.
|
|
||||||
/// </summary>
|
|
||||||
public byte Battery => this.battery;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the battery level of the last Robot.
|
|
||||||
/// </summary>
|
|
||||||
public byte LastRobotBatteryPower => this.lastRobotBatteryPower;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player is currently Overheated.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsOverheated() => (this.timerActive & 1) != 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the player has an active Robot.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsRobotActive() => (this.timerActive & 2) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory MNK job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct MNKGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte numChakra;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of Chakra available.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumChakra => this.numChakra;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory NIN job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct NINGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private int hutonTimeLeft;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte ninki;
|
|
||||||
|
|
||||||
[FieldOffset(5)]
|
|
||||||
private byte numHutonManualCasts;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time left on Huton in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public int HutonTimeLeft => this.hutonTimeLeft;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Ninki available.
|
|
||||||
/// </summary>
|
|
||||||
public byte Ninki => this.ninki;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of times Huton has been cast manually.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumHutonManualCasts => this.numHutonManualCasts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory PLD job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct PLDGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte gaugeAmount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current level of the Oath gauge.
|
|
||||||
/// </summary>
|
|
||||||
public byte GaugeAmount => this.gaugeAmount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory RDM job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct RDMGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte whiteGauge;
|
|
||||||
|
|
||||||
[FieldOffset(1)]
|
|
||||||
private byte blackGauge;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the level of the White gauge.
|
|
||||||
/// </summary>
|
|
||||||
public byte WhiteGauge => this.whiteGauge;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the level of the Black gauge.
|
|
||||||
/// </summary>
|
|
||||||
public byte BlackGauge => this.blackGauge;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory SAM job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct SAMGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(3)]
|
|
||||||
private byte kenki;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte meditationStacks;
|
|
||||||
|
|
||||||
[FieldOffset(5)]
|
|
||||||
private Sen sen;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current amount of Kenki available.
|
|
||||||
/// </summary>
|
|
||||||
public byte Kenki => this.kenki;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Meditation stacks.
|
|
||||||
/// </summary>
|
|
||||||
public byte MeditationStacks => this.meditationStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the active Sen.
|
|
||||||
/// </summary>
|
|
||||||
public Sen Sen => this.sen;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the Setsu Sen is active.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool HasSetsu() => (this.Sen & Sen.SETSU) != 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the Getsu Sen is active.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool HasGetsu() => (this.Sen & Sen.GETSU) != 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if the Ka Sen is active.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool HasKa() => (this.Sen & Sen.KA) != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory SCH job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct SCHGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private byte numAetherflowStacks;
|
|
||||||
|
|
||||||
[FieldOffset(3)]
|
|
||||||
private byte fairyGaugeAmount;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private short seraphTimer;
|
|
||||||
|
|
||||||
[FieldOffset(6)]
|
|
||||||
private DismissedFairy dismissedFairy;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of Aetherflow stacks available.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumAetherflowStacks => this.numAetherflowStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current level of the Fairy Gauge.
|
|
||||||
/// </summary>
|
|
||||||
public byte FairyGaugeAmount => this.fairyGaugeAmount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the Seraph time remaining in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short SeraphTimer => this.seraphTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the last dismissed fairy.
|
|
||||||
/// </summary>
|
|
||||||
public DismissedFairy DismissedFairy => this.dismissedFairy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory SMN job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct SMNGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private short timerRemaining;
|
|
||||||
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private SummonPet returnSummon;
|
|
||||||
|
|
||||||
[FieldOffset(3)]
|
|
||||||
private PetGlam returnSummonGlam;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte numStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time remaining for the current summon.
|
|
||||||
/// </summary>
|
|
||||||
public short TimerRemaining => this.timerRemaining;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the summon that will return after the current summon expires.
|
|
||||||
/// </summary>
|
|
||||||
public SummonPet ReturnSummon => this.returnSummon;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the summon glam for the <see cref="ReturnSummon"/>.
|
|
||||||
/// </summary>
|
|
||||||
public PetGlam ReturnSummonGlam => this.returnSummonGlam;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current stacks.
|
|
||||||
/// Use the summon accessors instead.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumStacks => this.numStacks;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if Phoenix is ready to be summoned.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsPhoenixReady() => (this.NumStacks & 0x10) > 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if Bahamut is ready to be summoned.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool IsBahamutReady() => (this.NumStacks & 8) > 0;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets if there are any Aetherflow stacks available.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns><c>true</c> or <c>false</c>.</returns>
|
|
||||||
public bool HasAetherflowStacks() => (this.NumStacks & 3) > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory WAR job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct WARGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(0)]
|
|
||||||
private byte beastGaugeAmount;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the amount of wrath in the Beast gauge.
|
|
||||||
/// </summary>
|
|
||||||
public byte BeastGaugeAmount => this.beastGaugeAmount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs.JobGauge
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// In-memory WHM job gauge.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct WHMGauge
|
|
||||||
{
|
|
||||||
[FieldOffset(2)]
|
|
||||||
private short lilyTimer;
|
|
||||||
|
|
||||||
[FieldOffset(4)]
|
|
||||||
private byte numLilies;
|
|
||||||
|
|
||||||
[FieldOffset(5)]
|
|
||||||
private byte numBloodLily;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the time to next lily in milliseconds.
|
|
||||||
/// </summary>
|
|
||||||
public short LilyTimer => this.lilyTimer;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of Lilies.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumLilies => this.numLilies;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the number of times the blood lily has been nourished.
|
|
||||||
/// </summary>
|
|
||||||
public byte NumBloodLily => this.numBloodLily;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
|
||||||
|
|
||||||
namespace Dalamud.Game.ClientState.Structs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// This represents a native PartyMember class in memory.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct PartyMember
|
|
||||||
{
|
|
||||||
[FieldOffset(0x0)]
|
|
||||||
public IntPtr namePtr;
|
|
||||||
|
|
||||||
[FieldOffset(0x8)]
|
|
||||||
public long unknown;
|
|
||||||
|
|
||||||
[FieldOffset(0x10)]
|
|
||||||
public int actorId;
|
|
||||||
|
|
||||||
[FieldOffset(0x14)]
|
|
||||||
public ObjectKind objectKind;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -47,7 +47,7 @@ namespace Dalamud.Game.Command
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dalamud.Framework.Gui.Chat.OnCheckMessageHandled += this.OnCheckMessageHandled;
|
dalamud.Framework.Gui.Chat.CheckMessageHandled += this.OnCheckMessageHandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Dalamud.Game.Gui
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate type used with the <see cref="OnChatMessage"/> event.
|
/// A delegate type used with the <see cref="ChatGui.ChatMessage"/> event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of chat.</param>
|
/// <param name="type">The type of chat.</param>
|
||||||
/// <param name="senderId">The sender ID.</param>
|
/// <param name="senderId">The sender ID.</param>
|
||||||
|
|
@ -60,7 +60,7 @@ namespace Dalamud.Game.Gui
|
||||||
public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled);
|
public delegate void OnMessageDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate type used with the <see cref="OnCheckMessageHandled"/> event.
|
/// A delegate type used with the <see cref="ChatGui.CheckMessageHandled"/> event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of chat.</param>
|
/// <param name="type">The type of chat.</param>
|
||||||
/// <param name="senderId">The sender ID.</param>
|
/// <param name="senderId">The sender ID.</param>
|
||||||
|
|
@ -70,7 +70,7 @@ namespace Dalamud.Game.Gui
|
||||||
public delegate void OnCheckMessageHandledDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled);
|
public delegate void OnCheckMessageHandledDelegate(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate type used with the <see cref="OnChatMessageHandled"/> event.
|
/// A delegate type used with the <see cref="ChatGui.ChatMessageHandled"/> event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of chat.</param>
|
/// <param name="type">The type of chat.</param>
|
||||||
/// <param name="senderId">The sender ID.</param>
|
/// <param name="senderId">The sender ID.</param>
|
||||||
|
|
@ -79,7 +79,7 @@ namespace Dalamud.Game.Gui
|
||||||
public delegate void OnMessageHandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message);
|
public delegate void OnMessageHandledDelegate(XivChatType type, uint senderId, SeString sender, SeString message);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A delegate type used with the <see cref="OnChatMessageUnhandled"/> event.
|
/// A delegate type used with the <see cref="ChatGui.ChatMessageUnhandled"/> event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="type">The type of chat.</param>
|
/// <param name="type">The type of chat.</param>
|
||||||
/// <param name="senderId">The sender ID.</param>
|
/// <param name="senderId">The sender ID.</param>
|
||||||
|
|
@ -99,22 +99,22 @@ namespace Dalamud.Game.Gui
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when a chat message is sent to chat by the game.
|
/// Event that will be fired when a chat message is sent to chat by the game.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnMessageDelegate OnChatMessage;
|
public event OnMessageDelegate ChatMessage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that allows you to stop messages from appearing in chat by setting the isHandled parameter to true.
|
/// Event that allows you to stop messages from appearing in chat by setting the isHandled parameter to true.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnCheckMessageHandledDelegate OnCheckMessageHandled;
|
public event OnCheckMessageHandledDelegate CheckMessageHandled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when a chat message is handled by Dalamud or a Plugin.
|
/// Event that will be fired when a chat message is handled by Dalamud or a Plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnMessageHandledDelegate OnChatMessageHandled;
|
public event OnMessageHandledDelegate ChatMessageHandled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when a chat message is not handled by Dalamud or a Plugin.
|
/// Event that will be fired when a chat message is not handled by Dalamud or a Plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnMessageUnhandledDelegate OnChatMessageUnhandled;
|
public event OnMessageUnhandledDelegate ChatMessageUnhandled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID of the last linked item.
|
/// Gets the ID of the last linked item.
|
||||||
|
|
@ -365,11 +365,11 @@ namespace Dalamud.Game.Gui
|
||||||
|
|
||||||
// Call events
|
// Call events
|
||||||
var isHandled = false;
|
var isHandled = false;
|
||||||
this.OnCheckMessageHandled?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
|
this.CheckMessageHandled?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
|
||||||
|
|
||||||
if (!isHandled)
|
if (!isHandled)
|
||||||
{
|
{
|
||||||
this.OnChatMessage?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
|
this.ChatMessage?.Invoke(chattype, senderid, ref parsedSender, ref parsedMessage, ref isHandled);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newEdited = parsedMessage.Encode();
|
var newEdited = parsedMessage.Encode();
|
||||||
|
|
@ -395,12 +395,12 @@ namespace Dalamud.Game.Gui
|
||||||
// Print the original chat if it's handled.
|
// Print the original chat if it's handled.
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
{
|
{
|
||||||
this.OnChatMessageHandled?.Invoke(chattype, senderid, parsedSender, parsedMessage);
|
this.ChatMessageHandled?.Invoke(chattype, senderid, parsedSender, parsedMessage);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter);
|
retVal = this.printMessageHook.Original(manager, chattype, pSenderName, messagePtr, senderid, parameter);
|
||||||
this.OnChatMessageUnhandled?.Invoke(chattype, senderid, parsedSender, parsedMessage);
|
this.ChatMessageUnhandled?.Invoke(chattype, senderid, parsedSender, parsedMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.baseAddress == IntPtr.Zero)
|
if (this.baseAddress == IntPtr.Zero)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
|
using ImGuiNET;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Dalamud.Game.Gui
|
namespace Dalamud.Game.Gui
|
||||||
|
|
@ -32,6 +33,7 @@ namespace Dalamud.Game.Gui
|
||||||
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
|
private readonly Hook<HandleItemOutDelegate> handleItemOutHook;
|
||||||
private readonly Hook<HandleActionHoverDelegate> handleActionHoverHook;
|
private readonly Hook<HandleActionHoverDelegate> handleActionHoverHook;
|
||||||
private readonly Hook<HandleActionOutDelegate> handleActionOutHook;
|
private readonly Hook<HandleActionOutDelegate> handleActionOutHook;
|
||||||
|
private readonly Hook<HandleImmDelegate> handleImmHook;
|
||||||
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
|
private readonly Hook<ToggleUiHideDelegate> toggleUiHideHook;
|
||||||
|
|
||||||
private GetUIMapObjectDelegate getUIMapObject;
|
private GetUIMapObjectDelegate getUIMapObject;
|
||||||
|
|
@ -57,6 +59,7 @@ namespace Dalamud.Game.Gui
|
||||||
Log.Verbose($"SetGlobalBgm address 0x{this.address.SetGlobalBgm.ToInt64():X}");
|
Log.Verbose($"SetGlobalBgm address 0x{this.address.SetGlobalBgm.ToInt64():X}");
|
||||||
Log.Verbose($"HandleItemHover address 0x{this.address.HandleItemHover.ToInt64():X}");
|
Log.Verbose($"HandleItemHover address 0x{this.address.HandleItemHover.ToInt64():X}");
|
||||||
Log.Verbose($"HandleItemOut address 0x{this.address.HandleItemOut.ToInt64():X}");
|
Log.Verbose($"HandleItemOut address 0x{this.address.HandleItemOut.ToInt64():X}");
|
||||||
|
Log.Verbose($"HandleImm address 0x{this.address.HandleImm.ToInt64():X}");
|
||||||
Log.Verbose($"GetUIObject address 0x{this.address.GetUIObject.ToInt64():X}");
|
Log.Verbose($"GetUIObject address 0x{this.address.GetUIObject.ToInt64():X}");
|
||||||
Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}");
|
Log.Verbose($"GetAgentModule address 0x{this.address.GetAgentModule.ToInt64():X}");
|
||||||
|
|
||||||
|
|
@ -66,13 +69,15 @@ namespace Dalamud.Game.Gui
|
||||||
this.FlyText = new FlyTextGui(scanner, dalamud);
|
this.FlyText = new FlyTextGui(scanner, dalamud);
|
||||||
|
|
||||||
this.setGlobalBgmHook = new Hook<SetGlobalBgmDelegate>(this.address.SetGlobalBgm, this.HandleSetGlobalBgmDetour);
|
this.setGlobalBgmHook = new Hook<SetGlobalBgmDelegate>(this.address.SetGlobalBgm, this.HandleSetGlobalBgmDetour);
|
||||||
this.handleItemHoverHook = new Hook<HandleItemHoverDelegate>(this.address.HandleItemHover, this.HandleItemHoverDetour);
|
|
||||||
|
|
||||||
|
this.handleItemHoverHook = new Hook<HandleItemHoverDelegate>(this.address.HandleItemHover, this.HandleItemHoverDetour);
|
||||||
this.handleItemOutHook = new Hook<HandleItemOutDelegate>(this.address.HandleItemOut, this.HandleItemOutDetour);
|
this.handleItemOutHook = new Hook<HandleItemOutDelegate>(this.address.HandleItemOut, this.HandleItemOutDetour);
|
||||||
|
|
||||||
this.handleActionHoverHook = new Hook<HandleActionHoverDelegate>(this.address.HandleActionHover, this.HandleActionHoverDetour);
|
this.handleActionHoverHook = new Hook<HandleActionHoverDelegate>(this.address.HandleActionHover, this.HandleActionHoverDetour);
|
||||||
this.handleActionOutHook = new Hook<HandleActionOutDelegate>(this.address.HandleActionOut, this.HandleActionOutDetour);
|
this.handleActionOutHook = new Hook<HandleActionOutDelegate>(this.address.HandleActionOut, this.HandleActionOutDetour);
|
||||||
|
|
||||||
|
this.handleImmHook = new Hook<HandleImmDelegate>(this.address.HandleImm, this.HandleImmDetour);
|
||||||
|
|
||||||
this.getUIObject = Marshal.GetDelegateForFunctionPointer<GetUIObjectDelegate>(this.address.GetUIObject);
|
this.getUIObject = Marshal.GetDelegateForFunctionPointer<GetUIObjectDelegate>(this.address.GetUIObject);
|
||||||
|
|
||||||
this.getMatrixSingleton = Marshal.GetDelegateForFunctionPointer<GetMatrixSingletonDelegate>(this.address.GetMatrixSingleton);
|
this.getMatrixSingleton = Marshal.GetDelegateForFunctionPointer<GetMatrixSingletonDelegate>(this.address.GetMatrixSingleton);
|
||||||
|
|
@ -136,6 +141,9 @@ namespace Dalamud.Game.Gui
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
private delegate IntPtr HandleActionOutDelegate(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4);
|
private delegate IntPtr HandleActionOutDelegate(IntPtr agentActionDetail, IntPtr a2, IntPtr a3, int a4);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
|
private delegate char HandleImmDelegate(IntPtr framework, char a2, byte a3);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
|
||||||
private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte);
|
private delegate IntPtr ToggleUiHideDelegate(IntPtr thisPtr, byte unknownByte);
|
||||||
|
|
||||||
|
|
@ -285,23 +293,6 @@ namespace Dalamud.Game.Gui
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Converts in-world coordinates to screen coordinates (upper left corner origin).
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="worldPos">Coordinates in the world.</param>
|
|
||||||
/// <param name="screenPos">Converted coordinates.</param>
|
|
||||||
/// <returns>True if worldPos corresponds to a position in front of the camera.</returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// This overload requires a conversion to SharpDX vectors, however the penalty should be negligible.
|
|
||||||
/// </remarks>
|
|
||||||
public bool WorldToScreen(Position3 worldPos, out Vector2 screenPos)
|
|
||||||
{
|
|
||||||
// This overload is necessary due to Positon3 implicit operators.
|
|
||||||
var result = this.WorldToScreen((SharpDX.Vector3)worldPos, out var sharpScreenPos);
|
|
||||||
screenPos = sharpScreenPos.ToSystem();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts screen coordinates to in-world coordinates via raycasting.
|
/// Converts screen coordinates to in-world coordinates via raycasting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -518,6 +509,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.setGlobalBgmHook.Enable();
|
this.setGlobalBgmHook.Enable();
|
||||||
this.handleItemHoverHook.Enable();
|
this.handleItemHoverHook.Enable();
|
||||||
this.handleItemOutHook.Enable();
|
this.handleItemOutHook.Enable();
|
||||||
|
this.handleImmHook.Enable();
|
||||||
this.toggleUiHideHook.Enable();
|
this.toggleUiHideHook.Enable();
|
||||||
this.handleActionHoverHook.Enable();
|
this.handleActionHoverHook.Enable();
|
||||||
this.handleActionOutHook.Enable();
|
this.handleActionOutHook.Enable();
|
||||||
|
|
@ -535,6 +527,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.setGlobalBgmHook.Dispose();
|
this.setGlobalBgmHook.Dispose();
|
||||||
this.handleItemHoverHook.Dispose();
|
this.handleItemHoverHook.Dispose();
|
||||||
this.handleItemOutHook.Dispose();
|
this.handleItemOutHook.Dispose();
|
||||||
|
this.handleImmHook.Dispose();
|
||||||
this.toggleUiHideHook.Dispose();
|
this.toggleUiHideHook.Dispose();
|
||||||
this.handleActionHoverHook.Dispose();
|
this.handleActionHoverHook.Dispose();
|
||||||
this.handleActionOutHook.Dispose();
|
this.handleActionOutHook.Dispose();
|
||||||
|
|
@ -666,5 +659,13 @@ namespace Dalamud.Game.Gui
|
||||||
|
|
||||||
return this.toggleUiHideHook.Original(thisPtr, unknownByte);
|
return this.toggleUiHideHook.Original(thisPtr, unknownByte);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private char HandleImmDetour(IntPtr framework, char a2, byte a3)
|
||||||
|
{
|
||||||
|
var result = this.handleImmHook.Original(framework, a2, a3);
|
||||||
|
return ImGui.GetIO().WantTextInput
|
||||||
|
? (char)0
|
||||||
|
: result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,11 @@ namespace Dalamud.Game.Gui
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IntPtr HandleActionOut { get; private set; }
|
public IntPtr HandleActionOut { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the address of the native HandleImm method.
|
||||||
|
/// </summary>
|
||||||
|
public IntPtr HandleImm { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the address of the native GetUIObject method.
|
/// Gets the address of the native GetUIObject method.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -100,6 +105,7 @@ namespace Dalamud.Game.Gui
|
||||||
this.HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
|
this.HandleItemOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 4D");
|
||||||
this.HandleActionHover = sig.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 83 F8 0F");
|
this.HandleActionHover = sig.ScanText("E8 ?? ?? ?? ?? E9 ?? ?? ?? ?? 83 F8 0F");
|
||||||
this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
|
this.HandleActionOut = sig.ScanText("48 89 5C 24 ?? 57 48 83 EC 20 48 8B DA 48 8B F9 4D 85 C0 74 1F");
|
||||||
|
this.HandleImm = sig.ScanText("E8 ?? ?? ?? ?? 84 C0 75 10 48 83 FF 09");
|
||||||
this.GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
|
this.GetUIObject = sig.ScanText("E8 ?? ?? ?? ?? 48 8B C8 48 8B 10 FF 52 40 80 88 ?? ?? ?? ?? 01 E9");
|
||||||
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
this.GetMatrixSingleton = sig.ScanText("E8 ?? ?? ?? ?? 48 8D 4C 24 ?? 48 89 4c 24 ?? 4C 8D 4D ?? 4C 8D 44 24 ??");
|
||||||
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
|
this.ScreenToWorld = sig.ScanText("48 83 EC 48 48 8B 05 ?? ?? ?? ?? 4D 8B D1");
|
||||||
|
|
|
||||||
234
Dalamud/Game/Gui/Internal/DalamudIME.cs
Normal file
234
Dalamud/Game/Gui/Internal/DalamudIME.cs
Normal file
|
|
@ -0,0 +1,234 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Dalamud.Logging.Internal;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
using static Dalamud.NativeFunctions;
|
||||||
|
|
||||||
|
namespace Dalamud.Game.Gui.Internal
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class handles IME for non-English users.
|
||||||
|
/// </summary>
|
||||||
|
internal class DalamudIME : IDisposable
|
||||||
|
{
|
||||||
|
private static readonly ModuleLog Log = new("IME");
|
||||||
|
|
||||||
|
private readonly Dalamud dalamud;
|
||||||
|
|
||||||
|
private IntPtr interfaceHandle;
|
||||||
|
private IntPtr wndProcPtr;
|
||||||
|
private IntPtr oldWndProcPtr;
|
||||||
|
private WndProcDelegate wndProcDelegate;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="DalamudIME"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dalamud">The Dalamud instance.</param>
|
||||||
|
internal DalamudIME(Dalamud dalamud)
|
||||||
|
{
|
||||||
|
this.dalamud = dalamud;
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate long WndProcDelegate(IntPtr hWnd, uint msg, ulong wParam, long lParam);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the module is enabled.
|
||||||
|
/// </summary>
|
||||||
|
internal bool IsEnabled { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the imm candidates.
|
||||||
|
/// </summary>
|
||||||
|
internal List<string> ImmCand { get; private set; } = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the imm component.
|
||||||
|
/// </summary>
|
||||||
|
internal string ImmComp { get; private set; } = string.Empty;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (this.oldWndProcPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
SetWindowLongPtrW(this.interfaceHandle, WindowLongType.WndProc, this.oldWndProcPtr);
|
||||||
|
this.oldWndProcPtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the IME module.
|
||||||
|
/// </summary>
|
||||||
|
internal void Enable()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.wndProcDelegate = this.WndProcDetour;
|
||||||
|
this.interfaceHandle = this.dalamud.InterfaceManager.WindowHandlePtr;
|
||||||
|
this.wndProcPtr = Marshal.GetFunctionPointerForDelegate(this.wndProcDelegate);
|
||||||
|
this.oldWndProcPtr = SetWindowLongPtrW(this.interfaceHandle, WindowLongType.WndProc, this.wndProcPtr);
|
||||||
|
this.IsEnabled = true;
|
||||||
|
Log.Information("Enabled!");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Information(ex, "Enable failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleWindow(bool visible)
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
this.dalamud.DalamudUi.OpenIMEWindow();
|
||||||
|
else
|
||||||
|
this.dalamud.DalamudUi.CloseIMEWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long WndProcDetour(IntPtr hWnd, uint msg, ulong wParam, long lParam)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (hWnd == this.interfaceHandle && ImGui.GetCurrentContext() != IntPtr.Zero && ImGui.GetIO().WantTextInput)
|
||||||
|
{
|
||||||
|
var io = ImGui.GetIO();
|
||||||
|
var wmsg = (WindowsMessage)msg;
|
||||||
|
|
||||||
|
switch (wmsg)
|
||||||
|
{
|
||||||
|
case WindowsMessage.WM_IME_NOTIFY:
|
||||||
|
switch ((IMECommand)wParam)
|
||||||
|
{
|
||||||
|
case IMECommand.ChangeCandidate:
|
||||||
|
this.ToggleWindow(true);
|
||||||
|
|
||||||
|
if (hWnd == IntPtr.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var hIMC = ImmGetContext(hWnd);
|
||||||
|
if (hIMC == IntPtr.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var size = ImmGetCandidateListW(hIMC, 0, IntPtr.Zero, 0);
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
var candlistPtr = Marshal.AllocHGlobal((int)size);
|
||||||
|
size = ImmGetCandidateListW(hIMC, 0, candlistPtr, (uint)size);
|
||||||
|
|
||||||
|
var candlist = Marshal.PtrToStructure<CandidateList>(candlistPtr);
|
||||||
|
var pageSize = candlist.PageSize;
|
||||||
|
var candCount = candlist.Count;
|
||||||
|
if (pageSize > 0 && candCount > 1)
|
||||||
|
{
|
||||||
|
var dwOffsets = new int[candCount];
|
||||||
|
for (var i = 0; i < candCount; i++)
|
||||||
|
dwOffsets[i] = Marshal.ReadInt32(candlistPtr + ((i + 6) * sizeof(int)));
|
||||||
|
|
||||||
|
var pageStart = candlist.PageStart;
|
||||||
|
// var pageEnd = pageStart + pageSize;
|
||||||
|
|
||||||
|
var cand = new string[pageSize];
|
||||||
|
this.ImmCand.Clear();
|
||||||
|
|
||||||
|
for (var i = 0; i < pageSize; i++)
|
||||||
|
{
|
||||||
|
var offStart = dwOffsets[i + pageStart];
|
||||||
|
var offEnd = i + pageStart + 1 < candCount ? dwOffsets[i + pageStart + 1] : size;
|
||||||
|
|
||||||
|
var pStrStart = candlistPtr + (int)offStart;
|
||||||
|
var pStrEnd = candlistPtr + (int)offEnd;
|
||||||
|
|
||||||
|
var len = (int)(pStrEnd.ToInt64() - pStrStart.ToInt64());
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
var candBytes = new byte[len];
|
||||||
|
Marshal.Copy(pStrStart, candBytes, 0, len);
|
||||||
|
|
||||||
|
var candStr = Encoding.Unicode.GetString(candBytes);
|
||||||
|
cand[i] = candStr;
|
||||||
|
|
||||||
|
this.ImmCand.Add(candStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal(candlistPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case IMECommand.OpenCandidate:
|
||||||
|
this.ToggleWindow(true);
|
||||||
|
this.ImmCand.Clear();
|
||||||
|
break;
|
||||||
|
case IMECommand.CloseCandidate:
|
||||||
|
this.ToggleWindow(false);
|
||||||
|
this.ImmCand.Clear();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case WindowsMessage.WM_IME_COMPOSITION:
|
||||||
|
if ((lParam & (long)IMEComposition.ResultStr) > 0)
|
||||||
|
{
|
||||||
|
var hIMC = ImmGetContext(hWnd);
|
||||||
|
if (hIMC == IntPtr.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var dwSize = ImmGetCompositionStringW(hIMC, IMEComposition.ResultStr, IntPtr.Zero, 0);
|
||||||
|
var unmanagedPointer = Marshal.AllocHGlobal((int)dwSize);
|
||||||
|
ImmGetCompositionStringW(hIMC, IMEComposition.ResultStr, unmanagedPointer, (uint)dwSize);
|
||||||
|
|
||||||
|
var bytes = new byte[dwSize];
|
||||||
|
Marshal.Copy(unmanagedPointer, bytes, 0, (int)dwSize);
|
||||||
|
Marshal.FreeHGlobal(unmanagedPointer);
|
||||||
|
|
||||||
|
var lpstr = Encoding.Unicode.GetString(bytes);
|
||||||
|
io.AddInputCharactersUTF8(lpstr);
|
||||||
|
|
||||||
|
this.ImmComp = string.Empty;
|
||||||
|
this.ImmCand.Clear();
|
||||||
|
this.ToggleWindow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((long)(IMEComposition.CompStr | IMEComposition.CompAttr | IMEComposition.CompClause |
|
||||||
|
IMEComposition.CompReadAttr | IMEComposition.CompReadClause | IMEComposition.CompReadStr) & lParam) > 0)
|
||||||
|
{
|
||||||
|
var hIMC = ImmGetContext(hWnd);
|
||||||
|
if (hIMC == IntPtr.Zero)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var dwSize = ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, IntPtr.Zero, 0);
|
||||||
|
var unmanagedPointer = Marshal.AllocHGlobal((int)dwSize);
|
||||||
|
ImmGetCompositionStringW(hIMC, IMEComposition.CompStr, unmanagedPointer, (uint)dwSize);
|
||||||
|
|
||||||
|
var bytes = new byte[dwSize];
|
||||||
|
Marshal.Copy(unmanagedPointer, bytes, 0, (int)dwSize);
|
||||||
|
Marshal.FreeHGlobal(unmanagedPointer);
|
||||||
|
|
||||||
|
var lpstr = Encoding.Unicode.GetString(bytes);
|
||||||
|
this.ImmComp = lpstr;
|
||||||
|
if (lpstr == string.Empty)
|
||||||
|
this.ToggleWindow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Error(ex, "Prevented a crash in an IME hook");
|
||||||
|
}
|
||||||
|
|
||||||
|
return CallWindowProcW(this.oldWndProcPtr, hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -85,17 +85,17 @@ namespace Dalamud.Game.Gui
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when a toast is sent by the game or a plugin.
|
/// Event that will be fired when a toast is sent by the game or a plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnNormalToastDelegate OnToast;
|
public event OnNormalToastDelegate Toast;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when a quest toast is sent by the game or a plugin.
|
/// Event that will be fired when a quest toast is sent by the game or a plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnQuestToastDelegate OnQuestToast;
|
public event OnQuestToastDelegate QuestToast;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Event that will be fired when an error toast is sent by the game or a plugin.
|
/// Event that will be fired when an error toast is sent by the game or a plugin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event OnErrorToastDelegate OnErrorToast;
|
public event OnErrorToastDelegate ErrorToast;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
@ -231,7 +231,7 @@ namespace Dalamud.Game.Gui
|
||||||
Speed = (ToastSpeed)isFast,
|
Speed = (ToastSpeed)isFast,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.OnToast?.Invoke(ref str, ref options, ref isHandled);
|
this.Toast?.Invoke(ref str, ref options, ref isHandled);
|
||||||
|
|
||||||
// do nothing if handled
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
@ -323,7 +323,7 @@ namespace Dalamud.Game.Gui
|
||||||
PlaySound = playSound == 1,
|
PlaySound = playSound == 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.OnQuestToast?.Invoke(ref str, ref options, ref isHandled);
|
this.QuestToast?.Invoke(ref str, ref options, ref isHandled);
|
||||||
|
|
||||||
// do nothing if handled
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
@ -409,7 +409,7 @@ namespace Dalamud.Game.Gui
|
||||||
var isHandled = false;
|
var isHandled = false;
|
||||||
var str = this.ParseString(text);
|
var str = this.ParseString(text);
|
||||||
|
|
||||||
this.OnErrorToast?.Invoke(ref str, ref isHandled);
|
this.ErrorToast?.Invoke(ref str, ref isHandled);
|
||||||
|
|
||||||
// do nothing if handled
|
// do nothing if handled
|
||||||
if (isHandled)
|
if (isHandled)
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Dalamud.Game
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// A game native equivalent of a Vector3.
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
|
||||||
public struct Position3
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The X of (X,Z,Y).
|
|
||||||
/// </summary>
|
|
||||||
public float X;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Z of (X,Z,Y).
|
|
||||||
/// </summary>
|
|
||||||
public float Z;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Y of (X,Z,Y).
|
|
||||||
/// </summary>
|
|
||||||
public float Y;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of the <see cref="Position3"/> struct.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="x">The X position.</param>
|
|
||||||
/// <param name="z">The Z position.</param>
|
|
||||||
/// <param name="y">The Y position.</param>
|
|
||||||
public Position3(float x, float z, float y)
|
|
||||||
{
|
|
||||||
this.X = x;
|
|
||||||
this.Z = z;
|
|
||||||
this.Y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert this Position3 to a System.Numerics.Vector3.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pos">Position to convert.</param>
|
|
||||||
public static implicit operator System.Numerics.Vector3(Position3 pos) => new(pos.X, pos.Y, pos.Z);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert this Position3 to a SharpDX.Vector3.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pos">Position to convert.</param>
|
|
||||||
public static implicit operator SharpDX.Vector3(Position3 pos) => new(pos.X, pos.Z, pos.Y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -72,6 +72,12 @@ namespace Dalamud.Game.Text.SeStringHandling.Payloads
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the raw item ID of this payload.
|
||||||
|
/// </summary>
|
||||||
|
[JsonIgnore]
|
||||||
|
public uint ItemId => this.itemId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the underlying Lumina Item represented by this payload.
|
/// Gets the underlying Lumina Item represented by this payload.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -14,70 +14,3 @@ using System.Diagnostics.CodeAnalysis;
|
||||||
[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.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")]
|
[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.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")]
|
||||||
|
|
||||||
// Extensions
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group extensions with the relevant class", Scope = "type", Target = "~T:Dalamud.Interface.FontAwesomeExtensions")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Enum followed by an extension", Scope = "type", Target = "~T:Dalamud.Interface.FontAwesomeExtensions")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group extensions with the relevant class", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.JobFlagsExt")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Enum followed by an extension", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.JobFlagsExt")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group extensions with the relevant class", Scope = "type", Target = "~T:Dalamud.Game.Text.XivChatTypeExtensions")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "Enum followed by an extension", Scope = "type", Target = "~T:Dalamud.Game.Text.XivChatTypeExtensions")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "Group attributes with the relevant class", Scope = "type", Target = "~T:Dalamud.Game.Text.XivChatTypeInfoAttribute")]
|
|
||||||
|
|
||||||
// DalamudStartInfo.cs
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Interop", Scope = "type", Target = "~T:Dalamud.DalamudStartInfo")]
|
|
||||||
|
|
||||||
// PartyFinder
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "Explicit struct layout", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.PartyFinder.Packet")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:Elements should be ordered by access", Justification = "Explicit struct layout", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.PartyFinder.Listing")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "TODO", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.PartyFinder.Packet")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "TODO", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.PartyFinder.Listing")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "TODO", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Structs.PartyMember")]
|
|
||||||
|
|
||||||
// <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.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.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.Internal.Gui.Structs.AddonOffsets")]
|
|
||||||
|
|
||||||
// Breaking api changes: these should be split into a PartyFinder subdirectory
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.SearchAreaFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.JobFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.ObjectiveFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.ConditionFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.DutyFinderSettingsFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.LootRuleFlags")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.Category")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.Structs.DutyType")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.Internal.Gui.PartyFinderListingEventArgs")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1307:Accessible fields should begin with upper-case letter", Justification = "breaking api change", Scope = "type", Target = "~T:Dalamud.Game.ClientState.Structs.PartyMember")]
|
|
||||||
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "breaking api change", Scope = "member", Target = "~E:Dalamud.Game.Internal.Gui.PartyFinderGui.ReceiveListing")]
|
|
||||||
|
|
||||||
// Breaking api changes
|
|
||||||
[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.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.Text.SeStringHandling.Payload.DataResolver")]
|
|
||||||
[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.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("CodeQuality", "IDE0052:Remove unread private members", Justification = "Unused, but eventually, maybe.", Scope = "member", Target = "~F:Dalamud.Game.ClientState.PartyList.address")]
|
|
||||||
[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.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.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Framework.StatsHistory")]
|
|
||||||
[assembly: SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Framework.StatsHistory")]
|
|
||||||
[assembly: SuppressMessage("Usage", "CA2208:Instantiate argument exceptions correctly", Justification = "Appears to be a bug, it is being used correctly", Scope = "member", Target = "~M:Dalamud.Data.DataManager.Initialize(System.String)")]
|
|
||||||
|
|
||||||
// I mostly didnt care to do these.
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change", Scope = "member", Target = "~F:Dalamud.Game.Internal.Network.GameNetwork.OnNetworkMessage")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketBoardCurrentOfferings")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketBoardCurrentOfferings")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketBoardHistory")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketBoardHistory")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketTaxRates")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.Structures.MarketTaxRates")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.MarketBoardItemRequest")]
|
|
||||||
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "breaking api change.", Scope = "type", Target = "~T:Dalamud.Game.Network.MarketBoardItemRequest")]
|
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,12 @@ namespace Dalamud.Interface.Internal
|
||||||
ShowInHelp = false,
|
ShowInHelp = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.dalamud.CommandManager.AddHandler("/xlime", new CommandInfo(this.OnDebugDrawIMEPanel)
|
||||||
|
{
|
||||||
|
HelpMessage = Loc.Localize("DalamudIMEPanelHelp", "Draw IME panel"),
|
||||||
|
ShowInHelp = false,
|
||||||
|
});
|
||||||
|
|
||||||
this.dalamud.CommandManager.AddHandler("/xllog", new CommandInfo(this.OnOpenLog)
|
this.dalamud.CommandManager.AddHandler("/xllog", new CommandInfo(this.OnOpenLog)
|
||||||
{
|
{
|
||||||
HelpMessage = Loc.Localize("DalamudDevLogHelp", "Open dev log DEBUG"),
|
HelpMessage = Loc.Localize("DalamudDevLogHelp", "Open dev log DEBUG"),
|
||||||
|
|
@ -245,6 +251,11 @@ namespace Dalamud.Interface.Internal
|
||||||
this.dalamud.DalamudUi.OpenDataWindow(arguments);
|
this.dalamud.DalamudUi.OpenDataWindow(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnDebugDrawIMEPanel(string command, string arguments)
|
||||||
|
{
|
||||||
|
this.dalamud.DalamudUi.OpenIMEWindow();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnOpenLog(string command, string arguments)
|
private void OnOpenLog(string command, string arguments)
|
||||||
{
|
{
|
||||||
this.dalamud.DalamudUi.ToggleLogWindow();
|
this.dalamud.DalamudUi.ToggleLogWindow();
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Interface.Internal.Windows;
|
using Dalamud.Interface.Internal.Windows;
|
||||||
|
using Dalamud.Interface.Internal.Windows.SelfTest;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
|
|
@ -31,11 +32,13 @@ namespace Dalamud.Interface.Internal
|
||||||
private readonly CreditsWindow creditsWindow;
|
private readonly CreditsWindow creditsWindow;
|
||||||
private readonly DataWindow dataWindow;
|
private readonly DataWindow dataWindow;
|
||||||
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
|
private readonly GamepadModeNotifierWindow gamepadModeNotifierWindow;
|
||||||
|
private readonly IMEWindow imeWindow;
|
||||||
private readonly ConsoleWindow consoleWindow;
|
private readonly ConsoleWindow consoleWindow;
|
||||||
private readonly PluginStatWindow pluginStatWindow;
|
private readonly PluginStatWindow pluginStatWindow;
|
||||||
private readonly PluginInstallerWindow pluginWindow;
|
private readonly PluginInstallerWindow pluginWindow;
|
||||||
private readonly ScratchpadWindow scratchpadWindow;
|
private readonly ScratchpadWindow scratchpadWindow;
|
||||||
private readonly SettingsWindow settingsWindow;
|
private readonly SettingsWindow settingsWindow;
|
||||||
|
private readonly SelfTestWindow selfTestWindow;
|
||||||
|
|
||||||
private ulong frameCount = 0;
|
private ulong frameCount = 0;
|
||||||
|
|
||||||
|
|
@ -62,11 +65,13 @@ namespace Dalamud.Interface.Internal
|
||||||
this.creditsWindow = new CreditsWindow(dalamud) { IsOpen = false };
|
this.creditsWindow = new CreditsWindow(dalamud) { IsOpen = false };
|
||||||
this.dataWindow = new DataWindow(dalamud) { IsOpen = false };
|
this.dataWindow = new DataWindow(dalamud) { IsOpen = false };
|
||||||
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow();
|
this.gamepadModeNotifierWindow = new GamepadModeNotifierWindow();
|
||||||
|
this.imeWindow = new IMEWindow(dalamud);
|
||||||
this.consoleWindow = new ConsoleWindow(dalamud) { IsOpen = this.dalamud.Configuration.LogOpenAtStartup };
|
this.consoleWindow = new ConsoleWindow(dalamud) { IsOpen = this.dalamud.Configuration.LogOpenAtStartup };
|
||||||
this.pluginStatWindow = new PluginStatWindow(dalamud) { IsOpen = false };
|
this.pluginStatWindow = new PluginStatWindow(dalamud) { IsOpen = false };
|
||||||
this.pluginWindow = new PluginInstallerWindow(dalamud) { IsOpen = false };
|
this.pluginWindow = new PluginInstallerWindow(dalamud) { IsOpen = false };
|
||||||
this.scratchpadWindow = new ScratchpadWindow(dalamud) { IsOpen = false };
|
this.scratchpadWindow = new ScratchpadWindow(dalamud) { IsOpen = false };
|
||||||
this.settingsWindow = new SettingsWindow(dalamud) { IsOpen = false };
|
this.settingsWindow = new SettingsWindow(dalamud) { IsOpen = false };
|
||||||
|
this.selfTestWindow = new SelfTestWindow(dalamud) { IsOpen = false };
|
||||||
|
|
||||||
this.windowSystem.AddWindow(this.changelogWindow);
|
this.windowSystem.AddWindow(this.changelogWindow);
|
||||||
this.windowSystem.AddWindow(this.colorDemoWindow);
|
this.windowSystem.AddWindow(this.colorDemoWindow);
|
||||||
|
|
@ -74,13 +79,15 @@ namespace Dalamud.Interface.Internal
|
||||||
this.windowSystem.AddWindow(this.creditsWindow);
|
this.windowSystem.AddWindow(this.creditsWindow);
|
||||||
this.windowSystem.AddWindow(this.dataWindow);
|
this.windowSystem.AddWindow(this.dataWindow);
|
||||||
this.windowSystem.AddWindow(this.gamepadModeNotifierWindow);
|
this.windowSystem.AddWindow(this.gamepadModeNotifierWindow);
|
||||||
|
this.windowSystem.AddWindow(this.imeWindow);
|
||||||
this.windowSystem.AddWindow(this.consoleWindow);
|
this.windowSystem.AddWindow(this.consoleWindow);
|
||||||
this.windowSystem.AddWindow(this.pluginStatWindow);
|
this.windowSystem.AddWindow(this.pluginStatWindow);
|
||||||
this.windowSystem.AddWindow(this.pluginWindow);
|
this.windowSystem.AddWindow(this.pluginWindow);
|
||||||
this.windowSystem.AddWindow(this.scratchpadWindow);
|
this.windowSystem.AddWindow(this.scratchpadWindow);
|
||||||
this.windowSystem.AddWindow(this.settingsWindow);
|
this.windowSystem.AddWindow(this.settingsWindow);
|
||||||
|
this.windowSystem.AddWindow(this.selfTestWindow);
|
||||||
|
|
||||||
this.dalamud.InterfaceManager.OnDraw += this.OnDraw;
|
this.dalamud.InterfaceManager.Draw += this.OnDraw;
|
||||||
|
|
||||||
Log.Information("Windows added");
|
Log.Information("Windows added");
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +109,7 @@ namespace Dalamud.Interface.Internal
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
this.dalamud.InterfaceManager.OnDraw -= this.OnDraw;
|
this.dalamud.InterfaceManager.Draw -= this.OnDraw;
|
||||||
|
|
||||||
this.windowSystem.RemoveAllWindows();
|
this.windowSystem.RemoveAllWindows();
|
||||||
|
|
||||||
|
|
@ -156,6 +163,11 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true;
|
public void OpenGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.IsOpen = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the <see cref="IMEWindow"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void OpenIMEWindow() => this.imeWindow.IsOpen = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Opens the <see cref="ConsoleWindow"/>.
|
/// Opens the <see cref="ConsoleWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -181,6 +193,20 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void OpenSettings() => this.settingsWindow.IsOpen = true;
|
public void OpenSettings() => this.settingsWindow.IsOpen = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the <see cref="SelfTestWindow"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void OpenSelfTest() => this.selfTestWindow.IsOpen = true;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Close
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes the <see cref="IMEWindow"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void CloseIMEWindow() => this.imeWindow.IsOpen = false;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Toggle
|
#region Toggle
|
||||||
|
|
@ -228,6 +254,11 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle();
|
public void ToggleGamepadModeNotifierWindow() => this.gamepadModeNotifierWindow.Toggle();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the <see cref="IMEWindow"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void ToggleIMEWindow() => this.imeWindow.Toggle();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Toggles the <see cref="ConsoleWindow"/>.
|
/// Toggles the <see cref="ConsoleWindow"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -253,6 +284,11 @@ namespace Dalamud.Interface.Internal
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ToggleSettingsWindow() => this.settingsWindow.Toggle();
|
public void ToggleSettingsWindow() => this.settingsWindow.Toggle();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggles the <see cref="SelfTestWindow"/>.
|
||||||
|
/// </summary>
|
||||||
|
public void ToggleSelfTestWindow() => this.selfTestWindow.Toggle();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnDraw()
|
private void OnDraw()
|
||||||
|
|
@ -383,6 +419,13 @@ namespace Dalamud.Interface.Internal
|
||||||
this.OpenColorsDemoWindow();
|
this.OpenColorsDemoWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui.MenuItem("Open Self-Test"))
|
||||||
|
{
|
||||||
|
this.OpenSelfTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
ImGui.MenuItem("Draw ImGui demo", string.Empty, ref this.isImGuiDrawDemoWindow);
|
ImGui.MenuItem("Draw ImGui demo", string.Empty, ref this.isImGuiDrawDemoWindow);
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
@ -7,7 +8,6 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.ClientState;
|
|
||||||
using Dalamud.Game.ClientState.GamePad;
|
using Dalamud.Game.ClientState.GamePad;
|
||||||
using Dalamud.Game.Internal.DXGI;
|
using Dalamud.Game.Internal.DXGI;
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
|
|
@ -71,10 +71,10 @@ namespace Dalamud.Interface.Internal
|
||||||
|
|
||||||
this.address = sigResolver;
|
this.address = sigResolver;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (KeyNotFoundException)
|
||||||
{
|
{
|
||||||
// The SigScanner method fails on wine/proton since DXGI is not a real DLL. We fall back to vtable to detect our Present function address.
|
// The SigScanner method fails on wine/proton since DXGI is not a real DLL. We fall back to vtable to detect our Present function address.
|
||||||
Log.Debug(ex, "Could not get SwapChain address via sig method, falling back to vtable...");
|
Log.Debug("Could not get SwapChain address via sig method, falling back to vtable");
|
||||||
|
|
||||||
var vtableResolver = new SwapChainVtableResolver();
|
var vtableResolver = new SwapChainVtableResolver();
|
||||||
vtableResolver.Setup(scanner);
|
vtableResolver.Setup(scanner);
|
||||||
|
|
@ -93,7 +93,7 @@ namespace Dalamud.Interface.Internal
|
||||||
var fileName = new StringBuilder(255);
|
var fileName = new StringBuilder(255);
|
||||||
_ = NativeFunctions.GetModuleFileNameW(rtss, fileName, fileName.Capacity);
|
_ = NativeFunctions.GetModuleFileNameW(rtss, fileName, fileName.Capacity);
|
||||||
this.rtssPath = fileName.ToString();
|
this.rtssPath = fileName.ToString();
|
||||||
Log.Verbose("RTSS at {0}", this.rtssPath);
|
Log.Verbose($"RTSS at {this.rtssPath}");
|
||||||
|
|
||||||
if (!NativeFunctions.FreeLibrary(rtss))
|
if (!NativeFunctions.FreeLibrary(rtss))
|
||||||
throw new Win32Exception();
|
throw new Win32Exception();
|
||||||
|
|
@ -131,7 +131,7 @@ namespace Dalamud.Interface.Internal
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This event gets called by a plugin UiBuilder when read
|
/// This event gets called by a plugin UiBuilder when read
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event RawDX11Scene.BuildUIDelegate OnDraw;
|
public event RawDX11Scene.BuildUIDelegate Draw;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the default ImGui font.
|
/// Gets the default ImGui font.
|
||||||
|
|
@ -397,6 +397,8 @@ namespace Dalamud.Interface.Internal
|
||||||
ImGuiHelpers.MainViewport = ImGui.GetMainViewport();
|
ImGuiHelpers.MainViewport = ImGui.GetMainViewport();
|
||||||
|
|
||||||
Log.Information("[IM] Scene & ImGui setup OK!");
|
Log.Information("[IM] Scene & ImGui setup OK!");
|
||||||
|
|
||||||
|
this.dalamud.IME.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process information needed by ImGuiHelpers each frame.
|
// Process information needed by ImGuiHelpers each frame.
|
||||||
|
|
@ -581,8 +583,7 @@ namespace Dalamud.Interface.Internal
|
||||||
this.dalamud.DalamudUi.ToggleGamepadModeNotifierWindow();
|
this.dalamud.DalamudUi.ToggleGamepadModeNotifierWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gamepadEnabled
|
if (gamepadEnabled && (ImGui.GetIO().ConfigFlags & ImGuiConfigFlags.NavEnableGamepad) > 0)
|
||||||
&& (ImGui.GetIO().ConfigFlags & ImGuiConfigFlags.NavEnableGamepad) > 0)
|
|
||||||
{
|
{
|
||||||
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Activate] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.South);
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Activate] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.South);
|
||||||
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Cancel] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.East);
|
ImGui.GetIO().NavInputs[(int)ImGuiNavInput.Cancel] = this.dalamud.ClientState.GamepadState.Raw(GamepadButtons.East);
|
||||||
|
|
@ -621,7 +622,7 @@ namespace Dalamud.Interface.Internal
|
||||||
this.LastImGuiIoPtr = ImGui.GetIO();
|
this.LastImGuiIoPtr = ImGui.GetIO();
|
||||||
this.lastWantCapture = this.LastImGuiIoPtr.WantCaptureMouse;
|
this.lastWantCapture = this.LastImGuiIoPtr.WantCaptureMouse;
|
||||||
|
|
||||||
this.OnDraw?.Invoke();
|
this.Draw?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Dalamud.Interface.Colors;
|
using Dalamud.Interface.Colors;
|
||||||
|
using Dalamud.Interface.Components;
|
||||||
using Dalamud.Interface.Windowing;
|
using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Logging.Internal;
|
using Dalamud.Logging.Internal;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
@ -158,26 +159,38 @@ namespace Dalamud.Interface.Internal.Windows
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.PushFont(InterfaceManager.IconFont);
|
|
||||||
|
|
||||||
if (ImGui.Button(FontAwesomeIcon.Cog.ToIconString()))
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Cog))
|
||||||
ImGui.OpenPopup("Options");
|
ImGui.OpenPopup("Options");
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip("Options");
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGui.Button(FontAwesomeIcon.Search.ToIconString()))
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Search))
|
||||||
ImGui.OpenPopup("Filters");
|
ImGui.OpenPopup("Filters");
|
||||||
|
|
||||||
ImGui.SameLine();
|
if (ImGui.IsItemHovered())
|
||||||
var clear = ImGui.Button(FontAwesomeIcon.Trash.ToIconString());
|
ImGui.SetTooltip("Filters");
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var copy = ImGui.Button(FontAwesomeIcon.Copy.ToIconString());
|
var clear = ImGuiComponents.IconButton(FontAwesomeIcon.Trash);
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip("Clear Log");
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGui.Button(FontAwesomeIcon.Skull.ToIconString()))
|
var copy = ImGuiComponents.IconButton(FontAwesomeIcon.Copy);
|
||||||
|
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip("Copy Log");
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGuiComponents.IconButton(FontAwesomeIcon.Skull))
|
||||||
Process.GetCurrentProcess().Kill();
|
Process.GetCurrentProcess().Kill();
|
||||||
|
|
||||||
ImGui.PopFont();
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip("Kill game");
|
||||||
|
|
||||||
ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 55), false, ImGuiWindowFlags.HorizontalScrollbar);
|
ImGui.BeginChild("scrolling", new Vector2(0, ImGui.GetFrameHeightWithSpacing() - 55), false, ImGuiWindowFlags.HorizontalScrollbar);
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue