From 1c6fa9a84dae0b057b32fcbeca83d7b1bdd9aff8 Mon Sep 17 00:00:00 2001
From: XtraCube <72575280+XtraCube@users.noreply.github.com>
Date: Mon, 24 Feb 2025 21:51:02 -0500
Subject: [PATCH] major modifier overhaul
---
MiraAPI/Modifiers/BaseModifier.cs | 23 +-
MiraAPI/Modifiers/ModifierComponent.cs | 270 ++++++++++-----
MiraAPI/Modifiers/ModifierData.cs | 10 +-
MiraAPI/Modifiers/ModifierExtensions.cs | 313 ++++++++++++++----
MiraAPI/Modifiers/ModifierFactory.cs | 43 ++-
MiraAPI/Modifiers/ModifierManager.cs | 8 +-
MiraAPI/Modifiers/Types/TimedModifier.cs | 2 +-
MiraAPI/Networking/AddModifierRpc.cs | 42 ++-
.../Patches/Freeplay/TaskAddButtonPatches.cs | 2 +-
MiraAPI/Patches/Freeplay/TaskAdderPatches.cs | 9 +-
MiraAPI/Patches/PlayerControlPatches.cs | 2 +-
MiraAPI/Patches/Roles/TaskPanelPatch.cs | 2 +-
MiraAPI/Utilities/ModifierExtensions.cs | 252 --------------
13 files changed, 531 insertions(+), 447 deletions(-)
delete mode 100644 MiraAPI/Utilities/ModifierExtensions.cs
diff --git a/MiraAPI/Modifiers/BaseModifier.cs b/MiraAPI/Modifiers/BaseModifier.cs
index 9f6aa93..8834454 100644
--- a/MiraAPI/Modifiers/BaseModifier.cs
+++ b/MiraAPI/Modifiers/BaseModifier.cs
@@ -1,4 +1,6 @@
-namespace MiraAPI.Modifiers;
+using System;
+
+namespace MiraAPI.Modifiers;
///
/// Base class for all modifiers.
@@ -15,11 +17,6 @@ public abstract class BaseModifier
///
public ModifierComponent? ModifierComponent { get; internal set; }
- ///
- /// Gets the modifier id.
- ///
- public uint ModifierId { get; internal set; }
-
///
/// Gets the modifier name.
///
@@ -40,6 +37,20 @@ public abstract class BaseModifier
///
public virtual bool Unique => true;
+ ///
+ /// Gets a value indicating whether the modifier has been initialized.
+ ///
+ public bool Initialized { get; internal set; }
+
+ ///
+ /// Get the ID of the modifier.
+ ///
+ /// The ID of the modifier.
+ public uint GetId()
+ {
+ return ModifierManager.GetModifierId(GetType()) ?? throw new InvalidOperationException("Modifier is not registered.");
+ }
+
///
/// Gets the HUD information for this modifier. Defaults to the modifier name. Does nothing if is true.
///
diff --git a/MiraAPI/Modifiers/ModifierComponent.cs b/MiraAPI/Modifiers/ModifierComponent.cs
index 2b00652..6cd3d5e 100644
--- a/MiraAPI/Modifiers/ModifierComponent.cs
+++ b/MiraAPI/Modifiers/ModifierComponent.cs
@@ -67,6 +67,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
foreach (var modifier in _toAdd)
{
Modifiers.Add(modifier);
+ modifier.Initialized = true;
modifier.OnActivate();
if (modifier is TimedModifier { AutoStart: true } timer)
@@ -123,46 +124,153 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
}
///
- /// Gets a collection of modifiers by their type, or null if the player doesn't have one.
+ /// Gets a collection of modifiers by type.
///
+ /// The predicate to check the modifier by.
/// The Type of the Modifier.
/// The Modifier if it is found, null otherwise.
- public IEnumerable GetModifiersByType() where T : BaseModifier
+ [HideFromIl2Cpp]
+ public IEnumerable GetModifiersByType(Func? predicate=null) where T : BaseModifier
{
- return ActiveModifiers.OfType();
+ return ActiveModifiers.OfType().Where(x => predicate == null || predicate(x));
}
///
- /// Gets a modifier by its type, or null if the player doesn't have it.
+ /// Gets a collection of modifiers by type.
///
- /// The Type of the Modifier.
+ /// The modifier type.
+ /// The predicate to check the modifier by.
/// The Modifier if it is found, null otherwise.
- public T? GetModifier() where T : BaseModifier
+ [HideFromIl2Cpp]
+ public IEnumerable GetModifiersByType(Type type, Func? predicate=null)
{
- return GetModifiersByType().FirstOrDefault();
+ return ActiveModifiers.Where(x => x.GetType() == type && (predicate == null || predicate(x)));
+ }
+
+ ///
+ /// Gets a collection of modifiers by ID.
+ ///
+ /// The Modifier ID.
+ /// The predicate to check the modifier by.
+ /// The Modifier if it is found, null otherwise.
+ [HideFromIl2Cpp]
+ public IEnumerable GetModifiersByType(uint id, Func? predicate=null)
+ {
+ var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
+ $"Cannot get modifier with id {id} because it is not registered.");
+
+ return GetModifiersByType(type, predicate);
}
///
/// Tries to get a modifier by its type.
///
/// The modifier or null.
+ /// The predicate to check the modifier by.
/// The Type of the Modifier.
/// True if the modifier was found, false otherwise.
- public bool TryGetModifier(out T? modifier) where T : BaseModifier
+ [HideFromIl2Cpp]
+ public bool TryGetModifier(out T? modifier, Func? predicate = null) where T : BaseModifier
{
- modifier = GetModifier();
+ modifier = GetModifier(predicate);
return modifier != null;
}
+ ///
+ /// Tries to get a modifier by its type.
+ ///
+ /// The modifier type.
+ /// The modifier or null.
+ /// The predicate to check the modifier by.
+ /// True if the modifier was found, false otherwise.
+ [HideFromIl2Cpp]
+ public bool TryGetModifier(Type type, out BaseModifier? modifier, Func? predicate = null)
+ {
+ modifier = GetModifier(type, predicate);
+ return modifier != null;
+ }
+
+ ///
+ /// Tries to get a modifier by its ID.
+ ///
+ /// The modifier ID.
+ /// The modifier or null.
+ /// The predicate to check the modifier by.
+ /// True if the modifier was found, false otherwise.
+ [HideFromIl2Cpp]
+ public bool TryGetModifier(uint id, out BaseModifier? modifier, Func? predicate = null)
+ {
+ var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
+ $"Cannot get modifier with id {id} because it is not registered.");
+
+ return TryGetModifier(type, out modifier, predicate);
+ }
+
+ ///
+ /// Gets a modifier by its type, or null if the player doesn't have it.
+ ///
+ /// The predicate to check the modifier by.
+ /// The Type of the Modifier.
+ /// The Modifier if it is found, null otherwise.
+ [HideFromIl2Cpp]
+ public T? GetModifier(Func? predicate = null) where T : BaseModifier
+ {
+ return GetModifiersByType(predicate).FirstOrDefault();
+ }
+
+ ///
+ /// Gets a modifier by its type, or null if the player doesn't have it.
+ ///
+ /// The modifier type.
+ /// The predicate to check the modifier by.
+ /// The Modifier if it is found, null otherwise.
+ [HideFromIl2Cpp]
+ public BaseModifier? GetModifier(Type type, Func? predicate = null)
+ {
+ return GetModifiersByType(type).FirstOrDefault(predicate ?? (_ => true));
+ }
+
+ ///
+ /// Gets a modifier by its type, or null if the player doesn't have it.
+ ///
+ /// The modifier ID.
+ /// The predicate to check the modifier by.
+ /// The Modifier if it is found, null otherwise.
+ [HideFromIl2Cpp]
+ public BaseModifier? GetModifier(uint id, Func? predicate = null)
+ {
+ var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
+ $"Cannot get modifier with id {id} because it is not registered.");
+
+ return GetModifier(type, predicate);
+ }
+
+ ///
+ /// Removes a modifier from the player.
+ ///
+ /// The modifier type.
+ /// The predicate to check the modifier by.
+ [HideFromIl2Cpp]
+ public void RemoveModifier(Func? predicate = null) where T : BaseModifier
+ {
+ RemoveModifier(typeof(T), x => predicate == null || predicate((T)x));
+ }
+
///
/// Removes a modifier from the player.
///
/// The modifier type.
+ /// The predicate to check the modifier by.
[HideFromIl2Cpp]
- public void RemoveModifier(Type type)
+ public void RemoveModifier(Type type, Func? predicate = null)
{
- var modifier = Modifiers.Find(x => x.GetType() == type);
+ var modifiers = Modifiers.Where(x => x.GetType() == type && (predicate == null || predicate(x))).ToList();
+ if (modifiers.Count > 1)
+ {
+ throw new InvalidOperationException($"Cannot remove modifier {type.Name} because there are multiple instances of that modifier.");
+ }
+ var modifier = modifiers.FirstOrDefault();
if (modifier is null)
{
Logger.Error($"Cannot remove modifier {type.Name} because it is not active.");
@@ -172,32 +280,17 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
RemoveModifier(modifier);
}
- ///
- /// Removes a modifier from the player.
- ///
- /// The modifier type.
- [HideFromIl2Cpp]
- public void RemoveModifier() where T : BaseModifier
- {
- RemoveModifier(typeof(T));
- }
-
///
/// Removes a modifier from the player.
///
/// The modifier ID.
+ /// The predicate to check the modifier by.
[HideFromIl2Cpp]
- public void RemoveModifier(uint modifierId)
+ public void RemoveModifier(uint modifierId, Func? predicate = null)
{
- var modifier = Modifiers.Find(x => x.ModifierId == modifierId);
-
- if (modifier is null)
- {
- Logger.Error($"Cannot remove modifier with id {modifierId} because it is not active.");
- return;
- }
-
- RemoveModifier(modifier);
+ var type = ModifierManager.GetModifierType(modifierId) ?? throw new InvalidOperationException(
+ $"Cannot remove modifier with id {modifierId} because it is not registered.");
+ RemoveModifier(type, predicate);
}
///
@@ -216,6 +309,18 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
_toRemove.Add(modifier);
}
+ ///
+ /// Adds a modifier to the player.
+ ///
+ /// The arguments to initialize the modifier constructor with.
+ /// The Type of the modifier.
+ /// The new modifier.
+ [HideFromIl2Cpp]
+ public T? AddModifier(params object[] args) where T : BaseModifier
+ {
+ return AddModifier(typeof(T), args) as T;
+ }
+
///
/// Adds a modifier to the player.
///
@@ -224,24 +329,22 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
[HideFromIl2Cpp]
public BaseModifier? AddModifier(BaseModifier modifier)
{
- if (Modifiers.Contains(modifier))
+ var id = modifier.GetId();
+ if (modifier.Unique && Modifiers.Find(x => x.GetId() == id) != null)
{
- Logger.Error($"Player already has modifier with id {modifier.ModifierId}!");
+ Logger.Error($"Player already has modifier with id {id}!");
return null;
}
- var modifierId = ModifierManager.GetModifierId(modifier.GetType());
-
- if (modifierId == null)
+ if (Modifiers.Contains(modifier))
{
- Logger.Error($"Cannot add modifier {modifier.GetType().Name} because it has no ID!");
+ Logger.Error($"Player already has this modifier!");
return null;
}
_toAdd.Add(modifier);
modifier.Player = _player;
modifier.ModifierComponent = this;
- modifier.ModifierId = modifierId.Value;
return modifier;
}
@@ -249,66 +352,79 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr)
/// Adds a modifier to the player.
///
/// The modifier type.
+ /// The arguments to initialize the modifier constructor with.
/// The modifier that was added.
[HideFromIl2Cpp]
- public BaseModifier? AddModifier(Type type)
+ public BaseModifier? AddModifier(Type type, params object[] args)
{
- var modifierId = ModifierManager.GetModifierId(type);
- if (modifierId == null)
+ BaseModifier? modifier;
+ if (args.Length > 0)
{
- Logger.Error($"Cannot add modifier {type.Name} because it is not registered.");
- return null;
+ modifier = ModifierFactory.CreateInstance(type, args);
+ }
+ else
+ {
+ modifier = Activator.CreateInstance(type) as BaseModifier;
+ if (modifier == null)
+ {
+ throw new InvalidOperationException($"Cannot add modifier {type.Name} because it is not a valid modifier.");
+ }
}
- if (Modifiers.Find(x => x.ModifierId == modifierId && x.Unique) != null)
- {
- Logger.Error($"Player already has modifier with id {modifierId}!");
- return null;
- }
-
- if (Activator.CreateInstance(type) is not BaseModifier modifier)
- {
- Logger.Error($"Cannot add modifier {type.Name} because it is null.");
- return null;
- }
-
- AddModifier(modifier);
-
- return modifier;
+ return AddModifier(modifier);
}
///
/// Adds a modifier to the player.
///
- /// The Type of the modifier.
- /// The new modifier.
+ /// The ID of the modifier.
+ /// The arguments to initialize the modifier constructor with.
+ /// The modifier if it was created, or null if it failed.
[HideFromIl2Cpp]
- public T? AddModifier() where T : BaseModifier
+ public BaseModifier? AddModifier(uint id, params object[] args)
{
- return AddModifier(typeof(T)) as T;
+ var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
+ $"Cannot add modifier with id {id} because it is not registered.");
+
+ return AddModifier(type, args);
}
///
- /// Checks if a player has an active or queued modifier by its ID.
- ///
- /// The Modifier ID.
- /// The predicate to check the modifier.
- /// True if the Modifier is present, false otherwise.
- public bool HasModifier(uint id, Func? predicate=null)
- {
- return ActiveModifiers.Exists(x => x.ModifierId == id && (predicate == null || predicate(x))) ||
- _toAdd.Exists(x => x.ModifierId == id && (predicate == null || predicate(x)));
- }
-
- ///
- /// Checks if a player has an active or queued modifier by its type.
+ /// Checks if a player has an active modifier by its type.
///
/// The predicate to check the modifier.
/// The Type of the Modifier.
/// True if the Modifier is present, false otherwise.
+ [HideFromIl2Cpp]
public bool HasModifier(Func? predicate=null) where T : BaseModifier
{
- return ModifierManager.GetModifierId(typeof(T)) is { } id &&
- HasModifier(id, (Func?)predicate);
+ return ActiveModifiers.Exists(x => x is T modifier && (predicate == null || predicate(modifier)));
+ }
+
+ ///
+ /// Checks if a player has an active modifier by its type.
+ ///
+ /// The modifier type.
+ /// The predicate to check the modifier.
+ /// True if the Modifier is present, false otherwise.
+ [HideFromIl2Cpp]
+ public bool HasModifier(Type type, Func? predicate=null)
+ {
+ return ActiveModifiers.Exists(x => x.GetType() == type && (predicate == null || predicate(x)));
+ }
+
+ ///
+ /// Checks if a player has an active modifier by its ID.
+ ///
+ /// The Modifier ID.
+ /// The predicate to check the modifier.
+ /// True if the Modifier is present, false otherwise.
+ [HideFromIl2Cpp]
+ public bool HasModifier(uint id, Func? predicate=null)
+ {
+ var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException(
+ $"Cannot get modifier with id {id} because it is not registered.");
+
+ return HasModifier(type, predicate);
}
}
diff --git a/MiraAPI/Modifiers/ModifierData.cs b/MiraAPI/Modifiers/ModifierData.cs
index 425e063..7260834 100644
--- a/MiraAPI/Modifiers/ModifierData.cs
+++ b/MiraAPI/Modifiers/ModifierData.cs
@@ -1,18 +1,16 @@
-using System;
-
-namespace MiraAPI.Modifiers;
+namespace MiraAPI.Modifiers;
///
/// Modifier data for networking.
///
-/// The Type of the modifier.
+/// The ID of the modifier.
/// Parameters for constructor.
-public readonly struct ModifierData(Type type, object[] args)
+public readonly struct ModifierData(uint id, object[] args)
{
///
/// Gets the type of the modifier.
///
- public Type Type { get; } = type;
+ public uint Id { get; } = id;
///
/// Gets the parameters for the constructor.
diff --git a/MiraAPI/Modifiers/ModifierExtensions.cs b/MiraAPI/Modifiers/ModifierExtensions.cs
index d6ce5ff..226b16b 100644
--- a/MiraAPI/Modifiers/ModifierExtensions.cs
+++ b/MiraAPI/Modifiers/ModifierExtensions.cs
@@ -8,11 +8,81 @@ using Reactor.Utilities;
namespace MiraAPI.Modifiers;
///
-/// Extension methods for modifiers.
+/// Extensions for modifiers.
///
public static class ModifierExtensions
{
- internal static Dictionary ModifierComponents { get; } = [];
+ ///
+ /// Gets the dictionary to cache ModifierComponents.
+ ///
+ public static Dictionary ModifierComponents { get; } = [];
+
+ ///
+ /// Remote Procedure Call to add a modifier to a player.
+ ///
+ /// The player to add the modifier to.
+ /// The modifier ID.
+ /// The arguments to initialize the modifier constructor with.
+ public static void RpcAddModifier(this PlayerControl target, uint modifierId, params object[] args)
+ {
+ _ = ModifierManager.GetModifierType(modifierId) ?? throw new InvalidOperationException(
+ $"Modifier with ID {modifierId} is not registered.");
+
+ Rpc.Instance.Send(target, new ModifierData(modifierId, args));
+ }
+
+ ///
+ /// Remote Procedure Call to add a modifier to a player.
+ ///
+ /// The player to add the modifier to.
+ /// The type of the modifier.
+ /// The arguments to initialize the modifier constructor with.
+ public static void RpcAddModifier(this PlayerControl player, Type type, params object[] args)
+ {
+ var id = ModifierManager.GetModifierId(type) ?? throw new InvalidOperationException(
+ $"Modifier {type.Name} is not registered.");
+
+ player.RpcAddModifier(id, args);
+ }
+
+ ///
+ /// Remote Procedure Call to add a modifier to a player.
+ ///
+ /// The player to add the modifier to.
+ /// The arguments to initialize the modifier constructor with.
+ /// The modifier Type.
+ public static void RpcAddModifier(this PlayerControl player, params object[] args) where T : BaseModifier
+ {
+ player.RpcAddModifier(typeof(T), args);
+ }
+
+ ///
+ /// Remote Procedure Call to remove a modifier from a player.
+ ///
+ /// The player to remove the modifier from.
+ /// The ID of the modifier.
+ [MethodRpc((uint)MiraRpc.RemoveModifier)]
+ public static void RpcRemoveModifier(this PlayerControl target, uint modifierId)
+ {
+ target.RemoveModifier(modifierId);
+ }
+
+ ///
+ /// Remote Procedure Call to remove a modifier from a player.
+ ///
+ /// The player to remove the modifier from.
+ /// The Type of the Modifier.
+ public static void RpcRemoveModifier(this PlayerControl player) where T : BaseModifier
+ {
+ var id = ModifierManager.GetModifierId(typeof(T));
+ if (id == null)
+ {
+ Logger.Error($"Cannot add modifier {typeof(T).Name} because it is not registered.");
+ return;
+ }
+
+ player.RpcRemoveModifier(id.Value);
+ }
///
/// Gets the ModifierComponent for a player.
@@ -37,102 +107,217 @@ public static class ModifierExtensions
}
///
- /// Gets a modifier by its type, or null if the player doesn't have it.
+ /// Checks if the player has a specific modifier.
///
- /// The PlayerControl object.
- /// The Type of the Modifier.
- /// The Modifier if it is found, null otherwise.
- public static T? GetModifier(this PlayerControl? player) where T : BaseModifier
+ /// The type of the modifier.
+ /// The PlayerControl instance.
+ /// Optional predicate to filter the modifiers.
+ /// True if the player has the modifier, false otherwise.
+ public static bool HasModifier(this PlayerControl player, Func? predicate = null) where T : BaseModifier
{
- return player?.GetModifierComponent()?.ActiveModifiers.Find(x => x is T) as T;
+ return player.GetModifierComponent()!.HasModifier(predicate);
}
///
- /// Checks if a player has a modifier.
+ /// Checks if the player has a specific modifier by type.
///
- /// The PlayerControl object.
- /// The Type of the Modifier.
- /// True if the Modifier is present, false otherwise.
- public static bool HasModifier(this PlayerControl? player) where T : BaseModifier
+ /// The PlayerControl instance.
+ /// The type of the modifier.
+ /// Optional predicate to filter the modifiers.
+ /// True if the player has the modifier, false otherwise.
+ public static bool HasModifier(this PlayerControl player, Type type, Func? predicate = null)
{
- return player?.GetModifierComponent() != null &&
- player.GetModifierComponent()!.HasModifier();
+ return player.GetModifierComponent()!.HasModifier(type, predicate);
}
///
- /// Checks if a player has a modifier by its ID.
+ /// Checks if the player has a specific modifier by ID.
///
- /// The PlayerControl object.
- /// The Modifier ID.
- /// True if the Modifier is present, false otherwise.
- public static bool HasModifier(this PlayerControl? player, uint id)
+ /// The PlayerControl instance.
+ /// The ID of the modifier.
+ /// Optional predicate to filter the modifiers.
+ /// True if the player has the modifier, false otherwise.
+ public static bool HasModifier(this PlayerControl player, uint id, Func? predicate = null)
{
- return player?.GetModifierComponent() != null &&
- player.GetModifierComponent()!.HasModifier(id);
+ return player.GetModifierComponent()!.HasModifier(id, predicate);
}
///
- /// Remote Procedure Call to remove a modifier from a player.
+ /// Gets a specific modifier from the player.
///
- /// The player to remove the modifier from.
+ /// The type of the modifier.
+ /// The PlayerControl instance.
+ /// Optional predicate to filter the modifiers.
+ /// The modifier if found, null otherwise.
+ public static T? GetModifier(this PlayerControl player, Func? predicate = null) where T : BaseModifier
+ {
+ return player.GetModifierComponent()!.GetModifier(predicate);
+ }
+
+ ///
+ /// Gets a specific modifier from the player by type.
+ ///
+ /// The PlayerControl instance.
+ /// The type of the modifier.
+ /// Optional predicate to filter the modifiers.
+ /// The modifier if found, null otherwise.
+ public static BaseModifier? GetModifier(
+ this PlayerControl player,
+ Type type,
+ Func? predicate = null)
+ {
+ return player.GetModifierComponent()!.GetModifier(type, predicate);
+ }
+
+ ///
+ /// Gets a specific modifier from the player by ID.
+ ///
+ /// The PlayerControl instance.
+ /// The ID of the modifier.
+ /// Optional predicate to filter the modifiers.
+ /// The modifier if found, null otherwise.
+ public static BaseModifier? GetModifier(
+ this PlayerControl player,
+ uint id,
+ Func? predicate = null)
+ {
+ return player.GetModifierComponent()!.GetModifier(id, predicate);
+ }
+
+ ///
+ /// Gets all modifiers of a specific type from the player.
+ ///
+ /// The type of the modifiers.
+ /// The PlayerControl instance.
+ /// Optional predicate to filter the modifiers.
+ /// An enumerable of modifiers.
+ public static IEnumerable GetModifiersByType(this PlayerControl player, Func? predicate = null)
+ where T : BaseModifier
+ {
+ return player.GetModifierComponent()!.GetModifiersByType(predicate);
+ }
+
+ ///
+ /// Gets all modifiers of a specific type from the player.
+ ///
+ /// The PlayerControl instance.
+ /// The type of the modifiers.
+ /// Optional predicate to filter the modifiers.
+ /// An enumerable of modifiers.
+ public static IEnumerable GetModifiersByType(
+ this PlayerControl player,
+ Type type,
+ Func? predicate = null)
+ {
+ return player.GetModifierComponent()!.GetModifiersByType(type, predicate);
+ }
+
+ ///
+ /// Gets all modifiers of a specific type from the player by ID.
+ ///
+ /// The PlayerControl instance.
+ /// The ID of the modifiers.
+ /// Optional predicate to filter the modifiers.
+ /// An enumerable of modifiers.
+ public static IEnumerable GetModifiersByType(
+ this PlayerControl player,
+ uint id,
+ Func? predicate = null)
+ {
+ return player.GetModifierComponent()!.GetModifiersByType(id, predicate);
+ }
+
+ ///
+ /// Removes a specific modifier from the player.
+ ///
+ /// The type of the modifier.
+ /// The PlayerControl instance.
+ /// Optional predicate to filter the modifiers.
+ public static void RemoveModifier(this PlayerControl player, Func? predicate = null)
+ where T : BaseModifier
+ {
+ player.GetModifierComponent()!.RemoveModifier(predicate);
+ }
+
+ ///
+ /// Removes a specific modifier from the player by type.
+ ///
+ /// The PlayerControl instance.
+ /// The type of the modifier.
+ /// Optional predicate to filter the modifiers.
+ public static void RemoveModifier(this PlayerControl player, Type type, Func? predicate = null)
+ {
+ player.GetModifierComponent()!.RemoveModifier(type, predicate);
+ }
+
+ ///
+ /// Removes a specific modifier from the player by ID.
+ ///
+ /// The PlayerControl instance.
/// The ID of the modifier.
- [MethodRpc((uint)MiraRpc.RemoveModifier)]
- public static void RpcRemoveModifier(this PlayerControl target, uint modifierId)
+ /// Optional predicate to filter the modifiers.
+ public static void RemoveModifier(
+ this PlayerControl player,
+ uint modifierId,
+ Func? predicate = null)
{
- target.GetModifierComponent()?.RemoveModifier(modifierId);
+ player.GetModifierComponent()!.RemoveModifier(modifierId, predicate);
}
///
- /// Remote Procedure Call to remove a modifier from a player.
+ /// Removes a specific modifier from the player.
///
- /// The player to remove the modifier from.
- /// The Type of the Modifier.
- public static void RpcRemoveModifier(this PlayerControl player) where T : BaseModifier
+ /// The PlayerControl instance.
+ /// The modifier to remove.
+ public static void RemoveModifier(this PlayerControl player, BaseModifier modifier)
{
- var id = ModifierManager.GetModifierId(typeof(T));
-
- if (id == null)
- {
- Logger.Error($"Cannot add modifier {typeof(T).Name} because it is not registered.");
- return;
- }
-
- player.RpcRemoveModifier(id.Value);
+ player.GetModifierComponent()!.RemoveModifier(modifier);
}
///
- /// Remote Procedure Call to add a modifier to a player.
+ /// Adds a specific modifier to the player.
///
- /// The player to add the modifier to.
- /// The modifier ID.
+ /// The type of the modifier.
+ /// The PlayerControl instance.
/// The arguments to initialize the modifier constructor with.
- public static void RpcAddModifier(this PlayerControl target, uint modifierId, params object[] args)
+ /// The added modifier.
+ public static T? AddModifier(this PlayerControl player, params object[] args) where T : BaseModifier
{
- var type = ModifierManager.GetModifierType(modifierId);
- if (type == null)
- {
- Logger.Error($"Cannot add modifier with id {modifierId} because it is not registered.");
- return;
- }
-
- Rpc.Instance.Send(target, new ModifierData(type, args));
+ return player.GetModifierComponent()!.AddModifier(args);
}
///
- /// Remote Procedure Call to add a modifier to a player.
+ /// Adds a specific modifier to the player.
///
- /// The player to add the modifier to.
- /// The arguments to initialize the modifier constructor with.
- /// The modifier Type.
- public static void RpcAddModifier(this PlayerControl player, params object[] args) where T : BaseModifier
+ /// The PlayerControl instance.
+ /// The modifier to add.
+ /// The added modifier.
+ public static BaseModifier? AddModifier(this PlayerControl player, BaseModifier modifier)
{
- var id = ModifierManager.GetModifierId(typeof(T));
- if (id == null)
- {
- Logger.Error($"Cannot add modifier {typeof(T).Name} because it is not registered.");
- return;
- }
+ return player.GetModifierComponent()!.AddModifier(modifier);
+ }
- player.RpcAddModifier(id.Value, args);
+ ///
+ /// Adds a specific modifier to the player by type.
+ ///
+ /// The PlayerControl instance.
+ /// The type of the modifier.
+ /// The arguments to initialize the modifier constructor with.
+ /// The added modifier.
+ public static BaseModifier? AddModifier(this PlayerControl player, Type type, params object[] args)
+ {
+ return player.GetModifierComponent()!.AddModifier(type, args);
+ }
+
+ ///
+ /// Adds a specific modifier to the player by ID.
+ ///
+ /// The PlayerControl instance.
+ /// The ID of the modifier.
+ /// The arguments to initialize the modifier constructor with.
+ /// The added modifier.
+ public static BaseModifier? AddModifier(this PlayerControl player, uint id, params object[] args)
+ {
+ return player.GetModifierComponent()!.AddModifier(id, args);
}
}
diff --git a/MiraAPI/Modifiers/ModifierFactory.cs b/MiraAPI/Modifiers/ModifierFactory.cs
index e1b018c..d145b82 100644
--- a/MiraAPI/Modifiers/ModifierFactory.cs
+++ b/MiraAPI/Modifiers/ModifierFactory.cs
@@ -1,18 +1,28 @@
using System;
-using System.Linq;
using System.Linq.Expressions;
namespace MiraAPI.Modifiers;
+///
+/// Factory for creating instances of a modifier. More efficient than using reflection.
+///
public static class ModifierFactory
{
private static Func