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