Skip to content

Commit 9bcdeee

Browse files
committed
Add PlacedAmnesticCloud event
1 parent 1f2d209 commit 9bcdeee

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="PlacedAmnesticCloudEventArgs.cs" company="Exiled Team">
3+
// Copyright (c) Exiled Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.Events.EventArgs.Scp939
9+
{
10+
using API.Features;
11+
using API.Features.Hazards;
12+
using Interfaces;
13+
using PlayerRoles.PlayableScps.Scp939;
14+
15+
using Scp939Role = API.Features.Roles.Scp939Role;
16+
17+
/// <summary>
18+
/// Contains all information after SCP-939 used its amnestic cloud ability.
19+
/// </summary>
20+
public class PlacedAmnesticCloudEventArgs : IScp939Event
21+
{
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="PlacedAmnesticCloudEventArgs" /> class.
24+
/// </summary>
25+
/// <param name="hub">
26+
/// <inheritdoc cref="ReferenceHub" />
27+
/// </param>
28+
/// <param name="cloud">
29+
/// <inheritdoc cref="PlayerRoles.PlayableScps.Scp939.Scp939AmnesticCloudInstance" />
30+
/// </param>
31+
public PlacedAmnesticCloudEventArgs(ReferenceHub hub, Scp939AmnesticCloudInstance cloud)
32+
{
33+
Player = Player.Get(hub);
34+
AmnesticCloud = new AmnesticCloudHazard(cloud);
35+
Scp939 = Player.Role.As<Scp939Role>();
36+
}
37+
38+
/// <summary>
39+
/// Gets the player who's controlling SCP-939.
40+
/// </summary>
41+
public Player Player { get; }
42+
43+
/// <summary>
44+
/// Gets the <see cref="AmnesticCloudHazard"/> instance.
45+
/// </summary>
46+
public AmnesticCloudHazard AmnesticCloud { get; }
47+
48+
/// <inheritdoc/>
49+
public Scp939Role Scp939 { get; }
50+
}
51+
}

EXILED/Exiled.Events/Handlers/Scp939.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public static class Scp939
3232
/// </summary>
3333
public static Event<PlacingAmnesticCloudEventArgs> PlacingAmnesticCloud { get; set; } = new();
3434

35+
/// <summary>
36+
/// Invoked after SCP-939 used its amnestic cloud ability.
37+
/// </summary>
38+
public static Event<PlacedAmnesticCloudEventArgs> PlacedAmnesticCloud { get; set; } = new();
39+
3540
/// <summary>
3641
/// Invoked before SCP-939 plays a stolen voice.
3742
/// </summary>
@@ -81,6 +86,12 @@ public static class Scp939
8186
/// <param name="ev">The <see cref="PlacingAmnesticCloudEventArgs" /> instance.</param>
8287
public static void OnPlacingAmnesticCloud(PlacingAmnesticCloudEventArgs ev) => PlacingAmnesticCloud.InvokeSafely(ev);
8388

89+
/// <summary>
90+
/// Called after SCP-939 used its amnestic cloud ability.
91+
/// </summary>
92+
/// <param name="ev">The <see cref="PlacedAmnesticCloudEventArgs" /> instance.</param>
93+
public static void OnPlacedAmnesticCloud(PlacedAmnesticCloudEventArgs ev) => PlacedAmnesticCloud.InvokeSafely(ev);
94+
8495
/// <summary>
8596
/// Called before SCP-939 plays a stolen voice.
8697
/// </summary>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// -----------------------------------------------------------------------
2+
// <copyright file="PlacedAmnesticCloud.cs" company="Exiled Team">
3+
// Copyright (c) Exiled Team. All rights reserved.
4+
// Licensed under the CC BY-SA 3.0 license.
5+
// </copyright>
6+
// -----------------------------------------------------------------------
7+
8+
namespace Exiled.Events.Patches.Events.Scp939
9+
{
10+
using System.Collections.Generic;
11+
using System.Reflection.Emit;
12+
13+
using Exiled.API.Features.Pools;
14+
using Exiled.Events.Attributes;
15+
using Exiled.Events.EventArgs.Scp939;
16+
using Exiled.Events.Handlers;
17+
using HarmonyLib;
18+
using PlayerRoles.PlayableScps.Scp939;
19+
20+
using static HarmonyLib.AccessTools;
21+
22+
/// <summary>
23+
/// Patches <see cref="Scp939AmnesticCloudAbility.OnStateEnabled" />
24+
/// to add the <see cref="Scp939.PlacedAmnesticCloud" /> event.
25+
/// </summary>
26+
[EventPatch(typeof(Scp939), nameof(Scp939.PlacedAmnesticCloud))]
27+
[HarmonyPatch(typeof(Scp939AmnesticCloudAbility), nameof(Scp939AmnesticCloudAbility.OnStateEnabled))]
28+
internal static class PlacedAmnesticCloud
29+
{
30+
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
31+
{
32+
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);
33+
34+
LocalBuilder cloud = generator.DeclareLocal(typeof(Scp939AmnesticCloudInstance));
35+
36+
const int offset = -2;
37+
int index = newInstructions.FindIndex(x => x.opcode == OpCodes.Callvirt && x.OperandIs(Method(typeof(Scp939AmnesticCloudInstance), nameof(Scp939AmnesticCloudInstance.ServerSetup)))) + offset;
38+
39+
newInstructions.InsertRange(
40+
index,
41+
new[]
42+
{
43+
// Scp939AmnesticCloudInstance cloud = Object.Instantiate<Scp939AmnesticCloudInstance>(this._instancePrefab)
44+
new CodeInstruction(OpCodes.Dup),
45+
new CodeInstruction(OpCodes.Stloc_S, cloud),
46+
});
47+
48+
index = newInstructions.FindLastIndex(x => x.opcode == OpCodes.Ret);
49+
50+
// Scp939.OnPlacedAmnesticCloud(new PlacedAmnesticCloudEventArgs(this.Owner, cloud));
51+
newInstructions.InsertRange(
52+
index,
53+
new[]
54+
{
55+
// this.Owner
56+
new CodeInstruction(OpCodes.Ldarg_0),
57+
new(OpCodes.Callvirt, PropertyGetter(typeof(Scp939AmnesticCloudAbility), nameof(Scp939AmnesticCloudAbility.Owner))),
58+
59+
// cloud
60+
new CodeInstruction(OpCodes.Ldloc_S, cloud),
61+
62+
// Scp939.OnPlacedAmnesticCloud(new PlacedAmnesticCloudEventArgs(this.Owner, cloud));
63+
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(PlacedAmnesticCloudEventArgs))[0]),
64+
new(OpCodes.Call, Method(typeof(Scp939), nameof(Scp939.OnPlacedAmnesticCloud))),
65+
});
66+
67+
for (int z = 0; z < newInstructions.Count; z++)
68+
yield return newInstructions[z];
69+
70+
ListPool<CodeInstruction>.Pool.Return(newInstructions);
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)