From 043d9a98ba58c30ee05a7e13210126b2b085502b Mon Sep 17 00:00:00 2001
From: VALERA771 <72030575+VALERA771@users.noreply.github.com>
Date: Sun, 10 Nov 2024 01:16:47 +0300
Subject: [PATCH] `[Exiled::Events]` `[Exiled::API]` New event + new property
(#31)
* new ev + previous role
* suggestions
* uwu
* suj
* fix
* uwu
---------
Co-authored-by: Yamato <66829532+louis1706@users.noreply.github.com>
---
EXILED/Exiled.API/Features/Player.cs | 11 ++-
.../EventArgs/Player/EscapedEventArgs.cs | 70 +++++++++++++++++++
EXILED/Exiled.Events/Handlers/Player.cs | 11 +++
.../{Escaping.cs => EscapingAndEscaped.cs} | 51 ++++++++++++--
4 files changed, 136 insertions(+), 7 deletions(-)
create mode 100644 EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs
rename EXILED/Exiled.Events/Patches/Events/Player/{Escaping.cs => EscapingAndEscaped.cs} (74%)
diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs
index d5e3d3eae..c6cd27514 100644
--- a/EXILED/Exiled.API/Features/Player.cs
+++ b/EXILED/Exiled.API/Features/Player.cs
@@ -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;
+ }
}
+ ///
+ /// Gets the role that player had before changing role.
+ ///
+ public RoleTypeId PreviousRole { get; private set; }
+
///
/// Gets or sets the player's SCP preferences.
///
diff --git a/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs
new file mode 100644
index 000000000..f185f7845
--- /dev/null
+++ b/EXILED/Exiled.Events/EventArgs/Player/EscapedEventArgs.cs
@@ -0,0 +1,70 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (c) Exiled Team. All rights reserved.
+// Licensed under the CC BY-SA 3.0 license.
+//
+// -----------------------------------------------------------------------
+
+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;
+
+ ///
+ /// Contains all information after player has escaped.
+ ///
+ public class EscapedEventArgs : IPlayerEvent
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ /// , .
+ public EscapedEventArgs(Player player, EscapeScenario escapeScenario, Role role, KeyValuePair kvp)
+ {
+ Player = player;
+ EscapeScenario = escapeScenario;
+ Team = kvp.Key;
+ Tickets = kvp.Value;
+ OldRole = role;
+ EscapeTime = (int)Math.Ceiling(role.ActiveTime.TotalSeconds);
+ }
+
+ ///
+ public Player Player { get; }
+
+ ///
+ /// Gets the type of escape.
+ ///
+ public EscapeScenario EscapeScenario { get; }
+
+ ///
+ /// Gets the that gained tickets for this escape.
+ ///
+ public SpawnableTeamType Team { get; }
+
+ ///
+ /// Gets the amount of tickets gained for this escape.
+ ///
+ public float Tickets { get; }
+
+ ///
+ /// Gets the previous role for this player.
+ ///
+ public Role OldRole { get; }
+
+ ///
+ /// Gets the time in seconds since round started.
+ ///
+ public int EscapeTime { get; }
+ }
+}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Handlers/Player.cs b/EXILED/Exiled.Events/Handlers/Player.cs
index 2e6209741..576cc3bb0 100644
--- a/EXILED/Exiled.Events/Handlers/Player.cs
+++ b/EXILED/Exiled.Events/Handlers/Player.cs
@@ -239,6 +239,11 @@ public class Player
///
public static Event Escaping { get; set; } = new();
+ ///
+ /// Invoked after a escapes.
+ ///
+ public static Event Escaped { get; set; } = new();
+
///
/// Invoked before a begins speaking to the intercom.
///
@@ -734,6 +739,12 @@ public class Player
/// The instance.
public static void OnEscaping(EscapingEventArgs ev) => Escaping.InvokeSafely(ev);
+ ///
+ /// Called after a escapes.
+ ///
+ /// The instance.
+ public static void OnEscaped(EscapedEventArgs ev) => Escaped.InvokeSafely(ev);
+
///
/// Called before a begins speaking to the intercom.
///
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs b/EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs
similarity index 74%
rename from EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs
rename to EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs
index 048de1136..a48e531d9 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Escaping.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/EscapingAndEscaped.cs
@@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
-//
+//
// Copyright (c) Exiled Team. All rights reserved.
// Licensed under the CC BY-SA 3.0 license.
//
@@ -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;
@@ -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;
@@ -28,11 +29,12 @@ namespace Exiled.Events.Patches.Events.Player
using static HarmonyLib.AccessTools;
///
- /// Patches for .
+ /// Patches for and .
///
[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 Transpiler(IEnumerable instructions, ILGenerator generator)
{
@@ -42,6 +44,7 @@ private static IEnumerable Transpiler(IEnumerable instruction.opcode == OpCodes.Newobj) + offset;
@@ -97,9 +100,44 @@ private static IEnumerable Transpiler(IEnumerable 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++)
@@ -120,6 +158,7 @@ private static void GrantAllTickets(EscapingEventArgs ev)
/// Replaces last returned to .
///
[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
{
@@ -151,4 +190,4 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions);
}
}
-}
+}
\ No newline at end of file