mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
feat: New Condition APIs (#1842)
* feat: New Condition APIs - New methods for `ICondition`: - `AnyExcept` ensures the listed conditions are *not* present. - `OnlyAny` ensures that *only* the listed conditions are met. - `EqualTo` ensures that the condition state matches the listed set. - New `IsGameIdle` method in `IClientState` can be used to check if the player is not in any "active" game state.
This commit is contained in:
parent
8f36641f36
commit
1c03242aa9
4 changed files with 88 additions and 29 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
using Dalamud.Data;
|
using Dalamud.Data;
|
||||||
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Game.Gui;
|
using Dalamud.Game.Gui;
|
||||||
|
|
@ -123,6 +125,27 @@ internal sealed class ClientState : IInternalDisposableService, IClientState
|
||||||
/// Gets client state address resolver.
|
/// Gets client state address resolver.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal ClientStateAddressResolver AddressResolver => this.address;
|
internal ClientStateAddressResolver AddressResolver => this.address;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsClientIdle(out ConditionFlag blockingFlag)
|
||||||
|
{
|
||||||
|
blockingFlag = 0;
|
||||||
|
if (this.LocalPlayer is null) return true;
|
||||||
|
|
||||||
|
var condition = Service<Conditions.Condition>.GetNullable();
|
||||||
|
|
||||||
|
var blockingConditions = condition.AsReadOnlySet().Except([
|
||||||
|
ConditionFlag.NormalConditions,
|
||||||
|
ConditionFlag.Jumping,
|
||||||
|
ConditionFlag.Mounted,
|
||||||
|
ConditionFlag.UsingParasol]);
|
||||||
|
|
||||||
|
blockingFlag = blockingConditions.FirstOrDefault();
|
||||||
|
return blockingFlag == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsClientIdle() => this.IsClientIdle(out _);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dispose of managed and unmanaged resources.
|
/// Dispose of managed and unmanaged resources.
|
||||||
|
|
@ -271,6 +294,12 @@ internal class ClientStatePluginScoped : IInternalDisposableService, IClientStat
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool IsGPosing => this.clientStateService.IsGPosing;
|
public bool IsGPosing => this.clientStateService.IsGPosing;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsClientIdle(out ConditionFlag blockingFlag) => this.clientStateService.IsClientIdle(out blockingFlag);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsClientIdle() => this.clientStateService.IsClientIdle();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService()
|
void IInternalDisposableService.DisposeService()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,22 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
void IInternalDisposableService.DisposeService() => this.Dispose(true);
|
void IInternalDisposableService.DisposeService() => this.Dispose(true);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IReadOnlySet<ConditionFlag> AsReadOnlySet()
|
||||||
|
{
|
||||||
|
var result = new HashSet<ConditionFlag>();
|
||||||
|
|
||||||
|
for (var i = 0; i < MaxConditionEntries; i++)
|
||||||
|
{
|
||||||
|
if (this[i])
|
||||||
|
{
|
||||||
|
result.Add((ConditionFlag)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Any()
|
public bool Any()
|
||||||
|
|
@ -100,37 +116,26 @@ internal sealed class Condition : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool AnyExcept(params ConditionFlag[] excluded)
|
||||||
|
{
|
||||||
|
return !this.AsReadOnlySet().Intersect(excluded).Any();
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool OnlyAny(params ConditionFlag[] other)
|
public bool OnlyAny(params ConditionFlag[] other)
|
||||||
{
|
{
|
||||||
var resultSet = this.AsReadOnlySet();
|
return !this.AsReadOnlySet().Except(other).Any();
|
||||||
return !resultSet.Except(other).Any();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool OnlyAll(params ConditionFlag[] other)
|
public bool EqualTo(params ConditionFlag[] other)
|
||||||
{
|
{
|
||||||
var resultSet = this.AsReadOnlySet();
|
var resultSet = this.AsReadOnlySet();
|
||||||
return resultSet.SetEquals(other);
|
return resultSet.SetEquals(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public IReadOnlySet<ConditionFlag> AsReadOnlySet()
|
|
||||||
{
|
|
||||||
var result = new HashSet<ConditionFlag>();
|
|
||||||
|
|
||||||
for (var i = 0; i < MaxConditionEntries; i++)
|
|
||||||
{
|
|
||||||
if (this[i])
|
|
||||||
{
|
|
||||||
result.Add((ConditionFlag)i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool disposing)
|
private void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (this.isDisposed)
|
if (this.isDisposed)
|
||||||
|
|
@ -217,12 +222,15 @@ internal class ConditionPluginScoped : IInternalDisposableService, ICondition
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool Any(params ConditionFlag[] flags) => this.conditionService.Any(flags);
|
public bool Any(params ConditionFlag[] flags) => this.conditionService.Any(flags);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool AnyExcept(params ConditionFlag[] except) => this.conditionService.AnyExcept(except);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool OnlyAny(params ConditionFlag[] other) => this.conditionService.OnlyAny(other);
|
public bool OnlyAny(params ConditionFlag[] other) => this.conditionService.OnlyAny(other);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool OnlyAll(params ConditionFlag[] other) => this.conditionService.OnlyAll(other);
|
public bool EqualTo(params ConditionFlag[] other) => this.conditionService.EqualTo(other);
|
||||||
|
|
||||||
private void ConditionChangedForward(ConditionFlag flag, bool value) => this.ConditionChange?.Invoke(flag, value);
|
private void ConditionChangedForward(ConditionFlag flag, bool value) => this.ConditionChange?.Invoke(flag, value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
|
||||||
namespace Dalamud.Plugin.Services;
|
namespace Dalamud.Plugin.Services;
|
||||||
|
|
@ -81,4 +82,19 @@ public interface IClientState
|
||||||
/// Gets a value indicating whether the client is currently in Group Pose (GPose) mode.
|
/// Gets a value indicating whether the client is currently in Group Pose (GPose) mode.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsGPosing { get; }
|
public bool IsGPosing { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the client is currently "idle". This means a player is not logged in, or is notctively in combat
|
||||||
|
/// or doing anything that we may not want to disrupt.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="blockingFlag">An outvar containing the first observed condition blocking the "idle" state. 0 if idle.</param>
|
||||||
|
/// <returns>Returns true if the client is idle, false otherwise.</returns>
|
||||||
|
public bool IsClientIdle(out ConditionFlag blockingFlag);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the client is currently "idle". This means a player is not logged in, or is notctively in combat
|
||||||
|
/// or doing anything that we may not want to disrupt.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns true if the client is idle, false otherwise.</returns>
|
||||||
|
public bool IsClientIdle() => this.IsClientIdle(out _);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ public interface ICondition
|
||||||
|
|
||||||
/// <inheritdoc cref="this[int]"/>
|
/// <inheritdoc cref="this[int]"/>
|
||||||
public bool this[ConditionFlag flag] => this[(int)flag];
|
public bool this[ConditionFlag flag] => this[(int)flag];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert the conditions array to a set of all set condition flags.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Returns a set.</returns>
|
||||||
|
public IReadOnlySet<ConditionFlag> AsReadOnlySet();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check if any condition flags are set.
|
/// Check if any condition flags are set.
|
||||||
|
|
@ -55,8 +61,14 @@ public interface ICondition
|
||||||
public bool Any(params ConditionFlag[] flags);
|
public bool Any(params ConditionFlag[] flags);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check that *only* any of the condition flags specified are set. Useful to test if the client is in one of any
|
/// Check that the specified condition flags are *not* present in the current conditions.
|
||||||
/// of a few specific condiiton states.
|
/// </summary>
|
||||||
|
/// <param name="except">The array of flags to check.</param>
|
||||||
|
/// <returns>Returns false if any of the listed conditions are present, true otherwise.</returns>
|
||||||
|
public bool AnyExcept(params ConditionFlag[] except);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check that *only* any of the condition flags specified are set.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The array of flags to check.</param>
|
/// <param name="other">The array of flags to check.</param>
|
||||||
/// <returns>Returns a bool.</returns>
|
/// <returns>Returns a bool.</returns>
|
||||||
|
|
@ -68,11 +80,5 @@ public interface ICondition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="other">The array of flags to check.</param>
|
/// <param name="other">The array of flags to check.</param>
|
||||||
/// <returns>Returns a bool.</returns>
|
/// <returns>Returns a bool.</returns>
|
||||||
public bool OnlyAll(params ConditionFlag[] other);
|
public bool EqualTo(params ConditionFlag[] other);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert the conditions array to a set of all set condition flags.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Returns a set.</returns>
|
|
||||||
public IReadOnlySet<ConditionFlag> AsReadOnlySet();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue