Add ICondition (v9) (#1262)

This commit is contained in:
MidoriKami 2023-06-24 17:24:54 -07:00 committed by GitHub
parent 538976667f
commit 2677964fc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 29 deletions

View file

@ -2,6 +2,7 @@ using System;
using Dalamud.IoC; using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog; using Serilog;
namespace Dalamud.Game.ClientState.Conditions; namespace Dalamud.Game.ClientState.Conditions;
@ -12,13 +13,16 @@ namespace Dalamud.Game.ClientState.Conditions;
[PluginInterface] [PluginInterface]
[InterfaceVersion("1.0")] [InterfaceVersion("1.0")]
[ServiceManager.BlockingEarlyLoadedService] [ServiceManager.BlockingEarlyLoadedService]
public sealed partial class Condition : IServiceType #pragma warning disable SA1015
[ResolveVia<ICondition>]
#pragma warning restore SA1015
public sealed partial class Condition : IServiceType, ICondition
{ {
/// <summary> /// <summary>
/// The current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has. /// Gets the current max number of conditions. You can get this just by looking at the condition sheet and how many rows it has.
/// </summary> /// </summary>
public const int MaxConditionEntries = 104; internal const int MaxConditionEntries = 104;
private readonly bool[] cache = new bool[MaxConditionEntries]; private readonly bool[] cache = new bool[MaxConditionEntries];
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
@ -27,29 +31,17 @@ public sealed partial class Condition : IServiceType
var resolver = clientState.AddressResolver; var resolver = clientState.AddressResolver;
this.Address = resolver.ConditionFlags; this.Address = resolver.ConditionFlags;
} }
/// <inheritdoc/>
public event ICondition.ConditionChangeDelegate? ConditionChange;
/// <summary> /// <inheritdoc/>
/// A delegate type used with the <see cref="ConditionChange"/> event. public int MaxEntries => MaxConditionEntries;
/// </summary>
/// <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> /// <inheritdoc/>
/// 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; } public IntPtr Address { get; private set; }
/// <summary> /// <inheritdoc/>
/// Check the value of a specific condition/state flag.
/// </summary>
/// <param name="flag">The condition flag to check.</param>
public unsafe bool this[int flag] public unsafe bool this[int flag]
{ {
get get
@ -61,14 +53,11 @@ public sealed partial class Condition : IServiceType
} }
} }
/// <inheritdoc cref="this[int]"/> /// <inheritdoc/>
public unsafe bool this[ConditionFlag flag] public bool this[ConditionFlag flag]
=> this[(int)flag]; => this[(int)flag];
/// <summary> /// <inheritdoc/>
/// Check if any condition flags are set.
/// </summary>
/// <returns>Whether any single flag is set.</returns>
public bool Any() public bool Any()
{ {
for (var i = 0; i < MaxConditionEntries; i++) for (var i = 0; i < MaxConditionEntries; i++)
@ -81,6 +70,21 @@ public sealed partial class Condition : IServiceType
return false; return false;
} }
/// <inheritdoc/>
public bool Any(params ConditionFlag[] flags)
{
foreach (var flag in flags)
{
// this[i] performs range checking, so no need to check here
if (this[flag])
{
return true;
}
}
return false;
}
[ServiceManager.CallWhenServicesReady] [ServiceManager.CallWhenServicesReady]
private void ContinueConstruction(Framework framework) private void ContinueConstruction(Framework framework)

View file

@ -0,0 +1,54 @@
using Dalamud.Game.ClientState.Conditions;
namespace Dalamud.Plugin.Services;
/// <summary>
/// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc.
/// </summary>
public interface ICondition
{
/// <summary>
/// A delegate type used with the <see cref="ConditionChange"/> event.
/// </summary>
/// <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 current max number of conditions.
/// </summary>
public int MaxEntries { get; }
/// <summary>
/// Gets the condition array base pointer.
/// </summary>
public nint Address { get; }
/// <summary>
/// Check the value of a specific condition/state flag.
/// </summary>
/// <param name="flag">The condition flag to check.</param>
public bool this[int flag] { get; }
/// <inheritdoc cref="this[int]"/>
public bool this[ConditionFlag flag] => this[(int)flag];
/// <summary>
/// Check if any condition flags are set.
/// </summary>
/// <returns>Whether any single flag is set.</returns>
public bool Any();
/// <summary>
/// Check if any provided condition flags are set.
/// </summary>
/// <returns>Whether any single provided flag is set.</returns>
/// <param name="flags">The condition flags to check.</param>
public bool Any(params ConditionFlag[] flags);
}