Skip to content

Commit

Permalink
Add voicelines SCP-3114 (#2269)
Browse files Browse the repository at this point in the history
* Add Door EVent

* Add to DropItem isThrown

* Door

* Add voicelines SCP-3114

* Update Player.cs

* Oops

* Oops v3

* Convert bool Prefix to Transpiler

* Update Exiled.Events/Handlers/Scp3114.cs

* Update Exiled.Events/Handlers/Scp3114.cs

---------

Co-authored-by: BoltonII <boltonii.mc@gmail.com>
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
Co-authored-by: Nao <60253860+NaoUnderscore@users.noreply.github.com>
  • Loading branch information
4 people authored Dec 5, 2023
1 parent 304d8da commit b0058ea
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Exiled.Events/EventArgs/Scp3114/VoiceLinesEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// -----------------------------------------------------------------------
// <copyright file="VoiceLinesEventArgs.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.Scp3114
{
using API.Features;
using Exiled.API.Features.Roles;
using Interfaces;

using static PlayerRoles.PlayableScps.Scp3114.Scp3114VoiceLines;

/// <summary>
/// Contains all information prior to sending voiceline SCP-3114.
/// </summary>
public class VoiceLinesEventArgs : IScp3114Event, IDeniableEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="VoiceLinesEventArgs" /> class.
/// </summary>
/// <param name="player">
/// <inheritdoc cref="Player" />
/// </param>
/// <param name="voiceLine">
/// <inheritdoc cref="VoiceLine" />
/// </param>
/// <param name="isAllowed">
/// <inheritdoc cref="IsAllowed" />
/// </param>
public VoiceLinesEventArgs(ReferenceHub player, VoiceLinesDefinition voiceLine, bool isAllowed = true)
{
Player = Player.Get(player);
Scp3114 = Player.Role.As<Scp3114Role>();
VoiceLine = voiceLine;
IsAllowed = isAllowed;
}

/// <inheritdoc/>
public Player Player { get; }

/// <inheritdoc/>
public Scp3114Role Scp3114 { get; }

/// <summary>
/// Gets or sets the <see cref="VoiceLinesDefinition" />.
/// </summary>
public VoiceLinesDefinition VoiceLine { get; set; }

/// <inheritdoc/>
public bool IsAllowed { get; set; }
}
}
11 changes: 11 additions & 0 deletions Exiled.Events/Handlers/Scp3114.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public static class Scp3114
/// </summary>
public static Event<RevealingEventArgs> Revealing { get; set; } = new();

/// <summary>
/// Invoked before sending any SCP-3114 voicelines.
/// </summary>
public static Event<VoiceLinesEventArgs> VoiceLines { get; set; } = new();

/// <summary>
/// Called before diguising to a new Roles.
/// </summary>
Expand Down Expand Up @@ -72,5 +77,11 @@ public static class Scp3114
/// </summary>
/// <param name="ev">The <see cref="RevealingEventArgs" /> instance.</param>
public static void OnRevealing(RevealingEventArgs ev) => Revealing.InvokeSafely(ev);

/// <summary>
/// Called before sending any SCP-3114 voicelines.
/// </summary>
/// <param name="ev">The <see cref="VoiceLinesEventArgs" /> instance.</param>
public static void OnVoiceLines(VoiceLinesEventArgs ev) => VoiceLines.InvokeSafely(ev);
}
}
83 changes: 83 additions & 0 deletions Exiled.Events/Patches/Events/Scp3114/VoiceLines.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// -----------------------------------------------------------------------
// <copyright file="VoiceLines.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.Scp3114
{
using System.Collections.Generic;
using System.Reflection.Emit;

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

using HarmonyLib;

using PlayerRoles.PlayableScps.Scp3114;

using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="Scp3114VoiceLines.ServerPlayConditionally" />.
/// Adds the <see cref="Handlers.Scp3114.VoiceLines" /> event.
/// </summary>
[EventPatch(typeof(Scp3114), nameof(Scp3114.VoiceLines))]
[HarmonyPatch(typeof(Scp3114VoiceLines), nameof(Scp3114VoiceLines.ServerPlayConditionally))]
internal class VoiceLines
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = ListPool<CodeInstruction>.Pool.Get(instructions);

Label returnLabel = generator.DefineLabel();

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

int offset = 1;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Blt_S) + offset;

newInstructions.InsertRange(index, new CodeInstruction[]
{
// this.Owner
new(OpCodes.Ldarg_0),
new(OpCodes.Callvirt, PropertyGetter(typeof(Scp3114VoiceLines), nameof(Scp3114VoiceLines.Owner))),

// voiceLinesDefinition
new(OpCodes.Ldloc_0),

// true
new(OpCodes.Ldc_I4_1),

// VoiceLinesEventArgs ev = new VoiceLinesEventArgs(ReferenceHub, VoiceLinesDefinition, bool);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(VoiceLinesEventArgs))[0]),
new(OpCodes.Dup),
new(OpCodes.Dup),
new(OpCodes.Stloc_S, ev.LocalIndex),

// Handlers.Scp3114.OnVoiceLines(ev);
new(OpCodes.Call, Method(typeof(Handlers.Scp3114), nameof(Handlers.Scp3114.OnVoiceLines))),

// if(!ev.IsAllowed)
// return;
new(OpCodes.Callvirt, PropertyGetter(typeof(VoiceLinesEventArgs), nameof(VoiceLinesEventArgs.IsAllowed))),
new(OpCodes.Brfalse_S, returnLabel),

// voiceLinesDefinition = ev.VoiceLine;
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(VoiceLinesEventArgs), nameof(VoiceLinesEventArgs.VoiceLine))),
new(OpCodes.Stloc_S, 0),
});

newInstructions[newInstructions.Count - 1].labels.Add(returnLabel);

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

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

0 comments on commit b0058ea

Please sign in to comment.