From 90857d00b376cb29bab8503e00301b8ec3b1b8c7 Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+obvEve@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:34:55 +0100 Subject: [PATCH 1/3] TryGetTeleportLocation --- SecretAPI/Extensions/RoomExtensions.cs | 48 +++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/SecretAPI/Extensions/RoomExtensions.cs b/SecretAPI/Extensions/RoomExtensions.cs index 41629af..b2946a3 100644 --- a/SecretAPI/Extensions/RoomExtensions.cs +++ b/SecretAPI/Extensions/RoomExtensions.cs @@ -1,8 +1,11 @@ namespace SecretAPI.Extensions { using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using LabApi.Features.Wrappers; using MapGeneration; + using PlayerRoles.FirstPersonControl; + using PlayerRoles.PlayableScps.Scp106; using UnityEngine; /// @@ -10,6 +13,8 @@ /// public static class RoomExtensions { + private const float DefaultLocateRadius = 10; + private static readonly List KnownUnsafeRooms = [ RoomName.HczTesla, // Instant death @@ -35,7 +40,48 @@ public static bool IsSafeToTeleport(this Room room) if (KnownUnsafeRooms.Contains(room.Name)) return false; - return Physics.Raycast(room.Position, Vector3.down, out _, 2); + return Physics.Raycast(room.Position, Vector3.down, out _, 2, FpcStateProcessor.Mask); + } + + /// + /// Tries to get a location to teleport a to. + /// + /// The player to attempt to get a teleport position from. + /// The position found if any, otherwise null. + /// If set to anything other than will only attempt to find in that zone. + /// The default radius allowed nea the found spot. + /// Whether a valid teleport position was correctly found. + public static bool TryGetTeleportLocation(this Player player, [NotNullWhen(true)] out Vector3? position, FacilityZone zone = FacilityZone.None, float defaultRadius = DefaultLocateRadius) + { + position = null; + return player.RoleBase is IFpcRole fpc && TryGetTeleportLocation(fpc, out position, zone); + } + + /// + /// Tries to get a location to teleport a to. + /// + /// The to attempt to get a teleport position from. + /// The position found if any, otherwise null. + /// If set to anything other than will only attempt to find in that zone. + /// The default radius allowed nea the found spot. + /// Whether a valid teleport position was correctly found. + public static bool TryGetTeleportLocation(this IFpcRole fpc, [NotNullWhen(true)] out Vector3? position, FacilityZone zone = FacilityZone.None, float defaultRadius = Scp106PocketExitFinder.RaycastRange) + { + position = null; + + IEnumerable poses = zone == FacilityZone.None + ? SafeLocationFinder.GetLocations(null, null) + : Scp106PocketExitFinder.GetPosesForZone(zone); + + if (!poses.TryGetRandomValue(out Pose pose)) + return false; + + float radius = defaultRadius; + if (Room.TryGetRoomAtPosition(pose.position, out Room? room)) + radius = Scp106PocketExitFinder.GetRaycastRange(room.Zone); + + position = SafeLocationFinder.GetSafePosition(pose.position, pose.forward, radius, fpc.FpcModule.CharController); + return true; } } } \ No newline at end of file From 1248aa07a8e16fa10b0e7035eacad86e70baff9b Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+obvEve@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:46:44 +0100 Subject: [PATCH 2/3] RoomSafetyFailReason --- SecretAPI/Enums/RoomSafetyFailReason.cs | 39 +++++++++++++++++++++++++ SecretAPI/Extensions/RoomExtensions.cs | 20 +++++++++---- 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 SecretAPI/Enums/RoomSafetyFailReason.cs diff --git a/SecretAPI/Enums/RoomSafetyFailReason.cs b/SecretAPI/Enums/RoomSafetyFailReason.cs new file mode 100644 index 0000000..b7df960 --- /dev/null +++ b/SecretAPI/Enums/RoomSafetyFailReason.cs @@ -0,0 +1,39 @@ +namespace SecretAPI.Enums +{ + using System; + using MapGeneration; + using SecretAPI.Extensions; + using UnityEngine; + + /// + /// Reasons why should fail. + /// + [Flags] + public enum RoomSafetyFailReason + { + /// + /// No fail. + /// + None = 0, + + /// + /// Room safety check will fail if warhead has gone off and room is not part of . + /// + Warhead = 1, + + /// + /// Room safety check will fail if decontamination has gone off and room is part of . + /// + Decontamination = 2, + + /// + /// Room safety check will fail if room has . + /// + Tesla = 4, + + /// + /// Room safety check will fail if the listed room fails a check. + /// + MissingFloor = 8, + } +} \ No newline at end of file diff --git a/SecretAPI/Extensions/RoomExtensions.cs b/SecretAPI/Extensions/RoomExtensions.cs index b2946a3..7fadb3d 100644 --- a/SecretAPI/Extensions/RoomExtensions.cs +++ b/SecretAPI/Extensions/RoomExtensions.cs @@ -6,6 +6,7 @@ using MapGeneration; using PlayerRoles.FirstPersonControl; using PlayerRoles.PlayableScps.Scp106; + using SecretAPI.Enums; using UnityEngine; /// @@ -13,7 +14,7 @@ /// public static class RoomExtensions { - private const float DefaultLocateRadius = 10; + private const float RaycastDistance = 2; private static readonly List KnownUnsafeRooms = [ @@ -28,19 +29,26 @@ public static class RoomExtensions /// Gets whether a room is safe to teleport to. Will consider decontamination, warhead, teslas and void rooms. /// /// The room to check. + /// Reasons why the safety check should fail. /// Whether the room is safe to teleport to. - public static bool IsSafeToTeleport(this Room room) + public static bool IsSafeToTeleport(this Room room, RoomSafetyFailReason failReasons) { - if (Warhead.IsDetonated && room.Zone != FacilityZone.Surface) + if (failReasons.HasFlag(RoomSafetyFailReason.Warhead) && Warhead.IsDetonated && room.Zone != FacilityZone.Surface) return false; - if (Decontamination.IsDecontaminating && room.Zone == FacilityZone.LightContainment) + if (failReasons.HasFlag(RoomSafetyFailReason.Decontamination) && Decontamination.IsDecontaminating && room.Zone == FacilityZone.LightContainment) + return false; + + if (failReasons.HasFlag(RoomSafetyFailReason.Tesla) && room.Name == RoomName.HczTesla) return false; if (KnownUnsafeRooms.Contains(room.Name)) return false; - return Physics.Raycast(room.Position, Vector3.down, out _, 2, FpcStateProcessor.Mask); + if (failReasons.HasFlag(RoomSafetyFailReason.MissingFloor) && !Physics.Raycast(room.Position, Vector3.down, out _, RaycastDistance, FpcStateProcessor.Mask)) + return false; + + return true; } /// @@ -51,7 +59,7 @@ public static bool IsSafeToTeleport(this Room room) /// If set to anything other than will only attempt to find in that zone. /// The default radius allowed nea the found spot. /// Whether a valid teleport position was correctly found. - public static bool TryGetTeleportLocation(this Player player, [NotNullWhen(true)] out Vector3? position, FacilityZone zone = FacilityZone.None, float defaultRadius = DefaultLocateRadius) + public static bool TryGetTeleportLocation(this Player player, [NotNullWhen(true)] out Vector3? position, FacilityZone zone = FacilityZone.None, float defaultRadius = Scp106PocketExitFinder.RaycastRange) { position = null; return player.RoleBase is IFpcRole fpc && TryGetTeleportLocation(fpc, out position, zone); From 569056dfe90d52d148d528f777b185eaaa20adbc Mon Sep 17 00:00:00 2001 From: Misfiy <85962933+obvEve@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:50:07 +0100 Subject: [PATCH 3/3] RoomSafetyFailReason.KnownBad + public KnownUnsafeRooms --- SecretAPI/Enums/RoomSafetyFailReason.cs | 5 +++++ SecretAPI/Extensions/RoomExtensions.cs | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/SecretAPI/Enums/RoomSafetyFailReason.cs b/SecretAPI/Enums/RoomSafetyFailReason.cs index b7df960..a5cc293 100644 --- a/SecretAPI/Enums/RoomSafetyFailReason.cs +++ b/SecretAPI/Enums/RoomSafetyFailReason.cs @@ -35,5 +35,10 @@ public enum RoomSafetyFailReason /// Room safety check will fail if the listed room fails a check. /// MissingFloor = 8, + + /// + /// Room safety check will fail if the listed room is part of . + /// + KnownBad = 16, } } \ No newline at end of file diff --git a/SecretAPI/Extensions/RoomExtensions.cs b/SecretAPI/Extensions/RoomExtensions.cs index 7fadb3d..ab87169 100644 --- a/SecretAPI/Extensions/RoomExtensions.cs +++ b/SecretAPI/Extensions/RoomExtensions.cs @@ -16,9 +16,11 @@ public static class RoomExtensions { private const float RaycastDistance = 2; - private static readonly List KnownUnsafeRooms = + /// + /// Gets a list of that will be denied by . + /// + public static List KnownUnsafeRooms { get; } = [ - RoomName.HczTesla, // Instant death RoomName.EzEvacShelter, // Stuck permanently RoomName.EzCollapsedTunnel, // Stuck permanently RoomName.HczWaysideIncinerator, // Death