diff --git a/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs b/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs
index 73413e42c1..67311616d5 100644
--- a/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs
+++ b/EXILED/Exiled.Events/EventArgs/Player/SpawningEventArgs.cs
@@ -7,8 +7,6 @@
namespace Exiled.Events.EventArgs.Player
{
- using System;
-
using Exiled.API.Features;
using Exiled.API.Features.Roles;
using Exiled.Events.EventArgs.Interfaces;
@@ -22,6 +20,8 @@ namespace Exiled.Events.EventArgs.Player
///
public class SpawningEventArgs : IPlayerEvent
{
+ private Vector2 spawningRotation;
+
///
/// Initializes a new instance of the class.
///
@@ -32,7 +32,7 @@ public class SpawningEventArgs : IPlayerEvent
///
///
///
- ///
+ ///
///
///
/// the spawned player's new role.
@@ -41,7 +41,7 @@ public SpawningEventArgs(Player player, Vector3 position, float rotation, Player
{
Player = player;
Position = position;
- HorizontalRotation = rotation;
+ spawningRotation = new Vector2(0, rotation);
NewRole = Role.Create(newRole);
}
@@ -64,17 +64,24 @@ public SpawningEventArgs(Player player, Vector3 position, float rotation, Player
///
/// Rotation will apply only for .
///
- public float HorizontalRotation { get; set; }
+ public Vector2 SpawningRotation
+ {
+ get => spawningRotation;
+ set
+ {
+ spawningRotation = value;
+ IsRotationModified = true;
+ }
+ }
///
- /// Gets the player's old role.
+ /// Gets the player's new role.
///
- [Obsolete("Removed because the method is no longer provide OldRole since version 14.0. Use Player.Role instead")]
- public Role OldRole => Player.Role;
+ public Role NewRole { get; }
///
- /// Gets the player's new role.
+ /// Gets a value indicating whether the spawning rotation was modified.
///
- public Role NewRole { get; }
+ public bool IsRotationModified { get; private set; }
}
}
\ No newline at end of file
diff --git a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs
index c502d5984b..d37c44dde7 100644
--- a/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs
+++ b/EXILED/Exiled.Events/Patches/Events/Player/Spawning.cs
@@ -17,6 +17,9 @@ namespace Exiled.Events.Patches.Events.Player
using HarmonyLib;
+ using MEC;
+
+ using PlayerRoles.FirstPersonControl;
using PlayerRoles.FirstPersonControl.Spawnpoints;
using UnityEngine;
@@ -36,50 +39,43 @@ private static IEnumerable Transpiler(IEnumerable newInstructions = ListPool.Pool.Get(instructions);
- int offset = -1;
+ LocalBuilder ev = generator.DeclareLocal(typeof(SpawningEventArgs));
- // Locate the call to `Transform.position` setter to determine where to insert new instructions.
+ int offset = -1;
int index = newInstructions.FindIndex(instr => instr.Calls(PropertySetter(typeof(Transform), nameof(Transform.position)))) + offset;
- // Declare the `SpawningEventArgs` local variable.
- LocalBuilder ev = generator.DeclareLocal(typeof(SpawningEventArgs));
-
- newInstructions.InsertRange(
- index,
- new[]
+ newInstructions.InsertRange(index, new CodeInstruction[]
{
- // Load `ReferenceHub` (argument 0) and get `Player`.
- new CodeInstruction(OpCodes.Ldarg_0), // Load `hub` (first argument passed to the method).
- new CodeInstruction(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })), // Call Player.Get(hub) to get the Player instance.
+ // Player.Get(hub);
+ new(OpCodes.Ldarg_0),
+ new(OpCodes.Call, Method(typeof(Player), nameof(Player.Get), new[] { typeof(ReferenceHub) })),
- // Load `position` (local variable 2).
- new CodeInstruction(OpCodes.Ldloc_2),
+ // spawnLocation
+ new(OpCodes.Ldloc_2),
- // Load `rotation` (local variable 3).
- new CodeInstruction(OpCodes.Ldloc_3),
+ // horizontalRotation
+ new(OpCodes.Ldloc_3),
- // Load `newRole` (argument 1).
- new CodeInstruction(OpCodes.Ldarg_1), // Load `newRole` from argument 1.
+ // newRole
+ new(OpCodes.Ldarg_1),
- // Create a new instance of `SpawningEventArgs`.
- new CodeInstruction(OpCodes.Newobj, GetDeclaredConstructors(typeof(SpawningEventArgs))[0]),
+ // SpawningEventArg ev = new SpawningEventArgs(player, spawnLocation, horizontalRotation, newRole);
+ new(OpCodes.Newobj, GetDeclaredConstructors(typeof(SpawningEventArgs))[0]),
+ new(OpCodes.Dup),
+ new(OpCodes.Stloc, ev.LocalIndex),
- // Duplicate the object to store it and pass it around.
- new CodeInstruction(OpCodes.Dup), // Duplicate the `SpawningEventArgs` object.
- new CodeInstruction(OpCodes.Stloc, ev.LocalIndex), // Store the duplicated object in a local variable.
+ // Handlers.Player.OnSpawning(ev);
+ new(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnSpawning))),
- // Call `Handlers.Player.OnSpawning`.
- new CodeInstruction(OpCodes.Call, Method(typeof(Handlers.Player), nameof(Handlers.Player.OnSpawning))),
+ // spawnLocation = ev.Position;
+ new(OpCodes.Ldloc, ev.LocalIndex),
+ new(OpCodes.Call, PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.Position))),
+ new(OpCodes.Stloc_2),
- // Modify `position` from `ev.Position`.
- new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex), // Load the `SpawningEventArgs` object stored in the local variable.
- new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.Position))), // Get the `Position` property from `SpawningEventArgs`.
- new CodeInstruction(OpCodes.Stloc_2), // Store the position value back in the local variable 2 (`position`).
-
- // Modify `rotation` from `ev.HorizontalRotation`.
- new CodeInstruction(OpCodes.Ldloc, ev.LocalIndex), // Load the `SpawningEventArgs` object again.
- new CodeInstruction(OpCodes.Call, PropertyGetter(typeof(SpawningEventArgs), nameof(SpawningEventArgs.HorizontalRotation))), // Get the `HorizontalRotation` property from `SpawningEventArgs`.
- new CodeInstruction(OpCodes.Stloc_3), // Store the rotation value back in the local variable 3 (`rotation`).
+ // ApplyRotation(fpcRole, ev)
+ new(OpCodes.Ldloc_0),
+ new(OpCodes.Ldloc, ev.LocalIndex),
+ new(OpCodes.Call, Method(typeof(Spawning), nameof(ApplyRotation))),
});
for (int z = 0; z < newInstructions.Count; z++)
@@ -87,5 +83,24 @@ private static IEnumerable Transpiler(IEnumerable.Pool.Return(newInstructions);
}
+
+ private static void ApplyRotation(IFpcRole fpcRole, SpawningEventArgs ev)
+ {
+ if (!ev.IsRotationModified || fpcRole == null || fpcRole.FpcModule == null)
+ return;
+
+ Timing.RunCoroutine(WaitForMouseLookAndApply(fpcRole.FpcModule, ev.SpawningRotation), fpcRole.FpcModule.gameObject);
+ }
+
+ private static IEnumerator WaitForMouseLookAndApply(FirstPersonMovementModule fpcModule, Vector2 rotation)
+ {
+ yield return Timing.WaitUntilFalse(() => fpcModule != null && fpcModule.MouseLook == null);
+
+ if (fpcModule == null)
+ yield break;
+
+ yield return Timing.WaitForOneFrame;
+ fpcModule.ServerOverrideRotation(rotation);
+ }
}
}
\ No newline at end of file