diff --git a/EXILED/Exiled.Events/EventArgs/Scp939/SettingMimicPointEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp939/SettingMimicPointEventArgs.cs new file mode 100644 index 0000000000..6c6bd51a64 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Scp939/SettingMimicPointEventArgs.cs @@ -0,0 +1,48 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +namespace Exiled.Events.EventArgs.Scp939 +{ + using API.Features; + using Exiled.API.Features.Roles; + using Interfaces; + + /// + /// Contains all information before SCP-939 plays a stolen player's voice. + /// + public class SettingMimicPointEventArgs : IScp939Event, IDeniableEvent + { + /// + /// Initializes a new instance of the class. + /// + /// + /// + /// + /// /// + /// Indicates whether the mimic point can be placed or not. + /// + public SettingMimicPointEventArgs(Player player, bool isAllowed = true) + { + Player = player; + Scp939 = Player.Role.As(); + IsAllowed = isAllowed; + } + + /// + /// Gets or sets a value indicating whether SCP-939 can play the stolen voice. + /// + public bool IsAllowed { get; set; } + + /// + /// Gets the player who's controlling SCP-939. + /// + public Player Player { get; } + + /// + public Scp939Role Scp939 { get; } + } +} \ No newline at end of file diff --git a/EXILED/Exiled.Events/Handlers/Scp939.cs b/EXILED/Exiled.Events/Handlers/Scp939.cs index d2ca5e4533..ba94aa3b1d 100644 --- a/EXILED/Exiled.Events/Handlers/Scp939.cs +++ b/EXILED/Exiled.Events/Handlers/Scp939.cs @@ -74,6 +74,11 @@ public static class Scp939 /// public static Event ValidatingVisibility { get; set; } = new(); + /// + /// Invoked before SCP-939 places a mimic point. + /// + public static Event SettingMimicPoint { get; set; } = new(); + /// /// Called before SCP-939 changes its target focus. /// @@ -139,5 +144,11 @@ public static class Scp939 /// /// The instance. public static void OnValidatingVisibility(ValidatingVisibilityEventArgs ev) => ValidatingVisibility.InvokeSafely(ev); + + /// + /// Invoked before SCP-939 places a mimic point. + /// + /// The instance. + public static void OnSettingMimicPoint(SettingMimicPointEventArgs ev) => SettingMimicPoint.InvokeSafely(ev); } } \ No newline at end of file diff --git a/EXILED/Exiled.Events/Patches/Events/Scp939/SettingMimicPoint.cs b/EXILED/Exiled.Events/Patches/Events/Scp939/SettingMimicPoint.cs new file mode 100644 index 0000000000..f377f187a1 --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Scp939/SettingMimicPoint.cs @@ -0,0 +1,56 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) ExMod Team. All rights reserved. +// Licensed under the CC BY-SA 3.0 license. +// +// ----------------------------------------------------------------------- + +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + +namespace Exiled.Events.Patches.Events.Scp939 +{ + using Attributes; + using Exiled.Events.EventArgs.Scp939; + using HarmonyLib; + using Mirror; + using PlayerRoles.PlayableScps.Scp939.Mimicry; + using RelativePositioning; + + /// + /// Patches . + /// Adds the event. + /// + [EventPatch(typeof(Handlers.Scp939), nameof(Handlers.Scp939.SettingMimicPoint))] + [HarmonyPatch(typeof(MimicPointController), nameof(MimicPointController.ServerProcessCmd))] + internal static class SettingMimicPoint + { + private static bool Prefix(MimicPointController __instance, ref NetworkReader reader) + { + if (!__instance.Active) + { + SettingMimicPointEventArgs ev = new SettingMimicPointEventArgs(API.Features.Player.Get(__instance.Owner)); + Handlers.Scp939.OnSettingMimicPoint(ev); + + if (!ev.IsAllowed) + { + return false; + } + } + + if (__instance.Active) + { + __instance._syncMessage = MimicPointController.RpcStateMsg.RemovedByUser; + __instance.Active = false; + } + else + { + __instance._syncMessage = MimicPointController.RpcStateMsg.PlacedByUser; + __instance._syncPos = new RelativePosition(__instance.CastRole.FpcModule.Position); + __instance.Active = true; + } + + __instance.ServerSendRpc(true); + return true; + } + } +} \ No newline at end of file