From 2e9f87fd99bdc8ae888d749fbd3c9449f5cb5e65 Mon Sep 17 00:00:00 2001 From: FoxWorn3365 Date: Thu, 1 Aug 2024 15:51:16 +0200 Subject: [PATCH] added the RecontainingEvent with the patch --- .../EventArgs/Scp079/RecontainingEventArgs.cs | 50 ++++++++++++++ EXILED/Exiled.Events/Handlers/Scp079.cs | 11 ++++ .../Patches/Events/Scp079/Recontaining.cs | 65 +++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 EXILED/Exiled.Events/EventArgs/Scp079/RecontainingEventArgs.cs create mode 100644 EXILED/Exiled.Events/Patches/Events/Scp079/Recontaining.cs diff --git a/EXILED/Exiled.Events/EventArgs/Scp079/RecontainingEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Scp079/RecontainingEventArgs.cs new file mode 100644 index 000000000..f15352343 --- /dev/null +++ b/EXILED/Exiled.Events/EventArgs/Scp079/RecontainingEventArgs.cs @@ -0,0 +1,50 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled 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 information before SCP-079 gets recontained. + /// + public class RecontainingEventArgs : IDeniableEvent + { + /// + /// Initializes a new instance of the class. + /// + /// The istance. + public RecontainingEventArgs(BreakableWindow recontainer) + { + Recontainer = Player.Get(recontainer.LastAttacker); + } + + /// + /// Initializes a new instance of the class. + /// + /// The player that triggered the SCP-079 recontaining event. + public RecontainingEventArgs(ReferenceHub recontainer) + { + Recontainer = Player.Get(recontainer); + } + + /// + /// Gets the Player that started the recontainment process.

+ /// Can be null if is true. + ///
+ public Player Recontainer { get; } + + /// + public bool IsAllowed { get; set; } = true; + + /// + /// Gets a value indicating whether or not the recontained has been made automatically or by triggering the proccess. + /// + public bool IsAutomatic => Recontainer is null; + } +} diff --git a/EXILED/Exiled.Events/Handlers/Scp079.cs b/EXILED/Exiled.Events/Handlers/Scp079.cs index 85da2da7e..b272defea 100644 --- a/EXILED/Exiled.Events/Handlers/Scp079.cs +++ b/EXILED/Exiled.Events/Handlers/Scp079.cs @@ -57,6 +57,11 @@ public static class Scp079 /// public static Event ChangingSpeakerStatus { get; set; } = new(); + /// + /// Invoked before SCP-079 recontainment. + /// + public static Event Recontaining { get; set; } = new(); + /// /// Invoked after SCP-079 recontainment. /// @@ -125,6 +130,12 @@ public static class Scp079 /// The instance. public static void OnChangingSpeakerStatus(ChangingSpeakerStatusEventArgs ev) => ChangingSpeakerStatus.InvokeSafely(ev); + /// + /// Called before SCP-079 is recontained. + /// + /// The instance. + public static void OnRecontaining(RecontainingEventArgs ev) => Recontaining.InvokeSafely(ev); + /// /// Called after SCP-079 is recontained. /// diff --git a/EXILED/Exiled.Events/Patches/Events/Scp079/Recontaining.cs b/EXILED/Exiled.Events/Patches/Events/Scp079/Recontaining.cs new file mode 100644 index 000000000..80ebfb6fc --- /dev/null +++ b/EXILED/Exiled.Events/Patches/Events/Scp079/Recontaining.cs @@ -0,0 +1,65 @@ +// ----------------------------------------------------------------------- +// +// Copyright (c) Exiled 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 Exiled.Events.Attributes; + using Exiled.Events.EventArgs.Scp079; + using Exiled.Events.Handlers; + + using HarmonyLib; + + using PlayerRoles.PlayableScps.Scp079; + + using static HarmonyLib.AccessTools; + + /// + /// Patches . + /// Adds the event. + /// + [EventPatch(typeof(Scp079), nameof(Scp079.Recontaining))] + [HarmonyPatch(typeof(Scp079Recontainer), nameof(Scp079Recontainer.Recontain))] + internal class Recontaining + { + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + int index = 0; + List newInstructions = new(instructions); + + LocalBuilder ev = generator.DeclareLocal(typeof(RecontainingEventArgs)); + + Label proceed = generator.DefineLabel(); + + newInstructions.InsertRange(index, new CodeInstruction[] + { + // RecontainingEventArgs ev = new(ReferenceHub "attacker") + new(OpCodes.Ldarg_0), + new(OpCodes.Ldfld, PropertyGetter(typeof(Scp079Recontainer), nameof(Scp079Recontainer._activatorGlass))), + new(OpCodes.Newobj, GetDeclaredConstructors(typeof(RecontainingEventArgs))[0]), + new(OpCodes.Starg_S, ev.LocalIndex), + + // Call event + new(OpCodes.Ldarg_S, ev.LocalIndex), + new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnRecontaining))), + + // if (!ev.IsAllowed) return; + new(OpCodes.Ldarg_S, ev.LocalIndex), + new(OpCodes.Callvirt, Method(typeof(RecontainingEventArgs), nameof(RecontainingEventArgs.IsAllowed))), + new(OpCodes.Brtrue_S, proceed), + + new(OpCodes.Ret), + + new CodeInstruction(OpCodes.Nop).WithLabels(proceed), + }); + + return newInstructions; + } + } +}