diff --git a/SecretAPI/Enums/RoomSafetyFailReason.cs b/SecretAPI/Enums/RoomSafetyFailReason.cs
new file mode 100644
index 0000000..6aac865
--- /dev/null
+++ b/SecretAPI/Enums/RoomSafetyFailReason.cs
@@ -0,0 +1,32 @@
+namespace SecretAPI.Enums
+{
+ using System;
+ using MapGeneration;
+
+ ///
+ /// Reasons why room safety should fail.
+ ///
+ [Flags]
+ public enum RoomSafetyFailReason
+ {
+ ///
+ /// No fail.
+ ///
+ None = 0,
+
+ ///
+ /// Room safety check will fail if warhead has gone off and this is not part of .
+ ///
+ Warhead = 1,
+
+ ///
+ /// Room safety check will fail if decontamination has gone off and this is part of .
+ ///
+ Decontamination = 2,
+
+ ///
+ /// Room safety check will fail if the listed room is .
+ ///
+ Tesla = 4,
+ }
+}
\ No newline at end of file
diff --git a/SecretAPI/Extensions/RoomExtensions.cs b/SecretAPI/Extensions/RoomExtensions.cs
index 41629af..2bbe85a 100644
--- a/SecretAPI/Extensions/RoomExtensions.cs
+++ b/SecretAPI/Extensions/RoomExtensions.cs
@@ -3,16 +3,19 @@
using System.Collections.Generic;
using LabApi.Features.Wrappers;
using MapGeneration;
+ using PlayerRoles.FirstPersonControl;
+ using PlayerRoles.PlayableScps.Scp106;
+ using SecretAPI.Enums;
using UnityEngine;
///
/// Extensions related to rooms.
///
+ /// TODO: Make TryGetSafeTeleport(Room)
public static class RoomExtensions
{
private static readonly List KnownUnsafeRooms =
[
- RoomName.HczTesla, // Instant death
RoomName.EzEvacShelter, // Stuck permanently
RoomName.EzCollapsedTunnel, // Stuck permanently
RoomName.HczWaysideIncinerator, // Death
@@ -23,13 +26,17 @@ 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 .
/// 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))
@@ -37,5 +44,34 @@ public static bool IsSafeToTeleport(this Room room)
return Physics.Raycast(room.Position, Vector3.down, out _, 2);
}
+
+ ///
+ /// Gets a safe teleport point for a .
+ ///
+ /// The player to get teleport point for.
+ /// The zone to attempt to teleport to player to.
+ /// The range of which the position is allowed to vary from its "point".
+ /// The teleport point which was found.
+ /// Whether a valid position was found.
+ public static bool GetSafeTeleportPoint(this Player player, FacilityZone zone, float range, out Vector3 teleportPoint)
+ {
+ if (player.RoleBase is not IFpcRole fpcRole)
+ {
+ teleportPoint = Vector3.zero;
+ return false;
+ }
+
+ Pose[] poses = Scp106PocketExitFinder.GetPosesForZone(zone);
+ if (poses.IsEmpty())
+ {
+ teleportPoint = Vector3.zero;
+ return false;
+ }
+
+ Pose pose = Scp106PocketExitFinder.GetRandomPose(poses);
+ Vector3 position = SafeLocationFinder.GetSafePosition(pose.position, pose.rotation.eulerAngles, range, fpcRole.FpcModule.CharController);
+ teleportPoint = position;
+ return true;
+ }
}
}
\ No newline at end of file