Skip to content

Commit

Permalink
Added the SCP-079 Recontaining event (#21)
Browse files Browse the repository at this point in the history
* added the RecontainingEvent with the patch

* Fixed constructors

* consistency

* fixed logic skill issue

* Removed "useless" constructor

* corrected the typo

* fixed some typo

* final edit for the final request

* Apply suggestions from code review

* Apply suggestions from code review

Co-authored-by: VALERA771 <72030575+VALERA771@users.noreply.github.com>

---------

Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
Co-authored-by: VALERA771 <72030575+VALERA771@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 15, 2024
1 parent afdb0b2 commit 53ce718
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
42 changes: 42 additions & 0 deletions EXILED/Exiled.Events/EventArgs/Scp079/RecontainingEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// -----------------------------------------------------------------------
// <copyright file="RecontainingEventArgs.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.EventArgs.Scp079
{
using Exiled.API.Features;
using Exiled.Events.EventArgs.Interfaces;

/// <summary>
/// Contains information before SCP-079 gets recontained.
/// </summary>
public class RecontainingEventArgs : IDeniableEvent, IPlayerEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="RecontainingEventArgs" /> class.
/// </summary>
/// <param name="recontainer">The <see cref="BreakableWindow"/> instance.</param>
public RecontainingEventArgs(BreakableWindow recontainer)
{
Player = Player.Get(recontainer.LastAttacker.Hub);
IsAutomatic = recontainer.LastAttacker.IsSet;
}

/// <summary>
/// Gets the Player that started the recontainment process.<br></br>
/// Can be null if <see cref="IsAutomatic"/> is true.
/// </summary>
public Player Player { get; }

/// <inheritdoc/>
public bool IsAllowed { get; set; } = true;

/// <summary>
/// Gets a value indicating whether or not the recontained has been made automatically or by triggering the proccess.
/// </summary>
public bool IsAutomatic { get; }
}
}
11 changes: 11 additions & 0 deletions EXILED/Exiled.Events/Handlers/Scp079.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public static class Scp079
/// </summary>
public static Event<ChangingSpeakerStatusEventArgs> ChangingSpeakerStatus { get; set; } = new();

/// <summary>
/// Invoked before SCP-079 recontainment.
/// </summary>
public static Event<RecontainingEventArgs> Recontaining { get; set; } = new();

/// <summary>
/// Invoked after SCP-079 recontainment.
/// </summary>
Expand Down Expand Up @@ -125,6 +130,12 @@ public static class Scp079
/// <param name="ev">The <see cref="ChangingSpeakerStatusEventArgs" /> instance.</param>
public static void OnChangingSpeakerStatus(ChangingSpeakerStatusEventArgs ev) => ChangingSpeakerStatus.InvokeSafely(ev);

/// <summary>
/// Called before SCP-079 is recontained.
/// </summary>
/// <param name="ev">The <see cref="RecontainingEventArgs" /> instance.</param>
public static void OnRecontaining(RecontainingEventArgs ev) => Recontaining.InvokeSafely(ev);

/// <summary>
/// Called after SCP-079 is recontained.
/// </summary>
Expand Down
67 changes: 67 additions & 0 deletions EXILED/Exiled.Events/Patches/Events/Scp079/Recontaining.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// -----------------------------------------------------------------------
// <copyright file="Recontaining.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
// -----------------------------------------------------------------------

namespace Exiled.Events.Patches.Events.Scp079
{
using System.Collections.Generic;
using System.Reflection.Emit;

using Exiled.API.Features.Pools;
using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Scp079;
using Exiled.Events.Handlers;

using HarmonyLib;

using PlayerRoles.PlayableScps.Scp079;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="Scp079Recontainer.Recontain" />.
/// Adds the <see cref="Scp079.Recontaining" /> event.
/// </summary>
[EventPatch(typeof(Scp079), nameof(Scp079.Recontaining))]
[HarmonyPatch(typeof(Scp079Recontainer), nameof(Scp079Recontainer.Recontain))]
internal class Recontaining
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
int index = 0;
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

LocalBuilder ev = generator.DeclareLocal(typeof(RecontainingEventArgs));

Label returnLabel = generator.DefineLabel();

newInstructions.InsertRange(index, new CodeInstruction[]
{
// RecontainingEventArgs ev = new(this._activatorGlass)
new(OpCodes.Ldarg_0),
new(OpCodes.Ldfld, PropertyGetter(typeof(Scp079Recontainer), nameof(Scp079Recontainer._activatorGlass))),
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(RecontainingEventArgs))[0]),
new(OpCodes.Stloc_S, ev.LocalIndex),

// Scp079.OnRecontaining(ev)
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Call, Method(typeof(Scp079), nameof(Scp079.OnRecontaining))),

// if (!ev.IsAllowed) return;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, Method(typeof(RecontainingEventArgs), nameof(RecontainingEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),
});

newInstructions[newInstructions.Count - 1].WithLabels(returnLabel);

for (int z = 0; z < newInstructions.Count; z++)
yield return newInstructions[z];

ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}

0 comments on commit 53ce718

Please sign in to comment.