forked from Exiled-Official/EXILED
-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EXILED::Events] BeingObserved event stolen (#91)
* Scp173 Observing, Stolen from https://github.com/ExMod-Team/EXILED/pull/72/files * Remove old comment
- Loading branch information
1 parent
043d9a9
commit cc7c183
Showing
3 changed files
with
158 additions
and
1 deletion.
There are no files selected for viewing
57 changes: 57 additions & 0 deletions
57
EXILED/Exiled.Events/EventArgs/Scp173/BeingObservedEventArgs.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="BeingObservedEventArgs.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.Scp173 | ||
{ | ||
using Exiled.API.Features; | ||
using Exiled.API.Features.Roles; | ||
using Exiled.Events.EventArgs.Interfaces; | ||
|
||
/// <summary> | ||
/// Contains all the information before SCP-173 is observed. | ||
/// </summary> | ||
public class BeingObservedEventArgs : IScp173Event, IDeniableEvent | ||
{ | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="BeingObservedEventArgs" /> class. | ||
/// </summary> | ||
/// <param name="target"> | ||
/// The <see cref="Exiled.API.Features.Player"/> instance of the target. | ||
/// </param> | ||
/// <param name="scp173"> | ||
/// The <see cref="Exiled.API.Features.Player"/> instance of the SCP-173. | ||
/// </param> | ||
/// <param name="isAllowed"> | ||
/// Whether or not the target will be counted as observing the SCP-173. | ||
/// </param> | ||
public BeingObservedEventArgs(API.Features.Player target, API.Features.Player scp173, bool isAllowed = true) | ||
{ | ||
Target = target; | ||
Player = scp173; | ||
Scp173 = scp173.Role.As<Scp173Role>(); | ||
IsAllowed = isAllowed; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the player who's observing the SCP-173. | ||
/// </summary> | ||
public Player Target { get; } | ||
|
||
/// <summary> | ||
/// Gets the player who's being observed. | ||
/// </summary> | ||
public Player Player { get; } | ||
|
||
/// <inheritdoc/> | ||
public Scp173Role Scp173 { get; } | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether or not the player can be counted as observing. | ||
/// </summary> | ||
public bool IsAllowed { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
89 changes: 89 additions & 0 deletions
89
EXILED/Exiled.Events/Patches/Events/Scp173/BeingObserved.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// ----------------------------------------------------------------------- | ||
// <copyright file="BeingObserved.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.Scp173 | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Reflection.Emit; | ||
|
||
using Exiled.API.Features.Pools; | ||
using Exiled.Events.Attributes; | ||
using Exiled.Events.EventArgs.Scp173; | ||
using HarmonyLib; | ||
using PlayerRoles.PlayableScps.Scp173; | ||
using PlayerRoles.Subroutines; | ||
using PluginAPI.Events; | ||
|
||
using static HarmonyLib.AccessTools; | ||
|
||
/// <summary> | ||
/// Patches <see cref="Scp173ObserversTracker.IsObservedBy" />. | ||
/// Adds the <see cref="Handlers.Scp173.BeingObserved" /> event. | ||
/// </summary> | ||
[EventPatch(typeof(Handlers.Scp173), nameof(Handlers.Scp173.BeingObserved))] | ||
[HarmonyPatch(typeof(Scp173ObserversTracker), nameof(Scp173ObserversTracker.IsObservedBy), typeof(ReferenceHub), typeof(float))] | ||
internal static class BeingObserved | ||
{ | ||
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) | ||
{ | ||
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions); | ||
|
||
Label continueLabel = generator.DefineLabel(); | ||
|
||
const int offset = -4; | ||
var scp173ExecuteEvent = typeof(EventManager) | ||
.GetMethods(BindingFlags.Public | BindingFlags.Static) | ||
.FirstOrDefault(m => m.Name == nameof(EventManager.ExecuteEvent) | ||
&& !m.IsGenericMethod); | ||
int index = newInstructions.FindLastIndex(i => i.Calls(scp173ExecuteEvent)) + offset; | ||
|
||
newInstructions.InsertRange( | ||
index, | ||
new CodeInstruction[] | ||
{ | ||
// Player.Get(target) | ||
new(OpCodes.Ldarg_1), | ||
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), | ||
|
||
// Player.Get(base.Owner) | ||
new(OpCodes.Ldarg_0), | ||
new(OpCodes.Call, PropertyGetter(typeof(StandardSubroutine<Scp173Role>), nameof(StandardSubroutine<Scp173Role>.Owner))), | ||
new(OpCodes.Call, Method(typeof(API.Features.Player), nameof(API.Features.Player.Get), new[] { typeof(ReferenceHub) })), | ||
|
||
// true | ||
new(OpCodes.Ldc_I4_1), | ||
|
||
// BeingObservedEventArgs ev = new(Player, Player, bool) | ||
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(BeingObservedEventArgs))[0]), | ||
new(OpCodes.Dup), | ||
|
||
// Handlers.Scp173.OnBeingObserved(ev) | ||
new(OpCodes.Call, Method(typeof(Handlers.Scp173), nameof(Handlers.Scp173.OnBeingObserved))), | ||
|
||
// if (ev.IsAllowed) | ||
// goto continueLabel | ||
new(OpCodes.Callvirt, PropertyGetter(typeof(BeingObservedEventArgs), nameof(BeingObservedEventArgs.IsAllowed))), | ||
new(OpCodes.Brtrue, continueLabel), | ||
|
||
// return false | ||
new(OpCodes.Ldc_I4_0), | ||
new(OpCodes.Ret), | ||
|
||
// continueLabel: | ||
new CodeInstruction(OpCodes.Nop).WithLabels(continueLabel), | ||
}); | ||
|
||
for (int z = 0; z < newInstructions.Count; z++) | ||
yield return newInstructions[z]; | ||
|
||
ListPool<CodeInstruction>.Pool.Return(newInstructions); | ||
} | ||
} | ||
} |