From d061805aeec8351db94008f8d07eed059f4a72db Mon Sep 17 00:00:00 2001
From: Nameless <85962933+Misfiy@users.noreply.github.com>
Date: Wed, 20 Mar 2024 12:14:12 +0100
Subject: [PATCH] [Exiled.Events & Exiled.API] Role Spawn Fix (#2474)
- Fix spawning in wrong location
- Add TryGetRoleBase by Yamato
---
Exiled.API/Extensions/RoleExtensions.cs | 14 +++++-
.../Patches/Events/Player/Spawning.cs | 47 +++++++++----------
2 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/Exiled.API/Extensions/RoleExtensions.cs b/Exiled.API/Extensions/RoleExtensions.cs
index 76be3ff7f6..fd160c9ee1 100644
--- a/Exiled.API/Extensions/RoleExtensions.cs
+++ b/Exiled.API/Extensions/RoleExtensions.cs
@@ -93,6 +93,16 @@ public static class RoleExtensions
/// The .
public static bool TryGetRoleBase(this RoleTypeId roleType, out PlayerRoleBase roleBase) => PlayerRoleLoader.TryGetRoleTemplate(roleType, out roleBase);
+ ///
+ /// Tries to get the base of the given .
+ ///
+ /// The .
+ /// The to return.
+ /// The type to cast the to.
+ /// The .
+ public static bool TryGetRoleBase(this RoleTypeId roleType, out T roleBase)
+ where T : PlayerRoleBase => PlayerRoleLoader.TryGetRoleTemplate(roleType, out roleBase);
+
///
/// Gets the .
///
@@ -120,11 +130,11 @@ public static class RoleExtensions
/// Returns a representing the spawn, or if no spawns were found.
public static SpawnLocation GetRandomSpawnLocation(this RoleTypeId roleType)
{
- if (roleType.GetRoleBase() is IFpcRole fpcRole &&
+ if (roleType.TryGetRoleBase(out FpcStandardRoleBase fpcRole) &&
fpcRole.SpawnpointHandler != null &&
fpcRole.SpawnpointHandler.TryGetSpawnpoint(out Vector3 position, out float horizontalRotation))
{
- return new SpawnLocation(roleType, position, horizontalRotation);
+ return new(roleType, position, horizontalRotation);
}
return null;
diff --git a/Exiled.Events/Patches/Events/Player/Spawning.cs b/Exiled.Events/Patches/Events/Player/Spawning.cs
index 11fe075535..4473ac91c7 100644
--- a/Exiled.Events/Patches/Events/Player/Spawning.cs
+++ b/Exiled.Events/Patches/Events/Player/Spawning.cs
@@ -10,14 +10,12 @@ namespace Exiled.Events.Patches.Events.Player
using System.Reflection;
using API.Features;
- using Exiled.Events.Attributes;
using Exiled.Events.EventArgs.Player;
using HarmonyLib;
using PlayerRoles;
using PlayerRoles.FirstPersonControl;
- using PlayerRoles.FirstPersonControl.NetworkMessages;
using PlayerRoles.FirstPersonControl.Spawnpoints;
using UnityEngine;
@@ -27,8 +25,8 @@ namespace Exiled.Events.Patches.Events.Player
///
/// Patches delegate.
/// Adds the event.
+ /// Fix for spawning in void.
///
- [EventPatch(typeof(Handlers.Player), nameof(Handlers.Player.Spawning))]
[HarmonyPatch]
internal static class Spawning
{
@@ -39,36 +37,33 @@ private static MethodInfo TargetMethod()
private static bool Prefix(ReferenceHub hub, PlayerRoleBase prevRole, PlayerRoleBase newRole)
{
- if (newRole.ServerSpawnReason != RoleChangeReason.Destroyed && Player.TryGet(hub, out Player player))
- {
- Vector3 oldPosition = hub.transform.position;
- float oldRotation = (prevRole as IFpcRole)?.FpcModule.MouseLook.CurrentVertical ?? 0;
-
- if (newRole is IFpcRole fpcRole)
- {
- if (newRole.ServerSpawnFlags.HasFlag(RoleSpawnFlags.UseSpawnpoint) && fpcRole.SpawnpointHandler != null && fpcRole.SpawnpointHandler.TryGetSpawnpoint(out Vector3 position, out float horizontalRot))
- {
- oldPosition = position;
- oldRotation = horizontalRot;
- }
+ if (newRole.ServerSpawnReason == RoleChangeReason.Destroyed || Player.TryGet(hub, out Player player))
+ return true;
- SpawningEventArgs ev = new(player, oldPosition, oldRotation, prevRole);
+ Vector3 oldPosition = hub.transform.position;
+ float oldRotation = (prevRole as IFpcRole)?.FpcModule.MouseLook.CurrentVertical ?? 0;
- Handlers.Player.OnSpawning(ev);
-
- hub.transform.position = ev.Position;
- fpcRole.FpcModule.MouseLook.CurrentHorizontal = ev.HorizontalRotation;
- hub.connectionToClient.Send(new FpcOverrideMessage(ev.Position, ev.HorizontalRotation), 0);
- }
- else
+ if (newRole is IFpcRole fpcRole)
+ {
+ if (newRole.ServerSpawnFlags.HasFlag(RoleSpawnFlags.UseSpawnpoint) && fpcRole.SpawnpointHandler != null && fpcRole.SpawnpointHandler.TryGetSpawnpoint(out Vector3 position, out float horizontalRot))
{
- Handlers.Player.OnSpawning(new(player, oldPosition, oldRotation, prevRole));
+ oldPosition = position;
+ oldRotation = horizontalRot;
}
- return false;
+ SpawningEventArgs ev = new(player, oldPosition, oldRotation, prevRole);
+
+ Handlers.Player.OnSpawning(ev);
+
+ player.Position = ev.Position;
+ fpcRole.FpcModule.MouseLook.CurrentHorizontal = ev.HorizontalRotation;
+ }
+ else
+ {
+ Handlers.Player.OnSpawning(new(player, oldPosition, oldRotation, prevRole));
}
- return true;
+ return false;
}
}
}
\ No newline at end of file