From 4e603ce5c131f4f3727331298b8205c571d3baff Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 19 Apr 2025 20:49:27 +0100 Subject: [PATCH 1/4] feat: anti surface rework --- SillySCP/Handlers/AntiSurface.cs | 144 +++++++++++++++---------------- SillySCP/SillySCP.csproj | 2 +- 2 files changed, 71 insertions(+), 75 deletions(-) diff --git a/SillySCP/Handlers/AntiSurface.cs b/SillySCP/Handlers/AntiSurface.cs index fcdb730..c415643 100644 --- a/SillySCP/Handlers/AntiSurface.cs +++ b/SillySCP/Handlers/AntiSurface.cs @@ -1,8 +1,11 @@ using System.Collections; +using System.Reflection; using System.Text.RegularExpressions; using Exiled.API.Enums; using Exiled.API.Features; using Exiled.API.Features.Doors; +using Exiled.API.Features.Objectives; +using Exiled.API.Features.Waves; using Exiled.Events.EventArgs.Map; using Exiled.Events.EventArgs.Player; using Exiled.Events.EventArgs.Server; @@ -18,100 +21,93 @@ public class AntiSurface : IRegisterable { public void Init() { - Exiled.Events.Handlers.Map.ElevatorSequencesUpdated += OnElevatorSequencesUpdated; - Exiled.Events.Handlers.Server.RespawnedTeam += OnRespawned; - Exiled.Events.Handlers.Player.Died += OnPlayerDied; + Exiled.Events.Handlers.Server.RespawnedTeam += OnRespawnedTeam; + Exiled.Events.Handlers.Server.CompletingObjective += OnObjectiveComplete; } public void Unregister() { - Exiled.Events.Handlers.Map.ElevatorSequencesUpdated -= OnElevatorSequencesUpdated; - Exiled.Events.Handlers.Server.RespawnedTeam -= OnRespawned; - Exiled.Events.Handlers.Player.Died -= OnPlayerDied; + Exiled.Events.Handlers.Server.RespawnedTeam -= OnRespawnedTeam; + Exiled.Events.Handlers.Server.CompletingObjective += OnObjectiveComplete; } - private void OnPlayerDied(DiedEventArgs ev) + private void OnObjectiveComplete(CompletingObjectiveEventArgs ev) { - if (Exiled.API.Features.Player.List.Count(p => p.IsAlive && !p.IsScp) > 3) return; - TryStartCoroutine(); - } + float? timeReward = null; + + if (ev.Objective.GetType().IsGenericType && + ev.Objective.GetType().GetGenericTypeDefinition() == typeof(HumanObjective<>)) + { + PropertyInfo propertyInfo = ev.Objective.GetType().GetProperty("TimeReward"); + if (propertyInfo != null) + { + timeReward = (float)propertyInfo.GetValue(ev.Objective); + } + } - private void OnElevatorSequencesUpdated(ElevatorSequencesUpdatedEventArgs ev) - { - if (ev.Sequence != ElevatorChamber.ElevatorSequence.DoorOpening) return; - if (ev.Lift.Type is not ElevatorType.GateA and not ElevatorType.GateB) return; - if (ev.Lift.CurrentLevel != 1) return; - TryStartCoroutine(); - } + if (timeReward == null) return; - private void OnRespawned(RespawnedTeamEventArgs ev) - { - _handle = null; - - Door ezA = Door.Get(DoorType.GateA); - Door ezB = Door.Get(DoorType.GateB); - ezA.Unlock(); - ezB.Unlock(); - - TryStartCoroutine(); + _wave = GetWave(); } - - private CoroutineHandle? _handle; - private void TryStartCoroutine() + private void OnRespawnedTeam(RespawnedTeamEventArgs ev) { - if (_handle != null) return; + Timing.KillCoroutines(_handle); + _wave = GetWave(); _handle = Timing.RunCoroutine(SurfaceChecker()); } - private IEnumerator SurfaceChecker() + private static TimedWave GetWave() { - yield return Timing.WaitForSeconds(120); - - if (Exiled.API.Features.Player.List.Count(player => player.IsAlive && !player.IsScp) > 3) - yield break; + if (Respawn.NextKnownSpawnableFaction == SpawnableFaction.None) return null; + TimedWave wave = TimedWave.GetTimedWaves() + .FirstOrDefault(wave => wave.SpawnableFaction == Respawn.NextKnownSpawnableFaction && !wave.Timer.IsPaused); + return wave; + } - List surfacePlayers = Room.Get(RoomType.Surface).Players.ToList(); - - if (surfacePlayers.Count == 0 || - surfacePlayers.Count(p => p.IsScp) > 1 || - surfacePlayers.Select(p => p.Role.Team).Distinct().Count() > 1) - yield break; + private static TimedWave _wave; + private CoroutineHandle _handle; - Team team = surfacePlayers[0].Role.Team; - int playerCount = surfacePlayers.Count; - - Door gateA = Door.Get(DoorType.ElevatorGateA); - Door gateB = Door.Get(DoorType.ElevatorGateB); - Door ezA = Door.Get(DoorType.GateA); - Door ezB = Door.Get(DoorType.GateB); - - int closerToACount = surfacePlayers.Count(player => - Vector3.Distance(player.Position, gateA.Position) <= Vector3.Distance(player.Position, gateB.Position)); - - ezA.IsOpen = ezB.IsOpen = true; - ezA.Lock(DoorLockType.Warhead); - ezB.Lock(DoorLockType.Warhead); - - string message; - string translation; - - if (playerCount != closerToACount) - { - message = $"{playerCount} {Spaceify(team.ToString())} personnel located on surface"; - translation = $"{playerCount} {Spaceify(team.ToString())} personnel located on Surface"; - } - else + private static IEnumerator SurfaceChecker() + { + IEnumerable lastKnownPlayers = GetSurfacePlayers(); + DateTime firstCalled = DateTime.Now; + foreach (int seconds in Seconds) { - string nearGate = closerToACount > 0 ? "a" : "b"; - string nearGateTranslation = closerToACount > 0 ? "A" : "B"; - message = $"{playerCount} {Spaceify(team.ToString())} personnel located near gate {nearGate}"; - translation = $"{playerCount} {Spaceify(team.ToString())} personnel located near Gate {nearGateTranslation}"; + if(TotalSeconds(_wave) < seconds) continue; + yield return Timing.WaitUntilTrue(() => TotalSeconds(_wave) <= seconds); + IEnumerable currentPlayers = GetSurfacePlayers(); + if (Convert.ToInt32((DateTime.Now - firstCalled).TotalSeconds) < 29) + { + lastKnownPlayers = currentPlayers; + continue; + } + + foreach (Exiled.API.Features.Player currentPlayer in currentPlayers) + { + if(!lastKnownPlayers.Contains(currentPlayer)) continue; + currentPlayer.Kick("Holding up the round on surface."); + } + + lastKnownPlayers = currentPlayers; } - - Cassie.MessageTranslated(message, translation); - _handle = null; } - private string Spaceify(string input) => Regex.Replace(input, "([A-Z])", " $1").Trim(); + private static IEnumerable GetSurfacePlayers() + { + return Exiled.API.Features.Player.List.Where(player => player.Zone == ZoneType.Surface && player.IsHuman); + } + + private static int[] Seconds = new[] + { + 180, + 120, + 60, + 30 + }; + + private static int TotalSeconds(TimedWave wave) + { + return Convert.ToInt32(wave.Timer.TimeLeft.TotalSeconds); + } } \ No newline at end of file diff --git a/SillySCP/SillySCP.csproj b/SillySCP/SillySCP.csproj index 362eb74..54a8a99 100644 --- a/SillySCP/SillySCP.csproj +++ b/SillySCP/SillySCP.csproj @@ -18,7 +18,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 9b01adc0a4dd65821f102a232133e20f64f06f4b Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 19 Apr 2025 20:57:21 +0100 Subject: [PATCH 2/4] refactor: remove unused code --- SillySCP/Handlers/AntiSurface.cs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/SillySCP/Handlers/AntiSurface.cs b/SillySCP/Handlers/AntiSurface.cs index c415643..bdde263 100644 --- a/SillySCP/Handlers/AntiSurface.cs +++ b/SillySCP/Handlers/AntiSurface.cs @@ -33,20 +33,6 @@ public void Unregister() private void OnObjectiveComplete(CompletingObjectiveEventArgs ev) { - float? timeReward = null; - - if (ev.Objective.GetType().IsGenericType && - ev.Objective.GetType().GetGenericTypeDefinition() == typeof(HumanObjective<>)) - { - PropertyInfo propertyInfo = ev.Objective.GetType().GetProperty("TimeReward"); - if (propertyInfo != null) - { - timeReward = (float)propertyInfo.GetValue(ev.Objective); - } - } - - if (timeReward == null) return; - _wave = GetWave(); } @@ -72,7 +58,7 @@ private static IEnumerator SurfaceChecker() { IEnumerable lastKnownPlayers = GetSurfacePlayers(); DateTime firstCalled = DateTime.Now; - foreach (int seconds in Seconds) + foreach (int seconds in _seconds) { if(TotalSeconds(_wave) < seconds) continue; yield return Timing.WaitUntilTrue(() => TotalSeconds(_wave) <= seconds); @@ -98,7 +84,7 @@ private static IEnumerator SurfaceChecker() return Exiled.API.Features.Player.List.Where(player => player.Zone == ZoneType.Surface && player.IsHuman); } - private static int[] Seconds = new[] + private static int[] _seconds = new[] { 180, 120, From 29b15617d8363f799c9166e4ea495f2c5aa4f978 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 19 Apr 2025 21:04:54 +0100 Subject: [PATCH 3/4] refactor: use hash sets --- SillySCP/Handlers/AntiSurface.cs | 35 ++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/SillySCP/Handlers/AntiSurface.cs b/SillySCP/Handlers/AntiSurface.cs index bdde263..b64a185 100644 --- a/SillySCP/Handlers/AntiSurface.cs +++ b/SillySCP/Handlers/AntiSurface.cs @@ -56,26 +56,35 @@ private static TimedWave GetWave() private static IEnumerator SurfaceChecker() { - IEnumerable lastKnownPlayers = GetSurfacePlayers(); + HashSet lastKnownPlayers = new (GetSurfacePlayers()); DateTime firstCalled = DateTime.Now; - foreach (int seconds in _seconds) + bool isFirstRun = true; + + foreach (int seconds in Seconds) { - if(TotalSeconds(_wave) < seconds) continue; + if (TotalSeconds(_wave) < seconds) + continue; + yield return Timing.WaitUntilTrue(() => TotalSeconds(_wave) <= seconds); - IEnumerable currentPlayers = GetSurfacePlayers(); - if (Convert.ToInt32((DateTime.Now - firstCalled).TotalSeconds) < 29) + + if (isFirstRun && (DateTime.Now - firstCalled).TotalSeconds < 29) { - lastKnownPlayers = currentPlayers; + lastKnownPlayers = new (GetSurfacePlayers()); + isFirstRun = false; continue; } - - foreach (Exiled.API.Features.Player currentPlayer in currentPlayers) + + IEnumerable currentPlayers = GetSurfacePlayers(); + + foreach (Exiled.API.Features.Player player in currentPlayers) { - if(!lastKnownPlayers.Contains(currentPlayer)) continue; - currentPlayer.Kick("Holding up the round on surface."); + if (lastKnownPlayers.Contains(player)) + { + player.Kick("Holding up the round on surface."); + } } - - lastKnownPlayers = currentPlayers; + + lastKnownPlayers = new (currentPlayers); } } @@ -84,7 +93,7 @@ private static IEnumerator SurfaceChecker() return Exiled.API.Features.Player.List.Where(player => player.Zone == ZoneType.Surface && player.IsHuman); } - private static int[] _seconds = new[] + private static readonly int[] Seconds = new[] { 180, 120, From 00b3c90205cedca9f684cf0640be82b985710e05 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 19 Apr 2025 21:14:25 +0100 Subject: [PATCH 4/4] chore: remove unused imports --- SillySCP/Handlers/AntiSurface.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/SillySCP/Handlers/AntiSurface.cs b/SillySCP/Handlers/AntiSurface.cs index b64a185..6b9165f 100644 --- a/SillySCP/Handlers/AntiSurface.cs +++ b/SillySCP/Handlers/AntiSurface.cs @@ -1,19 +1,9 @@ -using System.Collections; -using System.Reflection; -using System.Text.RegularExpressions; -using Exiled.API.Enums; +using Exiled.API.Enums; using Exiled.API.Features; -using Exiled.API.Features.Doors; -using Exiled.API.Features.Objectives; using Exiled.API.Features.Waves; -using Exiled.Events.EventArgs.Map; -using Exiled.Events.EventArgs.Player; using Exiled.Events.EventArgs.Server; -using Interactables.Interobjects; using MEC; -using PlayerRoles; using SillySCP.API.Interfaces; -using UnityEngine; namespace SillySCP.Handlers;