diff --git a/EXILED/Exiled.API/Enums/SpawnableFaction.cs b/EXILED/Exiled.API/Enums/SpawnableFaction.cs
index 131a7a4ff4..0903253fca 100644
--- a/EXILED/Exiled.API/Enums/SpawnableFaction.cs
+++ b/EXILED/Exiled.API/Enums/SpawnableFaction.cs
@@ -12,6 +12,11 @@ namespace Exiled.API.Enums
///
public enum SpawnableFaction
{
+ ///
+ /// Represents no wave.
+ ///
+ None,
+
///
/// Normal NTF wave.
///
diff --git a/EXILED/Exiled.API/Extensions/RoleExtensions.cs b/EXILED/Exiled.API/Extensions/RoleExtensions.cs
index 407e26565c..445edb88c4 100644
--- a/EXILED/Exiled.API/Extensions/RoleExtensions.cs
+++ b/EXILED/Exiled.API/Extensions/RoleExtensions.cs
@@ -12,12 +12,13 @@ namespace Exiled.API.Extensions
using System.Linq;
using Enums;
- using Exiled.API.Features.Spawn;
+ using Features.Spawn;
using Footprinting;
using InventorySystem;
using InventorySystem.Configs;
using PlayerRoles;
using PlayerRoles.FirstPersonControl;
+ using Respawning;
using Respawning.Waves;
using UnityEngine;
@@ -233,12 +234,62 @@ public static Dictionary GetStartingAmmo(this RoleTypeId roleT
///
/// A instance.
/// associated with the wave.
- public static SpawnableFaction GetFaction(this SpawnableWaveBase waveBase) => waveBase switch
+ public static SpawnableFaction GetSpawnableFaction(this SpawnableWaveBase waveBase) => waveBase switch
{
NtfSpawnWave => SpawnableFaction.NtfWave,
NtfMiniWave => SpawnableFaction.NtfMiniWave,
ChaosSpawnWave => SpawnableFaction.ChaosWave,
- _ => SpawnableFaction.ChaosMiniWave
+ ChaosMiniWave => SpawnableFaction.ChaosMiniWave,
+ _ => SpawnableFaction.None
};
+
+ ///
+ /// Gets the associated with the provided .
+ ///
+ /// A member of the enum.
+ /// associated with the provided .
+ public static Faction GetFaction(this SpawnableFaction spawnableFaction) => spawnableFaction switch
+ {
+ SpawnableFaction.ChaosWave or SpawnableFaction.ChaosMiniWave => Faction.FoundationEnemy,
+ SpawnableFaction.NtfWave or SpawnableFaction.NtfMiniWave => Faction.FoundationStaff,
+ _ => Faction.Unclassified,
+ };
+
+ ///
+ /// Gets the associated with the provided .
+ ///
+ /// A member of the enum.
+ /// associated with the provided .
+ public static Faction GetFaction(this SpawnableTeamType spawnableTeamType) => spawnableTeamType switch
+ {
+ SpawnableTeamType.ChaosInsurgency => Faction.FoundationEnemy,
+ SpawnableTeamType.NineTailedFox => Faction.FoundationStaff,
+ _ => Faction.Unclassified,
+ };
+
+ ///
+ /// Tries to get the associated with the provided and .
+ ///
+ /// A member of the enum.
+ /// The to return.
+ /// A determining whether to get a normal spawn wave or a mini one.
+ /// associated with the provided influenced by .
+ public static bool TryGetSpawnableFaction(this Faction faction, out SpawnableFaction spawnableFaction, bool mini = false)
+ {
+ switch (faction)
+ {
+ case Faction.FoundationStaff:
+ spawnableFaction = mini ? SpawnableFaction.NtfMiniWave : SpawnableFaction.NtfWave;
+ break;
+ case Faction.FoundationEnemy:
+ spawnableFaction = mini ? SpawnableFaction.ChaosMiniWave : SpawnableFaction.ChaosWave;
+ break;
+ default:
+ spawnableFaction = SpawnableFaction.None;
+ return false;
+ }
+
+ return true;
+ }
}
}
diff --git a/EXILED/Exiled.API/Features/Respawn.cs b/EXILED/Exiled.API/Features/Respawn.cs
index fbbfd9ce5b..a7590dfd2d 100644
--- a/EXILED/Exiled.API/Features/Respawn.cs
+++ b/EXILED/Exiled.API/Features/Respawn.cs
@@ -9,9 +9,11 @@ namespace Exiled.API.Features
{
using System;
using System.Collections.Generic;
+ using System.Linq;
using CustomPlayerEffects;
using Enums;
+ using Extensions;
using PlayerRoles;
using Respawning;
using Respawning.Waves;
@@ -26,6 +28,16 @@ public static class Respawn
private static GameObject ntfHelicopterGameObject;
private static GameObject chaosCarGameObject;
+ ///
+ /// Gets the of paused 's.
+ ///
+ public static List PausedWaves { get; } = new();
+
+ ///
+ /// Gets the containing faction influence.
+ ///
+ public static Dictionary FactionInfluence => FactionInfluenceManager.Influence;
+
///
/// Gets the NTF Helicopter's .
///
@@ -55,18 +67,16 @@ public static GameObject ChaosVan
}
///
- /// Gets or sets the next known that will spawn.
+ /// Gets the next known that will spawn.
///
- public static Faction NextKnownFaction
- {
- get => WaveManager._nextWave.TargetFaction;
- set => WaveManager._nextWave = WaveManager.Waves.Find(x => x.TargetFaction == value);
- }
+ /// This returns SpawnableFaction.None unless a respawn has already started.
+ public static SpawnableFaction NextKnownSpawnableFaction => WaveManager._nextWave is not null ? WaveManager._nextWave.GetSpawnableFaction() : SpawnableFaction.None;
///
/// Gets the next known that will spawn.
///
- public static SpawnableTeamType NextKnownTeam => NextKnownFaction.GetSpawnableTeam();
+ /// This returns SpawnableFaction.None unless a respawn has already started.
+ public static SpawnableTeamType NextKnownTeam => NextKnownSpawnableFaction.GetFaction().GetSpawnableTeam();
///
/// Gets the current state of the .
@@ -74,7 +84,7 @@ public static Faction NextKnownFaction
public static WaveManager.WaveQueueState CurrentState => WaveManager.State;
///
- /// Gets a value indicating whether a team is currently being spawned or the animations are playing for a team.
+ /// Gets a value indicating whether the respawn process for a is currently in progress..
///
public static bool IsSpawning => WaveManager.State == WaveManager.WaveQueueState.WaveSpawning;
@@ -106,177 +116,335 @@ public static bool ProtectedCanShoot
}
///
- /// Gets a of that have spawn protection.
+ /// Gets a of s that have spawn protection.
///
public static List ProtectedTeams => SpawnProtected.ProtectedTeams;
///
/// Tries to get a .
///
- /// Found .
+ /// The found .
/// Type of .
- /// true if was successfully found. Otherwise, false.
- public static bool TryGetWaveBase(out T spawnWave)
- where T : SpawnableWaveBase => WaveManager.TryGet(out spawnWave);
+ /// true if was successfully found. Otherwise, false.
+ ///
+ public static bool TryGetWaveBase(out T spawnableWaveBase)
+ where T : SpawnableWaveBase => WaveManager.TryGet(out spawnableWaveBase);
///
- /// Tries to get a from a .
+ /// Tries to get a .
///
- /// Team's .
- /// Found .
- /// true if was successfully found. Otherwise, false.
- public static bool TryGetWaveBase(Faction faction, out SpawnableWaveBase spawnWave)
- => WaveManager.TryGet(faction, out spawnWave);
+ /// A determining which wave to search for.
+ /// The found .
+ /// true if was successfully found. Otherwise, false.
+ ///
+ public static bool TryGetWaveBase(SpawnableFaction spawnableFaction, out SpawnableWaveBase spawnableWaveBase)
+ {
+ spawnableWaveBase = WaveManager.Waves.Find(x => x.GetSpawnableFaction() == spawnableFaction);
+ return spawnableWaveBase is not null;
+ }
///
- /// Tries to get a from a .
+ /// Tries to get an of .
///
- /// Team's .
- /// Found .
- /// true if was successfully found. Otherwise, false.
- public static bool TryGetWaveBase(SpawnableFaction faction, out SpawnableWaveBase spawnWave)
+ /// A determining which waves to search for.
+ /// The containing found 's if there are any, otherwise null.
+ /// true if was successfully found. Otherwise, false.
+ ///
+ public static bool TryGetWaveBases(Faction faction, out IEnumerable spawnableWaveBases)
{
- switch (faction)
+ List spawnableWaves = new();
+ spawnableWaves.AddRange(WaveManager.Waves.Where(x => x.TargetFaction == faction));
+
+ if (spawnableWaves.IsEmpty())
{
- case SpawnableFaction.NtfWave:
- bool result = TryGetWaveBase(out NtfSpawnWave ntfSpawnWave);
- spawnWave = ntfSpawnWave;
- return result;
- case SpawnableFaction.NtfMiniWave:
- result = TryGetWaveBase(out NtfMiniWave ntfMiniWave);
- spawnWave = ntfMiniWave;
- return result;
- case SpawnableFaction.ChaosWave:
- result = TryGetWaveBase(out ChaosSpawnWave chaosSpawnWave);
- spawnWave = chaosSpawnWave;
- return result;
- case SpawnableFaction.ChaosMiniWave:
- result = TryGetWaveBase(out ChaosMiniWave chaosMiniWave);
- spawnWave = chaosMiniWave;
- return result;
+ spawnableWaveBases = null;
+ return false;
}
- spawnWave = null;
- return false;
+ spawnableWaveBases = spawnableWaves;
+ return true;
}
///
- /// Docs.
+ /// Tries to get an of .
+ ///
+ /// A determining which waves to search for.
+ /// The containing found 's if there are any, otherwise null.
+ /// true if was successfully found. Otherwise, false.
+ ///
+ public static bool TryGetWaveBases(SpawnableTeamType spawnableTeamType, out IEnumerable spawnableWaveBases)
+ {
+ return TryGetWaveBases(spawnableTeamType.GetFaction(), out spawnableWaveBases);
+ }
+
+ ///
+ /// Advances the respawn timer for s.
+ ///
+ /// The whose 's timers are to be advanced.
+ /// Number of seconds to advance the timers by.
+ /// This advances the timer for both the normal and mini wave.
+ public static void AdvanceTimer(Faction faction, float seconds) => WaveManager.AdvanceTimer(faction, seconds);
+
+ ///
+ /// Advances the respawn timer for s.
+ ///
+ /// The whose 's timers are to be advanced.
+ /// A representing the amount of time to advance the timers by.
+ /// This advances the timer for both the normal and mini wave.
+ public static void AdvanceTimer(Faction faction, TimeSpan time) => AdvanceTimer(faction, (float)time.TotalSeconds);
+
+ ///
+ /// Advances the respawn timer for s.
///
- /// Docs1.
- /// Docs2.
- public static void AdvanceTime(Faction faction, float time) => WaveManager.AdvanceTimer(faction, time);
+ /// The whose 's timers are to be advanced.
+ /// Number of seconds to advance the timers by.
+ /// This advances the timer for both the normal and mini wave.
+ public static void AdvanceTimer(SpawnableTeamType spawnableTeamType, float seconds) => AdvanceTimer(spawnableTeamType.GetFaction(), seconds);
///
- /// Docs.
+ /// Advances the respawn timer for s.
///
- /// Docs1.
- public static void SpawnWave(SpawnableWaveBase wave) => WaveManager.Spawn(wave);
+ /// The whose 's timers are to be advanced.
+ /// A representing the amount of time to advance the timers by.
+ /// This advances the timer for both the normal and mini wave.
+ public static void AdvanceTimer(SpawnableTeamType spawnableTeamType, TimeSpan time) => AdvanceTimer(spawnableTeamType.GetFaction(), time);
///
- /// Docs.
+ /// Advances the respawn timer for s.
///
- /// Docs1.
- /// Docs2.
- /// Docs3.
- public static void SpawnWave(Faction faction, bool mini)
- where T : SpawnableWaveBase
+ /// The whose 's timer is to be advanced.
+ /// Number of seconds to advance the timers by.
+ public static void AdvanceTimer(SpawnableFaction spawnableFaction, float seconds)
{
- if (TryGetWaveBase(out T wave))
- SpawnWave(wave);
+ foreach (SpawnableWaveBase spawnableWaveBase in WaveManager.Waves)
+ {
+ TimeBasedWave timeBasedWave = (TimeBasedWave)spawnableWaveBase;
+ if (timeBasedWave.GetSpawnableFaction() == spawnableFaction)
+ {
+ timeBasedWave.Timer.AddTime(Mathf.Abs(seconds));
+ }
+ }
}
///
- /// Play effects when a certain class spawns.
+ /// Advances the respawn timer for s.
///
- /// The for which effects should be played.
+ /// The whose 's timer is to be advanced.
+ /// A representing the amount of time to advance the timers by.
+ public static void AdvanceTimer(SpawnableFaction spawnableFaction, TimeSpan time) => AdvanceTimer(spawnableFaction, (float)time.TotalSeconds);
+
+ ///
+ /// Play the spawn effect of a .
+ ///
+ /// The whose effect should be played.
public static void PlayEffect(SpawnableWaveBase wave)
{
WaveUpdateMessage.ServerSendUpdate(wave, UpdateMessageFlags.Trigger);
}
///
- /// Summons the NTF chopper.
+ /// Summons the chopper.
///
public static void SummonNtfChopper()
{
- if (TryGetWaveBase(Faction.FoundationStaff, out SpawnableWaveBase wave))
+ if (TryGetWaveBase(SpawnableFaction.NtfWave, out SpawnableWaveBase wave))
PlayEffect(wave);
}
///
- /// Summons the van.
+ /// Summons the van.
///
/// This will also trigger Music effect.
+ ///
public static void SummonChaosInsurgencyVan()
{
- if (TryGetWaveBase(Faction.FoundationEnemy, out SpawnableWaveBase wave))
+ if (TryGetWaveBase(SpawnableFaction.ChaosWave, out SpawnableWaveBase wave))
PlayEffect(wave);
}
///
- /// Grants tickets to a .
+ /// Grants tokens to a given 's s.
+ ///
+ /// The to whose s to grant tokens.
+ /// The amount of tokens to grant.
+ /// true if tokens were successfully granted to an , otherwise false.
+ public static bool GrantTokens(Faction faction, int amount)
+ {
+ if (TryGetWaveBases(faction, out IEnumerable waveBases))
+ {
+ foreach (ILimitedWave limitedWave in waveBases.OfType())
+ {
+ limitedWave.RespawnTokens += amount;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Removes tokens from a given 's s.
+ ///
+ /// The from whose s to remove tokens.
+ /// The amount of tokens to remove.
+ /// true if tokens were successfully removed from an , otherwise false.
+ public static bool RemoveTokens(Faction faction, int amount)
+ {
+ if (TryGetWaveBases(faction, out IEnumerable waveBases))
+ {
+ foreach (ILimitedWave limitedWave in waveBases.OfType())
+ {
+ limitedWave.RespawnTokens = Math.Max(0, limitedWave.RespawnTokens - amount);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Modifies tokens of a given 's s by a given amount.
///
- /// The to grant tickets to.
- /// The amount of tickets to grant.
- public static void GrantTickets(Faction team, int amount)
+ /// The whose s' tokens are to be modified.
+ /// The amount of tokens to add/remove.
+ /// true if tokens were successfully modified for an , otherwise false.
+ public static bool ModifyTokens(Faction faction, int amount)
{
- if (TryGetWaveBase(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave)
- limitedWave.RespawnTokens += amount;
+ if (TryGetWaveBases(faction, out IEnumerable waveBases))
+ {
+ foreach (ILimitedWave limitedWave in waveBases.OfType())
+ {
+ limitedWave.RespawnTokens = amount;
+ }
+
+ return true;
+ }
+
+ return false;
}
///
- /// Removes tickets from a .
+ /// Tries to get the tokens of a given 's .
///
- /// The to remove tickets from.
- /// The amount of tickets to remove.
- public static void RemoveTickets(Faction team, int amount)
+ /// The from whose to get the tokens.
+ /// The amount of tokens an has, if one was found, otherwise 0.
+ /// true if an was successfully found, otherwise false.
+ public static bool TryGetTokens(SpawnableFaction spawnableFaction, out int tokens)
{
- if (TryGetWaveBase(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave)
- limitedWave.RespawnTokens = Math.Max(0, limitedWave.RespawnTokens - amount);
+ if (TryGetWaveBase(spawnableFaction, out SpawnableWaveBase waveBase) && waveBase is ILimitedWave limitedWave)
+ {
+ tokens = limitedWave.RespawnTokens;
+ return true;
+ }
+
+ tokens = 0;
+ return false;
}
///
- /// Modify tickets from a .
+ /// Sets the amount of tokens of an of the given .
///
- /// The to modify tickets from.
- /// The amount of tickets to modify.
- public static void ModifyTickets(Faction team, int amount)
+ /// The whose 's tokens to set.
+ /// The amount of tokens to set.
+ /// true if tokens were successfully set for an , otherwise false.
+ public static bool SetTokens(SpawnableFaction spawnableFaction, int amount)
{
- if (TryGetWaveBase(team, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave)
+ if (TryGetWaveBase(spawnableFaction, out SpawnableWaveBase waveBase) && waveBase is ILimitedWave limitedWave)
+ {
limitedWave.RespawnTokens = amount;
+ return true;
+ }
+
+ return false;
+ }
+
+ ///
+ /// Starts the spawn sequence of the given .
+ ///
+ /// The whose wave to spawn.
+ /// Whether the wave should be a mini wave or not.
+ public static void ForceWave(SpawnableTeamType spawnableTeamType, bool isMini = false)
+ {
+ ForceWave(spawnableTeamType.GetFaction(), isMini);
+ }
+
+ ///
+ /// Starts the spawn sequence of the given .
+ ///
+ /// The whose wave to spawn.
+ /// Whether the wave should be a mini wave or not.
+ public static void ForceWave(Faction faction, bool isMini = false)
+ {
+ if (faction.TryGetSpawnableFaction(out SpawnableFaction spawnableFaction, isMini))
+ {
+ ForceWave(spawnableFaction);
+ }
+ }
+
+ ///
+ /// Starts the spawn sequence of the given .
+ ///
+ /// The whose wave to spawn.
+ public static void ForceWave(SpawnableFaction spawnableFaction)
+ {
+ if (TryGetWaveBase(spawnableFaction, out SpawnableWaveBase spawnableWaveBase))
+ {
+ ForceWave(spawnableWaveBase);
+ }
}
///
- /// Gets the amount of tickets from a .
+ /// Starts the spawn sequence of the given .
///
- /// 's faction.
- /// Tickets of team or -1 if team doesn't depend on tickets.
- public static int GetTickets(SpawnableFaction faction)
+ /// The to spawn.
+ public static void ForceWave(SpawnableWaveBase spawnableWaveBase)
{
- if (TryGetWaveBase(faction, out SpawnableWaveBase wave) && wave is ILimitedWave limitedWave)
- return limitedWave.RespawnTokens;
+ WaveManager.Spawn(spawnableWaveBase);
+ }
- return -1;
+ ///
+ /// Pauses respawn waves by removing them from WaveManager.Waves and storing them in .
+ ///
+ ///
+ public static void PauseWaves()
+ {
+ PausedWaves.Clear();
+ PausedWaves.AddRange(WaveManager.Waves);
+ WaveManager.Waves.Clear();
}
///
- /// Forces a spawn of the given .
+ /// Resumes respawn waves by filling WaveManager.Waves with values stored in .
///
- /// The to spawn.
- public static void ForceWave(Faction team)
+ ///
+ /// This also clears .
+ public static void ResumeWaves()
{
- if (TryGetWaveBase(team, out SpawnableWaveBase wave))
- ForceWave(wave);
+ WaveManager.Waves.Clear();
+ WaveManager.Waves.AddRange(PausedWaves);
+ PausedWaves.Clear();
}
///
- /// Docs.
+ /// Restarts respawn waves by clearing WaveManager.Waves and filling it with new values..
///
- /// Docs1.
- public static void ForceWave(SpawnableWaveBase wave)
+ ///
+ /// This also clears .
+ public static void RestartWaves()
{
- WaveManager.Spawn(wave);
+ WaveManager.Waves.Clear();
+ WaveManager.Waves.AddRange(new List { new ChaosMiniWave(), new ChaosSpawnWave(), new NtfMiniWave(), new NtfSpawnWave() });
+ PausedWaves.Clear();
}
+
+ ///
+ /// Tries to get the influence value of a given .
+ ///
+ /// The whose influence to get.
+ /// The amount of influence a faction has.
+ /// Whether an entry was successfully found.
+ public static bool TryGetFactionInfluence(Faction faction, out float influence) => FactionInfluence.TryGetValue(faction, out influence);
}
}
\ No newline at end of file