From 3333a5ef4fa4d14257ac49be583347a54a51baf1 Mon Sep 17 00:00:00 2001
From: Yamato <66829532+louis1706@users.noreply.github.com>
Date: Mon, 20 Jan 2025 00:24:12 +0100
Subject: [PATCH] feat: PR 133 / Added Scp079 Signal Event (#400)
Squashed PR 133:
---
.../EventArgs/Scp079/LosingSignalEventArgs.cs | 44 ++++++++++
.../EventArgs/Scp079/LostSignalEventArgs.cs | 38 ++++++++
.../Scp079/StartingSpeakerEventArgs.cs | 66 --------------
.../Scp079/StoppingSpeakerEventArgs.cs | 57 ------------
EXILED/Exiled.Events/Handlers/Scp079.cs | 22 +++++
.../Patches/Events/Scp079/Lost.cs | 86 +++++++++++++++++++
6 files changed, 190 insertions(+), 123 deletions(-)
create mode 100644 EXILED/Exiled.Events/EventArgs/Scp079/LosingSignalEventArgs.cs
create mode 100644 EXILED/Exiled.Events/EventArgs/Scp079/LostSignalEventArgs.cs
create mode 100644 EXILED/Exiled.Events/Patches/Events/Scp079/Lost.cs
diff --git a/EXILED/Exiled.Events/EventArgs/Scp079/LosingSignalEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp079/LosingSignalEventArgs.cs
new file mode 100644
index 000000000..cae1c775e
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Scp079/LosingSignalEventArgs.cs
@@ -0,0 +1,44 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Scp079
+{
+ using Exiled.API.Features;
+ using Exiled.Events.EventArgs.Interfaces;
+
+ ///
+ /// Contains all information before SCP-079 loses a signal by SCP-2176.
+ ///
+ public class LosingSignalEventArgs : IScp079Event, IDeniableEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ public LosingSignalEventArgs(ReferenceHub player)
+ {
+ Player = Player.Get(player);
+ Scp079 = Player.Role.As();
+ IsAllowed = true;
+ }
+
+ ///
+ /// Gets the player who's controlling SCP-079.
+ ///
+ public Player Player { get; }
+
+ ///
+ /// Gets or sets a value indicating whether or not SCP-079 will lose his signal.
+ ///
+ public bool IsAllowed { get; set; }
+
+ ///
+ public API.Features.Roles.Scp079Role Scp079 { get; }
+ }
+}
diff --git a/EXILED/Exiled.Events/EventArgs/Scp079/LostSignalEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp079/LostSignalEventArgs.cs
new file mode 100644
index 000000000..247eb5c20
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Scp079/LostSignalEventArgs.cs
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.EventArgs.Scp079
+{
+ using Exiled.API.Features;
+ using Exiled.Events.EventArgs.Interfaces;
+
+ ///
+ /// Contains all information before SCP-079 loses a signal by SCP-2176.
+ ///
+ public class LostSignalEventArgs : IScp079Event
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ public LostSignalEventArgs(ReferenceHub player)
+ {
+ Player = Player.Get(player);
+ Scp079 = Player.Role.As();
+ }
+
+ ///
+ /// Gets the player who's controlling SCP-079.
+ ///
+ public Player Player { get; }
+
+ ///
+ public API.Features.Roles.Scp079Role Scp079 { get; }
+ }
+}
diff --git a/EXILED/Exiled.Events/EventArgs/Scp079/StartingSpeakerEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp079/StartingSpeakerEventArgs.cs
index fe160a28a..e69de29bb 100644
--- a/EXILED/Exiled.Events/EventArgs/Scp079/StartingSpeakerEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Scp079/StartingSpeakerEventArgs.cs
@@ -1,66 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) ExMod Team. All rights reserved.
-// Licensed under the CC BY-SA 3.0 license.
-//
-// -----------------------------------------------------------------------
-
-namespace Exiled.Events.EventArgs.Scp079
-{
- using Exiled.API.Features;
- using Exiled.API.Features.Roles;
- using Exiled.Events.EventArgs.Interfaces;
-
- ///
- /// Contains all information before SCP-079 uses a speaker.
- ///
- public class StartingSpeakerEventArgs : IScp079Event, IDeniableEvent
- {
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public StartingSpeakerEventArgs(Player player, Room room, float auxiliaryPowerCost, bool isAllowed = true)
- {
- Player = player;
- Scp079 = player.Role.As();
- Room = room;
- AuxiliaryPowerCost = auxiliaryPowerCost;
- IsAllowed = isAllowed;
- }
-
- ///
- /// Gets the player who's controlling SCP-079.
- ///
- public Player Player { get; }
-
- ///
- public Scp079Role Scp079 { get; }
-
- ///
- /// Gets the room that the speaker is located in.
- ///
- public Room Room { get; }
-
- ///
- /// Gets or sets the amount of auxiliary power required to use a speaker through SCP-079.
- ///
- public float AuxiliaryPowerCost { get; set; }
-
- ///
- /// Gets or sets a value indicating whether SCP-079 can use the speaker.
- ///
- public bool IsAllowed { get; set; }
- }
-}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/EventArgs/Scp079/StoppingSpeakerEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp079/StoppingSpeakerEventArgs.cs
index 9191c4cc0..e69de29bb 100644
--- a/EXILED/Exiled.Events/EventArgs/Scp079/StoppingSpeakerEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Scp079/StoppingSpeakerEventArgs.cs
@@ -1,57 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright (c) ExMod Team. All rights reserved.
-// Licensed under the CC BY-SA 3.0 license.
-//
-// -----------------------------------------------------------------------
-
-namespace Exiled.Events.EventArgs.Scp079
-{
- using Exiled.API.Features;
- using Exiled.API.Features.Roles;
- using Exiled.Events.EventArgs.Interfaces;
-
- ///
- /// Contains all information before SCP-079 finishes using a speaker.
- ///
- public class StoppingSpeakerEventArgs : IScp079Event, IDeniableEvent
- {
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public StoppingSpeakerEventArgs(Player player, Room room, bool isAllowed = true)
- {
- Player = player;
- Scp079 = player.Role.As();
- Room = room;
- IsAllowed = isAllowed;
- }
-
- ///
- /// Gets the player who's controlling SCP-079.
- ///
- public Player Player { get; }
-
- ///
- public Scp079Role Scp079 { get; }
-
- ///
- /// Gets the room that the speaker is located in.
- ///
- public Room Room { get; }
-
- ///
- /// Gets or sets a value indicating whether SCP-079 can stop using the speaker.
- ///
- public bool IsAllowed { get; set; }
- }
-}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Handlers/Scp079.cs b/EXILED/Exiled.Events/Handlers/Scp079.cs
index dab2d32c9..a43016314 100644
--- a/EXILED/Exiled.Events/Handlers/Scp079.cs
+++ b/EXILED/Exiled.Events/Handlers/Scp079.cs
@@ -82,6 +82,16 @@ public static class Scp079
///
public static Event ZoneBlackout { get; set; } = new();
+ ///
+ /// Invoked before SCP-079 loses a signal by SCP-2176.
+ ///
+ public static Event LosingSignal { get; set; } = new();
+
+ ///
+ /// Invoked after SCP-079 loses a signal by SCP-2176.
+ ///
+ public static Event LostSignal { get; set; } = new();
+
///
/// Called before SCP-079 switches cameras.
///
@@ -159,5 +169,17 @@ public static class Scp079
///
/// The instance.
public static void OnZoneBlackout(ZoneBlackoutEventArgs ev) => ZoneBlackout.InvokeSafely(ev);
+
+ ///
+ /// Called before SCP-079 loses a signal by SCP-2176.
+ ///
+ /// The instance.
+ public static void OnLosingSignal(LosingSignalEventArgs ev) => LosingSignal.InvokeSafely(ev);
+
+ ///
+ /// Called after SCP-079 loses a signal by SCP-2176.
+ ///
+ /// The instance.
+ public static void OnLostSignal(LostSignalEventArgs ev) => LostSignal.InvokeSafely(ev);
}
}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Patches/Events/Scp079/Lost.cs b/EXILED/Exiled.Events/Patches/Events/Scp079/Lost.cs
new file mode 100644
index 000000000..4583f447f
--- /dev/null
+++ b/EXILED/Exiled.Events/Patches/Events/Scp079/Lost.cs
@@ -0,0 +1,86 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) ExMod Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+namespace Exiled.Events.Patches.Events.Scp079
+{
+ using System.Collections.Generic;
+ using System.Reflection.Emit;
+
+ using API.Features.Pools;
+ using Exiled.Events.Attributes;
+ using Exiled.Events.EventArgs.Scp079;
+ using Exiled.Events.Handlers;
+
+ using HarmonyLib;
+
+ using PlayerRoles;
+ using PlayerRoles.PlayableScps.Scp079;
+
+ using static HarmonyLib.AccessTools;
+
+ ///
+ /// Patches .
+ /// Adds the and event.
+ ///
+ [EventPatch(typeof(Scp079), nameof(Scp079.LosingSignal))]
+ [EventPatch(typeof(Scp079), nameof(Scp079.LostSignal))]
+ [HarmonyPatch(typeof(Scp079LostSignalHandler), nameof(Scp079LostSignalHandler.ServerLoseSignal))]
+ internal static class Lost
+ {
+ private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator)
+ {
+ List newInstructions = ListPool.Pool.Get(instructions);
+
+ Label ret = generator.DefineLabel();
+
+ newInstructions.InsertRange(
+ 0,
+ new[]
+ {
+ // Role._lastOwner
+ new CodeInstruction(OpCodes.Ldarg_0),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079LostSignalHandler), nameof(Scp079LostSignalHandler.Role))),
+ new(OpCodes.Ldfld, Field(typeof(PlayerRoleBase), nameof(PlayerRoleBase._lastOwner))),
+
+ // LosingSignalEventArgs ev = new(Role._lastOwner)
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(LosingSignalEventArgs))[0]),
+ new(OpCodes.Dup),
+
+ // Scp079.OnLosingSignal(ev)
+ new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnLosingSignal))),
+
+ // if (!ev.IsAllowed)
+ // return;
+ new(OpCodes.Callvirt, PropertyGetter(typeof(LosingSignalEventArgs), nameof(LosingSignalEventArgs.IsAllowed))),
+ new(OpCodes.Brfalse_S, ret),
+ });
+
+ newInstructions.InsertRange(
+ newInstructions.Count - 1,
+ new[]
+ {
+ // Role._lastOwner
+ new CodeInstruction(OpCodes.Ldarg_0),
+ new(OpCodes.Callvirt, PropertyGetter(typeof(Scp079LostSignalHandler), nameof(Scp079LostSignalHandler.Role))),
+ new(OpCodes.Ldfld, Field(typeof(PlayerRoleBase), nameof(PlayerRoleBase._lastOwner))),
+
+ // LostSignalEventArgs ev = new(Role._lastOwner)
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(LostSignalEventArgs))[0]),
+
+ // Scp079.OnLosingSignal(ev)
+ new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnLostSignal))),
+ });
+
+ newInstructions[newInstructions.Count - 1].labels.Add(ret);
+
+ for (int z = 0; z < newInstructions.Count; z++)
+ yield return newInstructions[z];
+
+ ListPool.Pool.Return(newInstructions);
+ }
+ }
+}
\ No newline at end of file