From 2677964fc547d3ef1198ea58561ed29a4b3a9f52 Mon Sep 17 00:00:00 2001 From: MidoriKami <9083275+MidoriKami@users.noreply.github.com> Date: Sat, 24 Jun 2023 17:24:54 -0700 Subject: [PATCH] Add ICondition (v9) (#1262) --- .../Game/ClientState/Conditions/Condition.cs | 62 ++++++++++--------- Dalamud/Plugin/Services/ICondition.cs | 54 ++++++++++++++++ 2 files changed, 87 insertions(+), 29 deletions(-) create mode 100644 Dalamud/Plugin/Services/ICondition.cs diff --git a/Dalamud/Game/ClientState/Conditions/Condition.cs b/Dalamud/Game/ClientState/Conditions/Condition.cs index f611a01c6..b72c91c74 100644 --- a/Dalamud/Game/ClientState/Conditions/Condition.cs +++ b/Dalamud/Game/ClientState/Conditions/Condition.cs @@ -2,6 +2,7 @@ using System; using Dalamud.IoC; using Dalamud.IoC.Internal; +using Dalamud.Plugin.Services; using Serilog; namespace Dalamud.Game.ClientState.Conditions; @@ -12,13 +13,16 @@ namespace Dalamud.Game.ClientState.Conditions; [PluginInterface] [InterfaceVersion("1.0")] [ServiceManager.BlockingEarlyLoadedService] -public sealed partial class Condition : IServiceType +#pragma warning disable SA1015 +[ResolveVia] +#pragma warning restore SA1015 +public sealed partial class Condition : IServiceType, ICondition { /// - /// 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. /// - public const int MaxConditionEntries = 104; - + internal const int MaxConditionEntries = 104; + private readonly bool[] cache = new bool[MaxConditionEntries]; [ServiceManager.ServiceConstructor] @@ -27,29 +31,17 @@ public sealed partial class Condition : IServiceType var resolver = clientState.AddressResolver; this.Address = resolver.ConditionFlags; } + + /// + public event ICondition.ConditionChangeDelegate? ConditionChange; - /// - /// A delegate type used with the event. - /// - /// The changed condition. - /// The value the condition is set to. - public delegate void ConditionChangeDelegate(ConditionFlag flag, bool value); + /// + public int MaxEntries => MaxConditionEntries; - /// - /// Event that gets fired when a condition is set. - /// Should only get fired for actual changes, so the previous value will always be !value. - /// - public event ConditionChangeDelegate? ConditionChange; - - /// - /// Gets the condition array base pointer. - /// + /// public IntPtr Address { get; private set; } - /// - /// Check the value of a specific condition/state flag. - /// - /// The condition flag to check. + /// public unsafe bool this[int flag] { get @@ -61,14 +53,11 @@ public sealed partial class Condition : IServiceType } } - /// - public unsafe bool this[ConditionFlag flag] + /// + public bool this[ConditionFlag flag] => this[(int)flag]; - /// - /// Check if any condition flags are set. - /// - /// Whether any single flag is set. + /// public bool Any() { for (var i = 0; i < MaxConditionEntries; i++) @@ -81,6 +70,21 @@ public sealed partial class Condition : IServiceType return false; } + + /// + 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] private void ContinueConstruction(Framework framework) diff --git a/Dalamud/Plugin/Services/ICondition.cs b/Dalamud/Plugin/Services/ICondition.cs new file mode 100644 index 000000000..9700cef5a --- /dev/null +++ b/Dalamud/Plugin/Services/ICondition.cs @@ -0,0 +1,54 @@ +using Dalamud.Game.ClientState.Conditions; + +namespace Dalamud.Plugin.Services; + +/// +/// Provides access to conditions (generally player state). You can check whether a player is in combat, mounted, etc. +/// +public interface ICondition +{ + /// + /// A delegate type used with the event. + /// + /// The changed condition. + /// The value the condition is set to. + public delegate void ConditionChangeDelegate(ConditionFlag flag, bool value); + + /// + /// Event that gets fired when a condition is set. + /// Should only get fired for actual changes, so the previous value will always be !value. + /// + public event ConditionChangeDelegate? ConditionChange; + + /// + /// Gets the current max number of conditions. + /// + public int MaxEntries { get; } + + /// + /// Gets the condition array base pointer. + /// + public nint Address { get; } + + /// + /// Check the value of a specific condition/state flag. + /// + /// The condition flag to check. + public bool this[int flag] { get; } + + /// + public bool this[ConditionFlag flag] => this[(int)flag]; + + /// + /// Check if any condition flags are set. + /// + /// Whether any single flag is set. + public bool Any(); + + /// + /// Check if any provided condition flags are set. + /// + /// Whether any single provided flag is set. + /// The condition flags to check. + public bool Any(params ConditionFlag[] flags); +}