From caa27642db35486f326ac6e81a8f2e4ab539faed Mon Sep 17 00:00:00 2001 From: XtraCube <72575280+XtraCube@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:22:00 -0500 Subject: [PATCH] further modifier improvements (massive changes) --- MiraAPI.Example/Buttons/TestButton.cs | 6 + .../Events/Vanilla/Usables/PlayerUseEvent.cs | 2 +- MiraAPI/Modifiers/BaseModifier.cs | 13 +- MiraAPI/Modifiers/ModifierComponent.cs | 155 +++++++++----- MiraAPI/Modifiers/ModifierExtensions.cs | 191 ++++++++++++------ MiraAPI/Modifiers/ModifierManager.cs | 24 +-- .../{ => Modifiers}/AddModifierRpc.cs | 2 +- .../{ => Modifiers}/SyncModifiersRpc.cs | 2 +- .../Patches/Events/KillAnimationPatches.cs | 2 +- MiraAPI/Patches/Events/UsePatches.cs | 2 +- .../Patches/Freeplay/TaskAddButtonPatches.cs | 2 +- MiraAPI/Patches/Freeplay/TaskAdderPatches.cs | 8 +- .../Patches/Modifiers/EndGameDidWinPatch.cs | 2 +- MiraAPI/Patches/VentPatches.cs | 4 +- 14 files changed, 276 insertions(+), 139 deletions(-) rename MiraAPI/Networking/{ => Modifiers}/AddModifierRpc.cs (97%) rename MiraAPI/Networking/{ => Modifiers}/SyncModifiersRpc.cs (97%) diff --git a/MiraAPI.Example/Buttons/TestButton.cs b/MiraAPI.Example/Buttons/TestButton.cs index feb7992..776dc40 100644 --- a/MiraAPI.Example/Buttons/TestButton.cs +++ b/MiraAPI.Example/Buttons/TestButton.cs @@ -15,6 +15,12 @@ public class TestButton : CustomActionButton protected override void OnClick() { + if (PlayerControl.LocalPlayer.HasModifier()) + { + PlayerControl.LocalPlayer.RpcRemoveModifier(); + return; + } + var randomPlayer = PlayerControl.AllPlayerControls.ToArray().Random(); PlayerControl.LocalPlayer.RpcAddModifier("test", 1, randomPlayer); } diff --git a/MiraAPI/Events/Vanilla/Usables/PlayerUseEvent.cs b/MiraAPI/Events/Vanilla/Usables/PlayerUseEvent.cs index 655a46c..5f05676 100644 --- a/MiraAPI/Events/Vanilla/Usables/PlayerUseEvent.cs +++ b/MiraAPI/Events/Vanilla/Usables/PlayerUseEvent.cs @@ -1,4 +1,4 @@ -namespace MiraAPI.Events.Vanilla; +namespace MiraAPI.Events.Vanilla.Usables; /// /// Event for using a from Vanilla Among Us. Will always be ran locally. diff --git a/MiraAPI/Modifiers/BaseModifier.cs b/MiraAPI/Modifiers/BaseModifier.cs index 8834454..21ce064 100644 --- a/MiraAPI/Modifiers/BaseModifier.cs +++ b/MiraAPI/Modifiers/BaseModifier.cs @@ -43,13 +43,14 @@ public abstract class BaseModifier public bool Initialized { get; internal set; } /// - /// Get the ID of the modifier. + /// Gets the unique ID of the modifier. /// - /// The ID of the modifier. - public uint GetId() - { - return ModifierManager.GetModifierId(GetType()) ?? throw new InvalidOperationException("Modifier is not registered."); - } + public uint UniqueId { get; internal set; } + + /// + /// Gets the type ID of the modifier. + /// + public uint TypeId => ModifierManager.GetModifierTypeId(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 6cd3d5e..94ab3db 100644 --- a/MiraAPI/Modifiers/ModifierComponent.cs +++ b/MiraAPI/Modifiers/ModifierComponent.cs @@ -37,6 +37,14 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) private readonly List _toAdd = []; + private uint _nextUniqueId; + + private uint GetNextUniqueId() + { + _nextUniqueId++; + return _nextUniqueId; + } + internal void ClearModifiers() { _toRemove.AddRange(Modifiers); @@ -104,14 +112,12 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) return; } - var filteredModifiers = Modifiers.Where(mod => !mod.HideOnUi); + var filteredModifiers = Modifiers.Where(mod => !mod.HideOnUi).ToArray(); - var baseModifiers = filteredModifiers as BaseModifier[] ?? filteredModifiers.ToArray(); - - if (baseModifiers.Length != 0 && !MeetingHud.Instance) + if (filteredModifiers.Length != 0 && !MeetingHud.Instance) { var stringBuild = new StringBuilder(); - foreach (var mod in baseModifiers) + foreach (var mod in filteredModifiers) { stringBuild.Append(CultureInfo.InvariantCulture, $"\n{mod.GetHudString()}"); } @@ -128,11 +134,11 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) /// /// The predicate to check the modifier by. /// The Type of the Modifier. - /// The Modifier if it is found, null otherwise. + /// A collection of modifiers. [HideFromIl2Cpp] - public IEnumerable GetModifiersByType(Func? predicate=null) where T : BaseModifier + public IEnumerable GetModifiers(Func? predicate=null) where T : BaseModifier { - return ActiveModifiers.OfType().Where(x => predicate == null || predicate(x)); + return Modifiers.OfType().Where(x => predicate == null || predicate(x)); } /// @@ -140,26 +146,26 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) /// /// The modifier type. /// The predicate to check the modifier by. - /// The Modifier if it is found, null otherwise. + /// A collection of modifiers. [HideFromIl2Cpp] - public IEnumerable GetModifiersByType(Type type, Func? predicate=null) + public IEnumerable GetModifiers(Type type, Func? predicate=null) { - return ActiveModifiers.Where(x => x.GetType() == type && (predicate == null || predicate(x))); + return Modifiers.Where(x => x.GetType() == type && (predicate == null || predicate(x))); } /// - /// Gets a collection of modifiers by ID. + /// Gets a collection of modifiers by type ID. /// - /// The Modifier ID. + /// The modifier's type ID. /// The predicate to check the modifier by. - /// The Modifier if it is found, null otherwise. + /// A collection of modifiers. [HideFromIl2Cpp] - public IEnumerable GetModifiersByType(uint id, Func? predicate=null) + public IEnumerable GetModifiers(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); + return GetModifiers(type, predicate); } /// @@ -191,23 +197,34 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) } /// - /// Tries to get a modifier by its ID. + /// Tries to get a modifier by its type ID. /// - /// The modifier ID. + /// The modifier type 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) + public bool TryGetModifierByTypeId(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); + modifier = GetModifierByTypeId(id, predicate); + return modifier != null; } /// - /// Gets a modifier by its type, or null if the player doesn't have it. + /// Tries to get a modifier by its unique ID. + /// + /// The modifier unique ID. + /// The modifier or null. + /// True if the modifier was found, false otherwise. + [HideFromIl2Cpp] + public bool TryGetModifierByUniqueId(uint id, out BaseModifier? modifier) + { + modifier = GetModifierByUniqueId(id); + return modifier != null; + } + + /// + /// Gets a modifier by its type. /// /// The predicate to check the modifier by. /// The Type of the Modifier. @@ -215,11 +232,11 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) [HideFromIl2Cpp] public T? GetModifier(Func? predicate = null) where T : BaseModifier { - return GetModifiersByType(predicate).FirstOrDefault(); + return GetModifiers(predicate).FirstOrDefault(); } /// - /// Gets a modifier by its type, or null if the player doesn't have it. + /// Gets a modifier by its type. /// /// The modifier type. /// The predicate to check the modifier by. @@ -227,17 +244,17 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) [HideFromIl2Cpp] public BaseModifier? GetModifier(Type type, Func? predicate = null) { - return GetModifiersByType(type).FirstOrDefault(predicate ?? (_ => true)); + return GetModifiers(type).FirstOrDefault(predicate ?? (_ => true)); } /// - /// Gets a modifier by its type, or null if the player doesn't have it. + /// Gets a modifier by its type ID. /// /// 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) + public BaseModifier? GetModifierByTypeId(uint id, Func? predicate = null) { var type = ModifierManager.GetModifierType(id) ?? throw new InvalidOperationException( $"Cannot get modifier with id {id} because it is not registered."); @@ -245,6 +262,17 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) return GetModifier(type, predicate); } + /// + /// Gets a modifier by unique ID. + /// + /// The modifier's unique ID. + /// The modifier if it is found, or null. + [HideFromIl2Cpp] + public BaseModifier? GetModifierByUniqueId(uint id) + { + return Modifiers.Find(x => x.UniqueId == id); + } + /// /// Removes a modifier from the player. /// @@ -280,19 +308,6 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) RemoveModifier(modifier); } - /// - /// Removes a modifier from the player. - /// - /// The modifier ID. - /// The predicate to check the modifier by. - [HideFromIl2Cpp] - public void RemoveModifier(uint modifierId, Func? predicate = null) - { - var type = ModifierManager.GetModifierType(modifierId) ?? throw new InvalidOperationException( - $"Cannot remove modifier with id {modifierId} because it is not registered."); - RemoveModifier(type, predicate); - } - /// /// Removes a modifier from the player. /// @@ -309,6 +324,36 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) _toRemove.Add(modifier); } + /// + /// Removes a modifier from the player. + /// + /// The modifier's type ID. + /// The predicate to check the modifier by. + [HideFromIl2Cpp] + public void RemoveModifierByTypeId(uint typeId, Func? predicate = null) + { + var type = ModifierManager.GetModifierType(typeId) ?? throw new InvalidOperationException( + $"Cannot remove modifier with id {typeId} because it is not registered."); + RemoveModifier(type, predicate); + } + + /// + /// Removes a modifier from the player. + /// + /// The modifier's unique ID. + [HideFromIl2Cpp] + public void RemoveModifierByUniqueId(uint uniqueId) + { + var modifier = GetModifierByUniqueId(uniqueId); + if (modifier == null) + { + Logger.Error($"Cannot remove modifier with unique id {uniqueId} because it is not active."); + return; + } + + RemoveModifier(modifier); + } + /// /// Adds a modifier to the player. /// @@ -329,8 +374,8 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) [HideFromIl2Cpp] public BaseModifier? AddModifier(BaseModifier modifier) { - var id = modifier.GetId(); - if (modifier.Unique && Modifiers.Find(x => x.GetId() == id) != null) + var id = modifier.TypeId; + if (modifier.Unique && Modifiers.Find(x => x.TypeId == id) != null) { Logger.Error($"Player already has modifier with id {id}!"); return null; @@ -345,6 +390,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) _toAdd.Add(modifier); modifier.Player = _player; modifier.ModifierComponent = this; + modifier.UniqueId = GetNextUniqueId(); return modifier; } @@ -398,7 +444,7 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) [HideFromIl2Cpp] public bool HasModifier(Func? predicate=null) where T : BaseModifier { - return ActiveModifiers.Exists(x => x is T modifier && (predicate == null || predicate(modifier))); + return Modifiers.Exists(x => x is T modifier && (predicate == null || predicate(modifier))); } /// @@ -410,21 +456,32 @@ public class ModifierComponent(IntPtr cppPtr) : MonoBehaviour(cppPtr) [HideFromIl2Cpp] public bool HasModifier(Type type, Func? predicate=null) { - return ActiveModifiers.Exists(x => x.GetType() == type && (predicate == null || predicate(x))); + return Modifiers.Exists(x => x.GetType() == type && (predicate == null || predicate(x))); } /// - /// Checks if a player has an active modifier by its ID. + /// Checks if a player has an active modifier by its type ID /// - /// The Modifier ID. + /// The Modifier type ID. /// The predicate to check the modifier. /// True if the Modifier is present, false otherwise. [HideFromIl2Cpp] - public bool HasModifier(uint id, Func? predicate=null) + public bool HasModifierByTypeId(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); } + + /// + /// Checks if a player has an active modifier by its unique ID + /// + /// The Modifier type ID. + /// True if the Modifier is present, false otherwise. + [HideFromIl2Cpp] + public bool HasModifierByUniqueId(uint id) + { + return Modifiers.Exists(x => x.UniqueId == id); + } } diff --git a/MiraAPI/Modifiers/ModifierExtensions.cs b/MiraAPI/Modifiers/ModifierExtensions.cs index 226b16b..5b42c6b 100644 --- a/MiraAPI/Modifiers/ModifierExtensions.cs +++ b/MiraAPI/Modifiers/ModifierExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using MiraAPI.Networking; +using MiraAPI.Networking.Modifiers; using Reactor.Networking.Attributes; using Reactor.Networking.Rpc; using Reactor.Utilities; @@ -21,14 +22,14 @@ public static class ModifierExtensions /// Remote Procedure Call to add a modifier to a player. /// /// The player to add the modifier to. - /// The modifier ID. + /// The modifier type ID. /// The arguments to initialize the modifier constructor with. - public static void RpcAddModifier(this PlayerControl target, uint modifierId, params object[] args) + public static void RpcAddModifier(this PlayerControl target, uint typeId, params object[] args) { - _ = ModifierManager.GetModifierType(modifierId) ?? throw new InvalidOperationException( - $"Modifier with ID {modifierId} is not registered."); + _ = ModifierManager.GetModifierType(typeId) ?? throw new InvalidOperationException( + $"Modifier with ID {typeId} is not registered."); - Rpc.Instance.Send(target, new ModifierData(modifierId, args)); + Rpc.Instance.Send(target, new ModifierData(typeId, args)); } /// @@ -39,7 +40,7 @@ public static class ModifierExtensions /// 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( + var id = ModifierManager.GetModifierTypeId(type) ?? throw new InvalidOperationException( $"Modifier {type.Name} is not registered."); player.RpcAddModifier(id, args); @@ -60,28 +61,61 @@ public static class ModifierExtensions /// Remote Procedure Call to remove a modifier from a player. /// /// The player to remove the modifier from. - /// The ID of the modifier. + /// The unique ID of the modifier. [MethodRpc((uint)MiraRpc.RemoveModifier)] - public static void RpcRemoveModifier(this PlayerControl target, uint modifierId) + public static void RpcRemoveModifierByUniqueId(this PlayerControl target, uint uniqueId) { - target.RemoveModifier(modifierId); + target.RemoveModifierByUniqueId(uniqueId); + } + + /// + /// Remote Procedure Call to remove a modifier from a player by type ID. + /// + /// The player to remove the modifier from. + /// The type ID of the modifier. + /// Optional predicate to filter the modifiers. + public static void RpcRemoveModifierByTypeId( + this PlayerControl target, + uint typeId, + Func? predicate = null) + { + var modifier = target.GetModifierByTypeId(typeId, predicate); + if (modifier is null) + { + Logger.Error($"Player {target.PlayerId} does not have modifier with type ID {typeId}."); + return; + } + + target.RpcRemoveModifierByUniqueId(modifier.UniqueId); } /// /// 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 + /// The type of the modifier. + /// Optional predicate to filter the modifiers. + public static void RpcRemoveModifier( + this PlayerControl player, + Type type, + Func? predicate = null) { - var id = ModifierManager.GetModifierId(typeof(T)); - if (id == null) - { - Logger.Error($"Cannot add modifier {typeof(T).Name} because it is not registered."); - return; - } + var id = ModifierManager.GetModifierTypeId(type) ?? throw new InvalidOperationException( + $"Modifier {type.Name} is not registered."); - player.RpcRemoveModifier(id.Value); + player.RpcRemoveModifierByTypeId(id, predicate); + } + + /// + /// Remote Procedure Call to remove a modifier from a player. + /// + /// The player to remove the modifier from. + /// Optional predicate to filter the modifiers. + /// The Type of the Modifier. + public static void RpcRemoveModifier(this PlayerControl player, Func? predicate = null) + where T : BaseModifier + { + player.RpcRemoveModifier(typeof(T), predicate); } /// @@ -89,7 +123,7 @@ public static class ModifierExtensions /// /// The PlayerControl object. /// A ModifierComponent if there is one, null otherwise. - public static ModifierComponent? GetModifierComponent(this PlayerControl player) + public static ModifierComponent GetModifierComponent(this PlayerControl player) { if (ModifierComponents.TryGetValue(player, out var component)) { @@ -97,9 +131,9 @@ public static class ModifierExtensions } component = player.GetComponent(); - if (component == null) + if (!component) { - return null; + throw new InvalidOperationException("ModifierComponent is not attached to the player."); } ModifierComponents[player] = component; @@ -115,7 +149,7 @@ public static class ModifierExtensions /// 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()!.HasModifier(predicate); + return player.GetModifierComponent().HasModifier(predicate); } /// @@ -127,19 +161,33 @@ public static class ModifierExtensions /// True if the player has the modifier, false otherwise. public static bool HasModifier(this PlayerControl player, Type type, Func? predicate = null) { - return player.GetModifierComponent()!.HasModifier(type, predicate); + return player.GetModifierComponent().HasModifier(type, predicate); } /// - /// Checks if the player has a specific modifier by ID. + /// Checks if the player has a specific modifier by type ID. /// /// The PlayerControl instance. - /// The ID of the modifier. + /// The type 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) + public static bool HasModifierByTypeId( + this PlayerControl player, + uint id, + Func? predicate = null) { - return player.GetModifierComponent()!.HasModifier(id, predicate); + return player.GetModifierComponent().HasModifierByTypeId(id, predicate); + } + + /// + /// Checks if the player has a specific modifier by unique ID. + /// + /// The PlayerControl instance. + /// The unique ID of the modifier. + /// True if the player has the modifier, false otherwise. + public static bool HasModifierByUniqueId(this PlayerControl player, uint id) + { + return player.GetModifierComponent().HasModifierByUniqueId(id); } /// @@ -151,7 +199,7 @@ public static class ModifierExtensions /// The modifier if found, null otherwise. public static T? GetModifier(this PlayerControl player, Func? predicate = null) where T : BaseModifier { - return player.GetModifierComponent()!.GetModifier(predicate); + return player.GetModifierComponent().GetModifier(predicate); } /// @@ -166,7 +214,22 @@ public static class ModifierExtensions Type type, Func? predicate = null) { - return player.GetModifierComponent()!.GetModifier(type, predicate); + return player.GetModifierComponent().GetModifier(type, predicate); + } + + /// + /// Gets a specific modifier from the player by type ID. + /// + /// The PlayerControl instance. + /// The type ID of the modifier. + /// Optional predicate to filter the modifiers. + /// The modifier if found, null otherwise. + public static BaseModifier? GetModifierByTypeId( + this PlayerControl player, + uint id, + Func? predicate = null) + { + return player.GetModifierComponent().GetModifierByTypeId(id, predicate); } /// @@ -174,14 +237,12 @@ public static class ModifierExtensions /// /// The PlayerControl instance. /// The ID of the modifier. - /// Optional predicate to filter the modifiers. /// The modifier if found, null otherwise. - public static BaseModifier? GetModifier( + public static BaseModifier? GetModifierByUniqueId( this PlayerControl player, - uint id, - Func? predicate = null) + uint id) { - return player.GetModifierComponent()!.GetModifier(id, predicate); + return player.GetModifierComponent().GetModifierByUniqueId(id); } /// @@ -191,10 +252,10 @@ public static class ModifierExtensions /// The PlayerControl instance. /// Optional predicate to filter the modifiers. /// An enumerable of modifiers. - public static IEnumerable GetModifiersByType(this PlayerControl player, Func? predicate = null) + public static IEnumerable GetModifiers(this PlayerControl player, Func? predicate = null) where T : BaseModifier { - return player.GetModifierComponent()!.GetModifiersByType(predicate); + return player.GetModifierComponent().GetModifiers(predicate); } /// @@ -204,27 +265,37 @@ public static class ModifierExtensions /// The type of the modifiers. /// Optional predicate to filter the modifiers. /// An enumerable of modifiers. - public static IEnumerable GetModifiersByType( + public static IEnumerable GetModifiers( this PlayerControl player, Type type, Func? predicate = null) { - return player.GetModifierComponent()!.GetModifiersByType(type, predicate); + return player.GetModifierComponent().GetModifiers(type, predicate); } /// - /// Gets all modifiers of a specific type from the player by ID. + /// Gets all modifiers of a specific type from the player by type ID. /// /// The PlayerControl instance. - /// The ID of the modifiers. + /// The type ID of the modifiers. /// Optional predicate to filter the modifiers. /// An enumerable of modifiers. - public static IEnumerable GetModifiersByType( + public static IEnumerable GetModifiers( this PlayerControl player, uint id, Func? predicate = null) { - return player.GetModifierComponent()!.GetModifiersByType(id, predicate); + return player.GetModifierComponent().GetModifiers(id, predicate); + } + + /// + /// Removes a specific modifier from the player. + /// + /// The PlayerControl instance. + /// The modifier to remove. + public static void RemoveModifier(this PlayerControl player, BaseModifier modifier) + { + player.GetModifierComponent().RemoveModifier(modifier); } /// @@ -236,7 +307,7 @@ public static class ModifierExtensions public static void RemoveModifier(this PlayerControl player, Func? predicate = null) where T : BaseModifier { - player.GetModifierComponent()!.RemoveModifier(predicate); + player.GetModifierComponent().RemoveModifier(predicate); } /// @@ -247,31 +318,33 @@ public static class ModifierExtensions /// Optional predicate to filter the modifiers. public static void RemoveModifier(this PlayerControl player, Type type, Func? predicate = null) { - player.GetModifierComponent()!.RemoveModifier(type, predicate); + player.GetModifierComponent().RemoveModifier(type, predicate); } /// /// Removes a specific modifier from the player by ID. /// /// The PlayerControl instance. - /// The ID of the modifier. + /// The ID of the modifier. /// Optional predicate to filter the modifiers. - public static void RemoveModifier( + public static void RemoveModifierByTypeId( this PlayerControl player, - uint modifierId, + uint typeId, Func? predicate = null) { - player.GetModifierComponent()!.RemoveModifier(modifierId, predicate); + player.GetModifierComponent().RemoveModifierByTypeId(typeId, predicate); } /// - /// Removes a specific modifier from the player. + /// Removes a specific modifier from the player by ID. /// /// The PlayerControl instance. - /// The modifier to remove. - public static void RemoveModifier(this PlayerControl player, BaseModifier modifier) + /// The ID of the modifier. + public static void RemoveModifierByUniqueId( + this PlayerControl player, + uint uniqueId) { - player.GetModifierComponent()!.RemoveModifier(modifier); + player.GetModifierComponent().RemoveModifierByUniqueId(uniqueId); } /// @@ -283,7 +356,7 @@ public static class ModifierExtensions /// The added modifier. public static T? AddModifier(this PlayerControl player, params object[] args) where T : BaseModifier { - return player.GetModifierComponent()!.AddModifier(args); + return player.GetModifierComponent().AddModifier(args); } /// @@ -294,7 +367,7 @@ public static class ModifierExtensions /// The added modifier. public static BaseModifier? AddModifier(this PlayerControl player, BaseModifier modifier) { - return player.GetModifierComponent()!.AddModifier(modifier); + return player.GetModifierComponent().AddModifier(modifier); } /// @@ -306,18 +379,18 @@ public static class ModifierExtensions /// The added modifier. public static BaseModifier? AddModifier(this PlayerControl player, Type type, params object[] args) { - return player.GetModifierComponent()!.AddModifier(type, args); + return player.GetModifierComponent().AddModifier(type, args); } /// - /// Adds a specific modifier to the player by ID. + /// Adds a specific modifier to the player by type ID. /// /// The PlayerControl instance. - /// The ID of the modifier. + /// The type 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) + public static BaseModifier? AddModifier(this PlayerControl player, uint typeId, params object[] args) { - return player.GetModifierComponent()!.AddModifier(id, args); + return player.GetModifierComponent().AddModifier(typeId, args); } } diff --git a/MiraAPI/Modifiers/ModifierManager.cs b/MiraAPI/Modifiers/ModifierManager.cs index 65341a0..209423e 100644 --- a/MiraAPI/Modifiers/ModifierManager.cs +++ b/MiraAPI/Modifiers/ModifierManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.Serialization; using MiraAPI.Modifiers.Types; using MiraAPI.Networking; +using MiraAPI.Networking.Modifiers; using MiraAPI.PluginLoading; using MiraAPI.Roles; using MiraAPI.Utilities; @@ -23,16 +24,16 @@ public static class ModifierManager private static readonly Dictionary TypeToIdModifierMap = []; private static readonly Dictionary> PrioritiesToIdsMap = []; - private static uint _nextId; + private static uint _nextTypeId; - private static uint GetNextId() + private static uint GetNextTypeId() { - _nextId++; - return _nextId; + _nextTypeId++; + return _nextTypeId; } /// - /// Gets the modifier type from the id. + /// Gets the modifier type from the type id. /// /// The ID. /// The Type of the modifier. @@ -46,7 +47,7 @@ public static class ModifierManager /// /// The Type. /// The ID of the modifier. - public static uint? GetModifierId(Type type) + public static uint? GetModifierTypeId(Type type) { if (!TypeToIdModifierMap.TryGetValue(type, out var id)) { @@ -63,8 +64,8 @@ public static class ModifierManager return false; } - IdToTypeModifierMap.Add(GetNextId(), modifierType); - TypeToIdModifierMap.Add(modifierType, _nextId); + IdToTypeModifierMap.Add(GetNextTypeId(), modifierType); + TypeToIdModifierMap.Add(modifierType, _nextTypeId); var bm = (BaseModifier)FormatterServices.GetUninitializedObject(modifierType); // this probably isn't a great idea info.Modifiers.Add(bm); @@ -81,7 +82,7 @@ public static class ModifierManager PrioritiesToIdsMap[priority] = list = []; } - list.Add(_nextId); + list.Add(_nextTypeId); return true; } @@ -143,7 +144,7 @@ public static class ModifierManager var mod = Activator.CreateInstance(IdToTypeModifierMap[id]) as GameModifier; var plr = plrs.Where(x => IsGameModifierValid(x, mod!, id)).Random(); - if (plr == null) + if (!plr || plr == null) { Logger.Warning($"Somehow valid players for modifier {mod!.ModifierName} disappeared"); } @@ -158,8 +159,7 @@ public static class ModifierManager private static bool IsGameModifierValid(PlayerControl player, GameModifier modifier, uint modifierId) { return (player.Data.Role is not ICustomRole role || role.IsModifierApplicable(modifier)) && - modifier.IsModifierValidOn(player.Data.Role) && - !player.HasModifier(modifierId); + modifier.IsModifierValidOn(player.Data.Role) && !player.HasModifierByTypeId(modifierId); } internal static void SyncAllModifiers(int targetId = -1) diff --git a/MiraAPI/Networking/AddModifierRpc.cs b/MiraAPI/Networking/Modifiers/AddModifierRpc.cs similarity index 97% rename from MiraAPI/Networking/AddModifierRpc.cs rename to MiraAPI/Networking/Modifiers/AddModifierRpc.cs index fdc37a9..5727ba5 100644 --- a/MiraAPI/Networking/AddModifierRpc.cs +++ b/MiraAPI/Networking/Modifiers/AddModifierRpc.cs @@ -5,7 +5,7 @@ using Reactor.Networking.Attributes; using Reactor.Networking.Rpc; using Reactor.Networking.Serialization; -namespace MiraAPI.Networking; +namespace MiraAPI.Networking.Modifiers; /// /// Remote procedure call for adding a modifier. diff --git a/MiraAPI/Networking/SyncModifiersRpc.cs b/MiraAPI/Networking/Modifiers/SyncModifiersRpc.cs similarity index 97% rename from MiraAPI/Networking/SyncModifiersRpc.cs rename to MiraAPI/Networking/Modifiers/SyncModifiersRpc.cs index 288e2c1..0571198 100644 --- a/MiraAPI/Networking/SyncModifiersRpc.cs +++ b/MiraAPI/Networking/Modifiers/SyncModifiersRpc.cs @@ -3,7 +3,7 @@ using MiraAPI.Modifiers; using Reactor.Networking.Attributes; using Reactor.Networking.Rpc; -namespace MiraAPI.Networking; +namespace MiraAPI.Networking.Modifiers; [RegisterCustomRpc((uint)MiraRpc.SyncModifiers)] internal sealed class SyncModifiersRpc(MiraApiPlugin plugin, uint id) : PlayerCustomRpc(plugin, id) diff --git a/MiraAPI/Patches/Events/KillAnimationPatches.cs b/MiraAPI/Patches/Events/KillAnimationPatches.cs index 13b4cff..3572ff8 100644 --- a/MiraAPI/Patches/Events/KillAnimationPatches.cs +++ b/MiraAPI/Patches/Events/KillAnimationPatches.cs @@ -2,7 +2,7 @@ using MiraAPI.Events; using MiraAPI.Events.Vanilla.Gameplay; -namespace MiraAPI.Patches; +namespace MiraAPI.Patches.Events; /// /// General patches for the KillAnimation class. diff --git a/MiraAPI/Patches/Events/UsePatches.cs b/MiraAPI/Patches/Events/UsePatches.cs index beb1f69..0571cd6 100644 --- a/MiraAPI/Patches/Events/UsePatches.cs +++ b/MiraAPI/Patches/Events/UsePatches.cs @@ -1,8 +1,8 @@ using HarmonyLib; using MiraAPI.Events; -using MiraAPI.Events.Vanilla; using System.Collections.Generic; using System.Reflection; +using MiraAPI.Events.Vanilla.Usables; namespace MiraAPI.Patches.Events; diff --git a/MiraAPI/Patches/Freeplay/TaskAddButtonPatches.cs b/MiraAPI/Patches/Freeplay/TaskAddButtonPatches.cs index 184bafb..0ee6da4 100644 --- a/MiraAPI/Patches/Freeplay/TaskAddButtonPatches.cs +++ b/MiraAPI/Patches/Freeplay/TaskAddButtonPatches.cs @@ -16,7 +16,7 @@ internal static class TaskAddButtonPatches if (uint.TryParse(__instance.name, out var result)) { __instance.Overlay.sprite = __instance.CheckImage; - __instance.Overlay.enabled = PlayerControl.LocalPlayer.HasModifier(result); + __instance.Overlay.enabled = PlayerControl.LocalPlayer.HasModifierByTypeId(result); return false; } diff --git a/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs b/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs index b634c91..0c35670 100644 --- a/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs +++ b/MiraAPI/Patches/Freeplay/TaskAdderPatches.cs @@ -326,7 +326,7 @@ internal static class TaskAdderPatches } var taskAddButton = Object.Instantiate(instance.RoleButton); - taskAddButton.name = modifier.GetId().ToString(NumberFormatInfo.InvariantInfo); + taskAddButton.name = modifier.TypeId.ToString(NumberFormatInfo.InvariantInfo); taskAddButton.role = null; taskAddButton.MyTask = null; taskAddButton.SafePositionWorld = instance.SafePositionWorld; @@ -336,10 +336,10 @@ internal static class TaskAdderPatches taskAddButton.Button.OnClick = new Button.ButtonClickedEvent(); taskAddButton.Button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => { - var id = modifier.GetId(); - if (PlayerControl.LocalPlayer.HasModifier(id)) + var id = modifier.TypeId; + if (PlayerControl.LocalPlayer.HasModifierByTypeId(id)) { - PlayerControl.LocalPlayer.RemoveModifier(id); + PlayerControl.LocalPlayer.RemoveModifierByTypeId(id); taskAddButton.Overlay.enabled = false; } else diff --git a/MiraAPI/Patches/Modifiers/EndGameDidWinPatch.cs b/MiraAPI/Patches/Modifiers/EndGameDidWinPatch.cs index 17356db..a86383d 100644 --- a/MiraAPI/Patches/Modifiers/EndGameDidWinPatch.cs +++ b/MiraAPI/Patches/Modifiers/EndGameDidWinPatch.cs @@ -24,7 +24,7 @@ public static class EndGameDidWinPatch var didWin = networkedPlayerInfo.Role.DidWin(gameOverReason); - var modifierWin = networkedPlayerInfo.Object?.GetModifierComponent()?.ActiveModifiers.OfType() + var modifierWin = networkedPlayerInfo.Object?.GetModifierComponent().GetModifiers() .FirstOrDefault(x => x.DidWin(gameOverReason) != null)?.DidWin(gameOverReason); if (modifierWin != null) { diff --git a/MiraAPI/Patches/VentPatches.cs b/MiraAPI/Patches/VentPatches.cs index 8aa174b..2f8991d 100644 --- a/MiraAPI/Patches/VentPatches.cs +++ b/MiraAPI/Patches/VentPatches.cs @@ -35,8 +35,8 @@ public static class VentPatches var canVent = role is ICustomRole customRole ? customRole.Configuration.CanUseVent : role.CanVent; couldUse = canVent; - var modifiers = @object.GetModifierComponent()?.ActiveModifiers; - if (modifiers is { Count: > 0 }) + var modifiers = @object.GetModifierComponent().ActiveModifiers; + if (modifiers.Count > 0) { switch (canVent) {