mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
feat: condition changed event, expose condition address
This commit is contained in:
parent
b0f2486215
commit
37fc6ffc73
4 changed files with 116 additions and 26 deletions
|
|
@ -153,6 +153,19 @@ namespace Dalamud
|
|||
Service<NetworkHandlers>.Set();
|
||||
Log.Information("[T2] NH OK!");
|
||||
|
||||
try
|
||||
{
|
||||
Service<DataManager>.Set().Initialize(this.AssetDirectory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Could not initialize DataManager.");
|
||||
this.Unload();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Information("[T2] Data OK!");
|
||||
|
||||
var clientState = Service<ClientState>.Set();
|
||||
Log.Information("[T2] CS OK!");
|
||||
|
||||
|
|
@ -192,19 +205,6 @@ namespace Dalamud
|
|||
Log.Information(e, "Could not init IME.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Service<DataManager>.Set().Initialize(this.AssetDirectory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e, "Could not initialize DataManager.");
|
||||
this.Unload();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.Information("[T2] Data OK!");
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
Service<SeStringManager>.Set();
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ namespace Dalamud.Game.ClientState
|
|||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
Service<Condition>.Get().Enable();
|
||||
Service<GamepadState>.Get().Enable();
|
||||
this.setupTerritoryTypeHook.Enable();
|
||||
}
|
||||
|
|
@ -135,6 +136,7 @@ namespace Dalamud.Game.ClientState
|
|||
public void Dispose()
|
||||
{
|
||||
this.setupTerritoryTypeHook.Dispose();
|
||||
Service<Condition>.Get().Dispose();
|
||||
Service<GamepadState>.Get().Dispose();
|
||||
Service<Framework>.Get().Update -= this.FrameworkOnOnUpdateEvent;
|
||||
Service<NetworkHandlers>.Get().CfPop -= this.NetworkHandlersOnCfPop;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.ClientState.Conditions
|
||||
{
|
||||
|
|
@ -10,45 +11,61 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
/// </summary>
|
||||
[PluginInterface]
|
||||
[InterfaceVersion("1.0")]
|
||||
public class Condition
|
||||
public sealed partial class Condition
|
||||
{
|
||||
/// <summary>
|
||||
/// The current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has.
|
||||
/// </summary>
|
||||
public const int MaxConditionEntries = 100;
|
||||
|
||||
private readonly bool[] cache = new bool[MaxConditionEntries];
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Condition"/> class.
|
||||
/// </summary>
|
||||
/// <param name="resolver">The ClientStateAddressResolver instance.</param>
|
||||
internal Condition(ClientStateAddressResolver resolver)
|
||||
{
|
||||
this.ConditionArrayBase = resolver.ConditionFlags;
|
||||
this.Address = resolver.ConditionFlags;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the condition array base pointer.
|
||||
/// Would typically be private but is used in /xldata windows.
|
||||
/// A delegate type used with the <see cref="ConditionChange"/> event.
|
||||
/// </summary>
|
||||
internal IntPtr ConditionArrayBase { get; private set; }
|
||||
/// <param name="flag">The changed condition.</param>
|
||||
/// <param name="value">The value the condition is set to.</param>
|
||||
public delegate void ConditionChangeDelegate(ConditionFlag flag, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when a condition is set.
|
||||
/// Should only get fired for actual changes, so the previous value will always be !value.
|
||||
/// </summary>
|
||||
public event ConditionChangeDelegate? ConditionChange;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the condition array base pointer.
|
||||
/// </summary>
|
||||
public IntPtr Address { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Check the value of a specific condition/state flag.
|
||||
/// </summary>
|
||||
/// <param name="flag">The condition flag to check.</param>
|
||||
public unsafe bool this[ConditionFlag flag]
|
||||
public unsafe bool this[int flag]
|
||||
{
|
||||
get
|
||||
{
|
||||
var idx = (int)flag;
|
||||
|
||||
if (idx < 0 || idx >= MaxConditionEntries)
|
||||
if (flag < 0 || flag >= MaxConditionEntries)
|
||||
return false;
|
||||
|
||||
return *(bool*)(this.ConditionArrayBase + idx);
|
||||
return *(bool*)(this.Address + flag);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="this[int]"/>
|
||||
public unsafe bool this[ConditionFlag flag]
|
||||
=> this[(int)flag];
|
||||
|
||||
/// <summary>
|
||||
/// Check if any condition flags are set.
|
||||
/// </summary>
|
||||
|
|
@ -57,8 +74,7 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
{
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
{
|
||||
var typedCondition = (ConditionFlag)i;
|
||||
var cond = this[typedCondition];
|
||||
var cond = this[i];
|
||||
|
||||
if (cond)
|
||||
return true;
|
||||
|
|
@ -66,5 +82,77 @@ namespace Dalamud.Game.ClientState.Conditions
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables the hooks of the Condition class function.
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
// Initialization
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
this.cache[i] = this[i];
|
||||
|
||||
Service<Framework>.Get().Update += this.FrameworkUpdate;
|
||||
}
|
||||
|
||||
private void FrameworkUpdate(Framework framework)
|
||||
{
|
||||
for (var i = 0; i < MaxConditionEntries; i++)
|
||||
{
|
||||
var value = this[i];
|
||||
|
||||
if (value != this.cache[i])
|
||||
{
|
||||
this.cache[i] = value;
|
||||
|
||||
try
|
||||
{
|
||||
this.ConditionChange?.Invoke((ConditionFlag)i, value);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"While invoking {nameof(this.ConditionChange)}, an exception was thrown.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc.
|
||||
/// </summary>
|
||||
public sealed partial class Condition : IDisposable
|
||||
{
|
||||
private bool isDisposed;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="Condition" /> class.
|
||||
/// </summary>
|
||||
~Condition()
|
||||
{
|
||||
this.Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this instance, alongside its hooks.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
this.Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (this.isDisposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Service<Framework>.Get().Update -= this.FrameworkUpdate;
|
||||
}
|
||||
|
||||
this.isDisposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -674,7 +674,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
var condition = Service<Condition>.Get();
|
||||
|
||||
#if DEBUG
|
||||
ImGui.Text($"ptr: 0x{condition.ConditionArrayBase.ToInt64():X}");
|
||||
ImGui.Text($"ptr: 0x{condition.Address.ToInt64():X}");
|
||||
#endif
|
||||
|
||||
ImGui.Text("Current Conditions:");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue