Skip to content

Commit

Permalink
[Exiled::Events] [Exiled::API] New event + new property (#31)
Browse files Browse the repository at this point in the history
* new ev + previous role

* suggestions

* uwu

* suj

* fix

* uwu

---------

Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
  • Loading branch information
VALERA771 and louis1706 authored Nov 9, 2024
1 parent 534e847 commit 043d9a9
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 7 deletions.
11 changes: 10 additions & 1 deletion EXILED/Exiled.API/Features/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -589,9 +589,18 @@ public PlayerPermissions RemoteAdminPermissions
public Role Role
{
get => role ??= Role.Create(RoleManager.CurrentRole);
internal set => role = value;
internal set
{
PreviousRole = role.Type;
role = value;
}
}

/// <summary>
/// Gets the role that player had before changing role.
/// </summary>
public RoleTypeId PreviousRole { get; private set; }

/// <summary>
/// Gets or sets the player's SCP preferences.
/// </summary>
Expand Down
70 changes: 70 additions & 0 deletions EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// -----------------------------------------------------------------------
// <copyright file="EscapedEventArgs.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.Player
{
using System;
using System.Collections.Generic;

using Exiled.API.Enums;
using Exiled.API.Features;
using Exiled.API.Features.Roles;
using Exiled.Events.EventArgs.Interfaces;
using PlayerRoles;
using Respawning;

/// <summary>
/// Contains all information after player has escaped.
/// </summary>
public class EscapedEventArgs : IPlayerEvent
{
/// <summary>
/// Initializes a new instance of the <see cref="EscapedEventArgs"/> class.
/// </summary>
/// <param name="player"><inheritdoc cref="Player"/></param>
/// <param name="escapeScenario"><inheritdoc cref="EscapeScenario"/></param>
/// <param name="role"><inheritdoc cref="Role"/></param>
/// <param name="kvp"><inheritdoc cref="Tickets"/>, <inheritdoc cref="Team"/>.</param>
public EscapedEventArgs(Player player, EscapeScenario escapeScenario, Role role, KeyValuePair<SpawnableTeamType, float> kvp)
{
Player = player;
EscapeScenario = escapeScenario;
Team = kvp.Key;
Tickets = kvp.Value;
OldRole = role;
EscapeTime = (int)Math.Ceiling(role.ActiveTime.TotalSeconds);
}

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

/// <summary>
/// Gets the type of escape.
/// </summary>
public EscapeScenario EscapeScenario { get; }

/// <summary>
/// Gets the <see cref="SpawnableTeamType"/> that gained tickets for this escape.
/// </summary>
public SpawnableTeamType Team { get; }

/// <summary>
/// Gets the amount of tickets gained for this escape.
/// </summary>
public float Tickets { get; }

/// <summary>
/// Gets the previous role for this player.
/// </summary>
public Role OldRole { get; }

/// <summary>
/// Gets the time in seconds since round started.
/// </summary>
public int EscapeTime { get; }
}
}
11 changes: 11 additions & 0 deletions EXILED/Exiled.Events/Handlers/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ public class Player
/// </summary>
public static Event<EscapingEventArgs> Escaping { get; set; } = new();

/// <summary>
/// Invoked after a <see cref="API.Features.Player"/> escapes.
/// </summary>
public static Event<EscapedEventArgs> Escaped { get; set; } = new();

/// <summary>
/// Invoked before a <see cref="API.Features.Player"/> begins speaking to the intercom.
/// </summary>
Expand Down Expand Up @@ -734,6 +739,12 @@ public class Player
/// <param name="ev">The <see cref="EscapingEventArgs"/> instance.</param>
public static void OnEscaping(EscapingEventArgs ev) => Escaping.InvokeSafely(ev);

/// <summary>
/// Called after a <see cref="API.Features.Player"/> escapes.
/// </summary>
/// <param name="ev">The <see cref="EscapedEventArgs"/> instance.</param>
public static void OnEscaped(EscapedEventArgs ev) => Escaped.InvokeSafely(ev);

/// <summary>
/// Called before a <see cref="API.Features.Player"/> begins speaking to the intercom.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="Escaping.cs" company="Exiled Team">
// <copyright file="EscapingAndEscaped.cs" company="Exiled Team">
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
// </copyright>
Expand All @@ -8,6 +8,7 @@
namespace Exiled.Events.Patches.Events.Player
{
#pragma warning disable SA1402 // File may only contain a single type
#pragma warning disable IDE0060

using System;
using System.Collections.Generic;
Expand All @@ -18,8 +19,8 @@ namespace Exiled.Events.Patches.Events.Player
using API.Enums;
using API.Features;
using API.Features.Pools;

using EventArgs.Player;
using Exiled.API.Features.Roles;
using Exiled.Events.Attributes;
using HarmonyLib;
using PlayerRoles.FirstPersonControl;
Expand All @@ -28,11 +29,12 @@ namespace Exiled.Events.Patches.Events.Player
using static HarmonyLib.AccessTools;

/// <summary>
/// Patches <see cref="Escape.ServerHandlePlayer(ReferenceHub)"/> for <see cref="Handlers.Player.Escaping" />.
/// Patches <see cref="Escape.ServerHandlePlayer(ReferenceHub)"/> for <see cref="Handlers.Player.Escaping" /> and <see cref="Handlers.Player.Escaped"/>.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaping))]
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaped))]
[HarmonyPatch(typeof(Escape), nameof(Escape.ServerHandlePlayer))]
internal static class Escaping
internal static class EscapingAndEscaped
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
Expand All @@ -42,6 +44,7 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
Label returnLabel = generator.DefineLabel();

LocalBuilder ev = generator.DeclareLocal(typeof(EscapingEventArgs));
LocalBuilder role = generator.DeclareLocal(typeof(Role));

int offset = -2;
int index = newInstructions.FindIndex(instruction => instruction.opcode == OpCodes.Newobj) + offset;
Expand Down Expand Up @@ -97,9 +100,44 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
{
// GrantAllTickets(ev)
new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex).WithLabels(labels),
new(OpCodes.Call, Method(typeof(Escaping), nameof(GrantAllTickets))),
new(OpCodes.Call, Method(typeof(EscapingAndEscaped), nameof(GrantAllTickets))),
});

offset = 4;
index = newInstructions.FindIndex(x => x.Is(OpCodes.Stfld, Field(typeof(Escape.EscapeMessage), nameof(Escape.EscapeMessage.EscapeTime)))) + offset;

newInstructions.InsertRange(index, new CodeInstruction[]
{
// role = ev.Player.Role
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.Player))),
new(OpCodes.Callvirt, PropertyGetter(typeof(Player), nameof(Player.Role))),
new(OpCodes.Stloc_S, role.LocalIndex),
});

newInstructions.InsertRange(newInstructions.Count - 1, new CodeInstruction[]
{
// ev.Player
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.Player))),

// escapeScenario
new(OpCodes.Ldloc_1),

// role
new(OpCodes.Ldloc_S, role.LocalIndex),

// ev.RespawnTickets.Key
new(OpCodes.Ldloc_S, ev.LocalIndex),
new(OpCodes.Callvirt, PropertyGetter(typeof(EscapingEventArgs), nameof(EscapingEventArgs.RespawnTickets))),

// EscapedEventArgs ev2 = new(ev.Player, ev.EscapeScenario, role, float, SpawnableTeamType);
new(OpCodes.Newobj, GetDeclaredConstructors(typeof(EscapedEventArgs))[0]),

// Handlers.Player.OnEscaped(ev);
new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnEscaped))),
});

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

for (int z = 0; z < newInstructions.Count; z++)
Expand All @@ -120,6 +158,7 @@ private static void GrantAllTickets(EscapingEventArgs ev)
/// Replaces last returned <see cref="EscapeScenario.None"/> to <see cref="EscapeScenario.CustomEscape"/>.
/// </summary>
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaping))]
[EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Escaped))]
[HarmonyPatch(typeof(Escape), nameof(Escape.ServerGetScenario))]
internal static class GetScenario
{
Expand Down Expand Up @@ -151,4 +190,4 @@ private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstructi
ListPool<CodeInstruction>.Pool.Return(newInstructions);
}
}
}
}

0 comments on commit 043d9a9

Please sign in to comment.