diff --git a/Exiled.API/Enums/UEBranchType.cs b/Exiled.API/Enums/UEBranchType.cs index 5433abd074..d04a7d189a 100644 --- a/Exiled.API/Enums/UEBranchType.cs +++ b/Exiled.API/Enums/UEBranchType.cs @@ -40,9 +40,9 @@ public class UEBranchType : UnmanagedEnumClass public static readonly UEBranchType Alpha = new(4); /// - /// The prealpha branch. + /// The pre alpha branch. /// - public static readonly UEBranchType Prealpha = new(5); + public static readonly UEBranchType PreAlpha = new(5); /// /// The unstable branch. diff --git a/Exiled.API/Features/Core/Components/TickComponent.cs b/Exiled.API/Features/Core/Components/TickComponent.cs index 7e65d93a3b..1aec75ac52 100644 --- a/Exiled.API/Features/Core/Components/TickComponent.cs +++ b/Exiled.API/Features/Core/Components/TickComponent.cs @@ -24,7 +24,7 @@ public sealed class TickComponent : EObject /// The default fixed tick rate (60 per second). /// #pragma warning disable SA1310 - public const float DEFAULT_FIXED_TICK_RATE = 0.016f; + public const float DEFAULT_FIXED_TICK_RATE = 1f / 60f; #pragma warning restore SA1310 private readonly HashSet boundHandles; diff --git a/Exiled.API/Features/Core/ConstProperty.cs b/Exiled.API/Features/Core/ConstProperty.cs index 49dc60b7c5..20fc8ba15f 100644 --- a/Exiled.API/Features/Core/ConstProperty.cs +++ b/Exiled.API/Features/Core/ConstProperty.cs @@ -1,4 +1,4 @@ -// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- // // Copyright (c) Exiled Team. All rights reserved. // Licensed under the CC BY-SA 3.0 license. @@ -48,8 +48,6 @@ public ConstProperty(T constantValue, Type[] typesToPatch, MethodInfo[] skipMeth /// ~ConstProperty() { - List.Remove(this); - foreach (MethodInfo methodInfo in PatchedMethods) { try diff --git a/Exiled.API/Features/Core/Generic/EBehaviour.cs b/Exiled.API/Features/Core/Generic/EBehaviour.cs index 8b0cc346b1..db747a196f 100644 --- a/Exiled.API/Features/Core/Generic/EBehaviour.cs +++ b/Exiled.API/Features/Core/Generic/EBehaviour.cs @@ -61,14 +61,13 @@ protected virtual void FindOwner() { MethodInfo method = typeof(T).GetMethod("Get", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(GameObject) }, null); - if (method != null) - { - Owner = (T)method.Invoke(null, new object[] { Base }); - } - else - { + if (method == null) throw new MissingMethodException($"Method 'Get(GameObject)' not found in class '{typeof(T).Name}'."); - } + + if (typeof(T).IsAssignableFrom(method.ReturnType)) + throw new MissingMethodException($"Method 'Get(GameObject)' in class '{typeof(T).Name}' do not return an instance of {typeof(T).Name} but {method.ReturnType}."); + + Owner = (T)method.Invoke(null, new object[] { Base }); } /// diff --git a/Exiled.API/Features/Core/Generic/EnumClass.cs b/Exiled.API/Features/Core/Generic/EnumClass.cs index 951275ff9a..9b8a7457b7 100644 --- a/Exiled.API/Features/Core/Generic/EnumClass.cs +++ b/Exiled.API/Features/Core/Generic/EnumClass.cs @@ -23,7 +23,7 @@ namespace Exiled.API.Features.Core.Generic /// /// The type of the source object to handle the instance of. /// The type of the child object to handle the instance of. - public abstract class EnumClass : IComparable, IEquatable, IComparable, IComparer, IEnumClass + public abstract class EnumClass : IComparable, IEquatable, IComparable, IEnumClass where TSource : Enum where TObject : EnumClass { @@ -205,17 +205,29 @@ public static bool SafeCast(IEnumerable values, out IEnumerable /// Determines whether the specified object is equal to the current object. /// - /// The object to compare. + /// The object to compare. /// if the object was equal; otherwise, . - public override bool Equals(object obj) => - obj != null && (obj is TSource value ? Value.Equals(value) : obj is TObject derived && Value.Equals(derived.Value)); + public bool Equals(TSource other) => Value.Equals(other); /// /// Determines whether the specified object is equal to the current object. /// /// The object to compare. /// if the object was equal; otherwise, . - public bool Equals(TObject other) => Value.Equals(other.Value); + public bool Equals(TObject other) + { + if (other is null) + return false; + + return Equals(other.Value); + } + + /// + /// Determines whether the specified object is equal to the current object. + /// + /// The object to compare. + /// if the object was equal; otherwise, . + public override bool Equals(object obj) => obj is TSource value ? Equals(value) : Equals(obj as TObject); /// /// Returns a the 32-bit signed hash code of the current object instance. @@ -235,36 +247,40 @@ public override bool Equals(object obj) => /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(TObject other) => Value.CompareTo(other.Value); + public int CompareTo(TSource other) => Comparer.Default.Compare(Value, other); /// /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare with this instance. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(object obj) => - obj == null ? -1 : obj is TSource value ? Value.CompareTo(value) : obj is TObject derived ? Value.CompareTo(derived.Value) : -1; + public int CompareTo(TObject other) + { + if (other is null) + return 1; + + return CompareTo(other.Value); + } /// - /// Compares the specified object instance with another object of the same type and returns + /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare. - /// Another object to compare. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int Compare(TObject x, TObject y) => x == null ? -1 : y == null ? 1 : x.Value.CompareTo(y.Value); + public int CompareTo(object obj) => obj is TSource value ? CompareTo(value) : CompareTo(obj as TObject); } } diff --git a/Exiled.API/Features/Core/Generic/Singleton.cs b/Exiled.API/Features/Core/Generic/Singleton.cs index a212b6f874..bbdbf925d3 100644 --- a/Exiled.API/Features/Core/Generic/Singleton.cs +++ b/Exiled.API/Features/Core/Generic/Singleton.cs @@ -19,66 +19,53 @@ namespace Exiled.API.Features.Core.Generic public sealed class Singleton : TypeCastObject where T : class { - private static readonly Dictionary> Instances = new(); - - /// - /// Initializes a new instance of the class. - /// - /// The branch to instantiate. - public Singleton(T value) - { - Destroy(value); - Value = value; - Instances.Add(value, this); - } - - /// - /// Finalizes an instance of the class. - /// - ~Singleton() => Instances.Remove(Value); - /// /// Gets the relative value. /// - public static T Instance => Instances.FirstOrDefault(@object => @object.Key.GetType() == typeof(T)).Value; - - /// - /// Gets the singleton value. - /// - internal T Value { get; private set; } - - /// - /// Converts the given instance into . - /// - /// The instance to convert. - public static implicit operator T(Singleton instance) => instance?.Value; + public static T Instance { get; private set; } /// /// Tries to get the relative value. /// - /// The type of the object. /// The object instance. /// if the object instance is not null and can be casted as the specified type; otherwise, . - public static bool TryGet(out TObject instance) - where TObject : class => (instance = Instance as TObject) is not null; + public static bool TryGet(out T instance) + => (instance = Instance) is not null; - /// - public static void Create(T @object) => new Singleton(@object); + /// + /// Define the value of the if not already defined. + /// If you want to replace first call . + /// + /// The object use to create the singleton. + public static void Create(T @object) + { + if (Instance is not null) + return; + Instance = @object; + } /// - /// Destroys the given instance. + /// Set to null if is the same. /// /// The object to destroy. /// if the instance was destroyed; otherwise, . public static bool Destroy(T @object) { - if (Instances.TryGetValue(@object, out Singleton _)) + if (Instance == @object) { - Instances[@object] = null; - return Instances.Remove(@object); + Instance = null; + return true; } return false; } + + /// + /// Set to null . + /// + public static void Destroy() + { + Instance = null; + } } } \ No newline at end of file diff --git a/Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs b/Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs index 0db2f2b9d7..b2dacf940f 100644 --- a/Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs +++ b/Exiled.API/Features/Core/Generic/UniqueUnmanagedEnumClass.cs @@ -15,6 +15,7 @@ namespace Exiled.API.Features.Core.Generic using Exiled.API.Features.Core.Generic.Pools; using Exiled.API.Interfaces; using LiteNetLib.Utils; + using YamlDotNet.Core.Tokens; using YamlDotNet.Serialization; /// @@ -23,37 +24,38 @@ namespace Exiled.API.Features.Core.Generic /// /// The type of the source object to handle the instance of. /// The type of the child object to handle the instance of. - public abstract class UniqueUnmanagedEnumClass : IComparable, IEquatable, IComparable, IComparer, IConvertible, IEnumClass + public abstract class UniqueUnmanagedEnumClass : IComparable, IEquatable, IComparable, IConvertible, IEnumClass where TSource : unmanaged, IComparable, IFormattable, IConvertible, IComparable, IEquatable where TObject : UniqueUnmanagedEnumClass { private static SortedList values; - private static int nextValue = int.MinValue; + private static long nextValue; private static bool isDefined; private string name; + static UniqueUnmanagedEnumClass() + { + values = new SortedList(); + nextValue = (int)typeof(TSource).GetField("MinValue").GetValue(null); + } + /// /// Initializes a new instance of the class. /// - public UniqueUnmanagedEnumClass() + internal protected UniqueUnmanagedEnumClass() { - values ??= new(); - TypeCode code = Convert.GetTypeCode(typeof(TSource).GetField("MinValue").GetValue(null)); - - if (code is TypeCode.UInt16 or TypeCode.UInt32 or TypeCode.UInt64) - nextValue = 0; - lock (values) { TSource value; do { - value = (TSource)Convert.ChangeType(nextValue++, code); + value = (TSource)Convert.ChangeType(nextValue++, Value.GetTypeCode()); } while (values.ContainsKey(value)); Value = value; + values.Add(value, (TObject)this); } } @@ -227,17 +229,29 @@ public static TObject Parse(string obj) /// /// Determines whether the specified object is equal to the current object. /// - /// The object to compare. + /// The object to compare. /// if the object was equal; otherwise, . - public override bool Equals(object obj) => - obj != null && (obj is TSource value ? Value.Equals(value) : obj is TObject derived && Value.Equals(derived.Value)); + public bool Equals(TSource other) => Value.Equals(other); /// /// Determines whether the specified object is equal to the current object. /// /// The object to compare. /// if the object was equal; otherwise, . - public bool Equals(TObject other) => Value.Equals(other.Value); + public bool Equals(TObject other) + { + if (other is null) + return false; + + return Equals(other.Value); + } + + /// + /// Determines whether the specified object is equal to the current object. + /// + /// The object to compare. + /// if the object was equal; otherwise, . + public override bool Equals(object obj) => obj is TSource value ? Equals(value) : Equals(obj as TObject); /// /// Returns a the 32-bit signed hash code of the current object instance. @@ -257,39 +271,43 @@ public override bool Equals(object obj) => /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(TObject other) => Value.CompareTo(other.Value); + public int CompareTo(TSource other) => Comparer.Default.Compare(Value, other); /// /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare with this instance. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(object obj) => - obj == null ? -1 : obj is TSource value ? Value.CompareTo(value) : obj is TObject derived ? Value.CompareTo(derived.Value) : -1; + public int CompareTo(TObject other) + { + if (other is null) + return 1; + + return CompareTo(other.Value); + } /// - /// Compares the specified object instance with another object of the same type and returns + /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare. - /// Another object to compare. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int Compare(TObject x, TObject y) => x == null ? -1 : y == null ? 1 : x.Value.CompareTo(y.Value); + public int CompareTo(object obj) => obj is TSource value ? CompareTo(value) : CompareTo(obj as TObject); -/// + /// TypeCode IConvertible.GetTypeCode() => Value.GetTypeCode(); /// diff --git a/Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs b/Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs index 2d396b1e6a..96a0338592 100644 --- a/Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs +++ b/Exiled.API/Features/Core/Generic/UnmanagedEnumClass.cs @@ -23,7 +23,7 @@ namespace Exiled.API.Features.Core.Generic /// /// The type of the source object to handle the instance of. /// The type of the child object to handle the instance of. - public abstract class UnmanagedEnumClass : IComparable, IEquatable, IComparable, IComparer, IConvertible, IEnumClass + public abstract class UnmanagedEnumClass : IComparable, IEquatable, IComparable, IConvertible, IEnumClass where TSource : unmanaged, IComparable, IFormattable, IConvertible, IComparable, IEquatable where TObject : UnmanagedEnumClass { @@ -212,17 +212,29 @@ public static TObject Parse(string obj) /// /// Determines whether the specified object is equal to the current object. /// - /// The object to compare. + /// The object to compare. /// if the object was equal; otherwise, . - public override bool Equals(object obj) => - obj != null && (obj is TSource value ? Value.Equals(value) : obj is TObject derived && Value.Equals(derived.Value)); + public bool Equals(TSource other) => Value.Equals(other); /// /// Determines whether the specified object is equal to the current object. /// /// The object to compare. /// if the object was equal; otherwise, . - public bool Equals(TObject other) => Value.Equals(other.Value); + public bool Equals(TObject other) + { + if (other is null) + return false; + + return Equals(other.Value); + } + + /// + /// Determines whether the specified object is equal to the current object. + /// + /// The object to compare. + /// if the object was equal; otherwise, . + public override bool Equals(object obj) => obj is TSource value ? Equals(value) : Equals(obj as TObject); /// /// Returns a the 32-bit signed hash code of the current object instance. @@ -242,37 +254,41 @@ public override bool Equals(object obj) => /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(TObject other) => Value.CompareTo(other.Value); + public int CompareTo(TSource other) => Value.CompareTo(other); /// /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare with this instance. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int CompareTo(object obj) => - obj == null ? -1 : obj is TSource value ? Value.CompareTo(value) : obj is TObject derived ? Value.CompareTo(derived.Value) : -1; + public int CompareTo(TObject other) + { + if (other is null) + return 1; + + return CompareTo(other.Value); + } /// - /// Compares the specified object instance with another object of the same type and returns + /// Compares the current instance with another object of the same type and returns /// an integer that indicates whether the current instance precedes, follows, or /// occurs in the same position in the sort order as the other object. /// - /// An object to compare. - /// Another object to compare. + /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. /// The return value has these meanings: Value Meaning Less than zero This instance precedes other in the sort order. /// Zero This instance occurs in the same position in the sort order as other. /// Greater than zero This instance follows other in the sort order. /// - public int Compare(TObject x, TObject y) => x == null ? -1 : y == null ? 1 : x.Value.CompareTo(y.Value); + public int CompareTo(object obj) => obj is TSource value ? CompareTo(value) : CompareTo(obj as TObject); /// TypeCode IConvertible.GetTypeCode() => Value.GetTypeCode(); diff --git a/Exiled.API/Features/Player.cs b/Exiled.API/Features/Player.cs index 62b1d2375c..a3f0d13bb9 100644 --- a/Exiled.API/Features/Player.cs +++ b/Exiled.API/Features/Player.cs @@ -4049,10 +4049,10 @@ public void ChangeAppearance(RoleTypeId type, IEnumerable playersToAffec /// /// Send CASSIE announcement that only can hear. /// - /// Announcement words. - /// Same on 's isHeld. - /// Same on 's isNoisy. - /// Same on 's isSubtitles. + /// + /// + /// + /// public void PlayCassieAnnouncement(string words, bool makeHold = false, bool makeNoise = true, bool isSubtitles = false) { foreach (RespawnEffectsController controller in RespawnEffectsController.AllControllers) @@ -4067,11 +4067,12 @@ public void PlayCassieAnnouncement(string words, bool makeHold = false, bool mak /// /// Send CASSIE announcement with custom subtitles for translation that only can hear and see it. /// - /// The message to be reproduced. - /// The translation should be show in the subtitles. - /// Same on 's isHeld. - /// Same on 's isNoisy. - /// Same on 's isSubtitles. + /// + /// + /// + /// + /// + // @Nao, why not inherit the documentation for the param ? public void SendCassieAnnouncement(string words, string translation, bool makeHold = false, bool makeNoise = true, bool isSubtitles = true) { StringBuilder announcement = StringBuilderPool.Pool.Get(); diff --git a/Exiled.API/Features/Respawn.cs b/Exiled.API/Features/Respawn.cs index 59f4e0207b..69a49f8748 100644 --- a/Exiled.API/Features/Respawn.cs +++ b/Exiled.API/Features/Respawn.cs @@ -23,6 +23,9 @@ namespace Exiled.API.Features /// public static class Respawn { + private const string MtfChopperGameObjectName = "Chopper"; + private const string ChaosVanGameObjectName = "CIVanArrive"; + private static GameObject ntfHelicopterGameObject; private static GameObject chaosCarGameObject; @@ -34,7 +37,7 @@ public static GameObject NtfHelicopter get { if (ntfHelicopterGameObject == null) - ntfHelicopterGameObject = GameObject.Find("Chopper"); + ntfHelicopterGameObject = GameObject.Find(MtfChopperGameObjectName); return ntfHelicopterGameObject; } @@ -48,7 +51,7 @@ public static GameObject ChaosVan get { if (chaosCarGameObject == null) - chaosCarGameObject = GameObject.Find("CIVanArrive"); + chaosCarGameObject = GameObject.Find(ChaosVanGameObjectName); return chaosCarGameObject; } diff --git a/Exiled.API/Features/VirtualAssemblies/VirtualPlugin.cs b/Exiled.API/Features/VirtualAssemblies/VirtualPlugin.cs index c35fb0f1d0..addc77571b 100644 --- a/Exiled.API/Features/VirtualAssemblies/VirtualPlugin.cs +++ b/Exiled.API/Features/VirtualAssemblies/VirtualPlugin.cs @@ -175,7 +175,7 @@ public static IEnumerable EnableAll() continue; VirtualPlugin vp = Activator.CreateInstance(type) as VirtualPlugin; - vp.TryRegister(type.GetCustomAttribute(typeof(VirtualPluginAttribute)) as VirtualPluginAttribute); + vp.TryRegister(type.GetCustomAttribute()); vps.Add(vp); } @@ -274,7 +274,7 @@ protected virtual void OnReloaded() /// protected virtual void CreateInstance() { - Singleton.Create(this); + // Singleton.Create(this); } /// @@ -283,7 +283,6 @@ protected virtual void CreateInstance() protected virtual void DestroyInstance() { Config = null; - Singleton.Destroy(this); } /// diff --git a/Exiled.CustomModules/API/Features/CustomEscapes/EscapeSettings.cs b/Exiled.CustomModules/API/Features/CustomEscapes/EscapeSettings.cs index c2fa914066..ba3282ef3f 100644 --- a/Exiled.CustomModules/API/Features/CustomEscapes/EscapeSettings.cs +++ b/Exiled.CustomModules/API/Features/CustomEscapes/EscapeSettings.cs @@ -83,7 +83,7 @@ public EscapeSettings( Role = role; CustomRole = CustomRole.Get(customRole); Position = position == default ? DefaultPosition : position; - DistanceThreshold = distanceThreshold == DEFAULT_MAX_DISTANCE_TOLERANCE ? DEFAULT_MAX_DISTANCE_TOLERANCE : distanceThreshold; + DistanceThreshold = distanceThreshold; } /// diff --git a/Exiled.CustomModules/API/Features/CustomGamemodes/GameModeSettings.cs b/Exiled.CustomModules/API/Features/CustomGamemodes/GameModeSettings.cs index de338dedd6..c263a041c1 100644 --- a/Exiled.CustomModules/API/Features/CustomGamemodes/GameModeSettings.cs +++ b/Exiled.CustomModules/API/Features/CustomGamemodes/GameModeSettings.cs @@ -214,7 +214,7 @@ public class GameModeSettings : TypeCastObject, IAdditivePrope public virtual uint[] NonSpawnableCustomRoles { get; set; } /// - /// Gets or sets a [] containing all non spawnable custom teams. + /// Gets or sets a [] containing all non spawnable custom teams. /// /// If not empty, all undefined teams will be able to spawn. ///
diff --git a/Exiled.CustomModules/API/Features/CustomRoles/CustomRole.cs b/Exiled.CustomModules/API/Features/CustomRoles/CustomRole.cs index a48e8f4391..d50fc7e8a6 100644 --- a/Exiled.CustomModules/API/Features/CustomRoles/CustomRole.cs +++ b/Exiled.CustomModules/API/Features/CustomRoles/CustomRole.cs @@ -264,8 +264,7 @@ public virtual bool EvaluateConditions { if (pawn.Role == RequiredRoleToSpawn) { - if ((RoleExtensions.GetTeam(RequiredRoleToSpawn) is Team.SCPs && !pawn.IsScp) || - (RoleExtensions.GetTeam(RequiredRoleToSpawn) is not Team.SCPs && pawn.IsScp)) + if ((RoleExtensions.GetTeam(RequiredRoleToSpawn) is Team.SCPs) != pawn.IsScp) continue; return true; diff --git a/Exiled.CustomModules/API/Features/CustomRoles/CustomTeam.cs b/Exiled.CustomModules/API/Features/CustomRoles/CustomTeam.cs index e113bb78ea..4d9fe6fb78 100644 --- a/Exiled.CustomModules/API/Features/CustomRoles/CustomTeam.cs +++ b/Exiled.CustomModules/API/Features/CustomRoles/CustomTeam.cs @@ -36,6 +36,9 @@ namespace Exiled.CustomModules.API.Features.CustomRoles /// public abstract class CustomTeam : CustomModule { + private const string VanilaConfigMtfMinTime = "minimum_MTF_time_to_spawn"; + private const string VanilaConfigMtfMaxTime = "maximum_MTF_time_to_spawn"; + private static readonly Dictionary PlayersValue = new(); private static readonly List Registered = new(); private static readonly Dictionary TypeLookupTable = new(); @@ -121,13 +124,13 @@ public abstract class CustomTeam : CustomModule /// Gets or sets the minimum amount of time after which any team will be allowed to spawn. ///
[Description("The minimum time before the team can spawn.")] - public virtual float MinNextSequenceTime { get; set; } = GameCore.ConfigFile.ServerConfig.GetFloat("minimum_MTF_time_to_spawn", 280f); + public virtual float MinNextSequenceTime { get; set; } = GameCore.ConfigFile.ServerConfig.GetFloat(VanilaConfigMtfMinTime, 280f); /// /// Gets or sets the maximum amount of time after which any team will be spawned. /// [Description("The maximum time before the team can spawn.")] - public virtual float MaxNextSequenceTime { get; set; } = GameCore.ConfigFile.ServerConfig.GetFloat("maximum_MTF_time_to_spawn", 350f); + public virtual float MaxNextSequenceTime { get; set; } = GameCore.ConfigFile.ServerConfig.GetFloat(VanilaConfigMtfMaxTime, 350f); /// /// Gets or sets the relative spawn probability of the . @@ -223,8 +226,7 @@ public virtual bool EvaluateConditions { if (pawn.Role == RequiredRoleToSpawn) { - if ((RoleExtensions.GetTeam(RequiredRoleToSpawn) is Team.SCPs && !pawn.IsScp) || - (RoleExtensions.GetTeam(RequiredRoleToSpawn) is not Team.SCPs && pawn.IsScp)) + if ((RoleExtensions.GetTeam(RequiredRoleToSpawn) is Team.SCPs) != pawn.IsScp) continue; return true; diff --git a/Exiled.CustomModules/API/Features/CustomRoles/RoleBehaviour.cs b/Exiled.CustomModules/API/Features/CustomRoles/RoleBehaviour.cs index 4a23ca940b..f80c11d5f5 100644 --- a/Exiled.CustomModules/API/Features/CustomRoles/RoleBehaviour.cs +++ b/Exiled.CustomModules/API/Features/CustomRoles/RoleBehaviour.cs @@ -190,37 +190,47 @@ public virtual RoleTypeId FakeAppearance /// /// Evaluates the specified conditions affecting the round's ending conditions. /// - /// The corresponding evaluation. + /// + /// if the round should continue. + ///
Otherwise, if the round can end. + /// All other condition need to be to end the round. + ///
public virtual bool EvaluateEndingConditions() { - if (CustomRole.TeamsOwnership.Length == 1) - return true; - - SummaryInfo summaryInfo = World.Get().SummaryInfo; - - if (CustomRole.TeamsOwnership.Contains(Team.SCPs) && summaryInfo.FoundationForces <= 0 && summaryInfo.ChaosInsurgency <= 0) - return true; + SummaryInfo summaryInfo; + switch (CustomRole.TeamsOwnership.Length) + { + case 0: + summaryInfo = World.Get().SummaryInfo; + int uniqueFaction = 0; + if (summaryInfo.FoundationForces > 0) + ++uniqueFaction; + if (summaryInfo.ChaosInsurgency > 0) + ++uniqueFaction; + if (summaryInfo.Anomalies > 0) + ++uniqueFaction; + return uniqueFaction <= 1; + + case 1: return true; + + default: + summaryInfo = World.Get().SummaryInfo; + + bool noChaos = summaryInfo.ChaosInsurgency <= 0; + bool noFondation = summaryInfo.FoundationForces <= 0; + bool noScp = summaryInfo.ChaosInsurgency <= 0; + + if (noFondation && noChaos && CustomRole.TeamsOwnership.Contains(Team.SCPs)) + return true; - if (CustomRole.TeamsOwnership.Any(team => team is Team.ClassD or Team.ChaosInsurgency) && summaryInfo.FoundationForces <= 0 && summaryInfo.Anomalies <= 0) - return true; + if (noFondation && noScp && CustomRole.TeamsOwnership.Any(team => team is Team.ClassD or Team.ChaosInsurgency)) + return true; - if (CustomRole.TeamsOwnership.Any(team => team is Team.FoundationForces or Team.Scientists) && summaryInfo.ChaosInsurgency <= 0 && summaryInfo.Anomalies <= 0) - return true; + if (noChaos && noScp && CustomRole.TeamsOwnership.Any(team => team is Team.FoundationForces or Team.Scientists)) + return true; - if (CustomRole.TeamsOwnership.IsEmpty()) - { - int uniqueFaction = 0; - if (summaryInfo.FoundationForces > 0) - ++uniqueFaction; - if (summaryInfo.ChaosInsurgency > 0) - ++uniqueFaction; - if (summaryInfo.Anomalies > 0) - ++uniqueFaction; - - return uniqueFaction <= 1; + return false; } - - return false; } /// diff --git a/Exiled.CustomModules/API/Features/RespawnManager.cs b/Exiled.CustomModules/API/Features/RespawnManager.cs index ab0611850c..9102130347 100644 --- a/Exiled.CustomModules/API/Features/RespawnManager.cs +++ b/Exiled.CustomModules/API/Features/RespawnManager.cs @@ -191,6 +191,9 @@ private void OnPreRespawningTeam(PreRespawningTeamEventArgs ev) { PreviousKnownTeam = NextKnownTeam; + if (!ev.IsAllowed) + return; + if (NextKnownTeam is null or SpawnableTeamType) { ev.IsAllowed = true; @@ -201,9 +204,7 @@ private void OnPreRespawningTeam(PreRespawningTeamEventArgs ev) if (customTeam is null) return; - if (customTeam.TeamsOwnership.Any(t => - t == (ev.NextKnownTeam is SpawnableTeamType.ChaosInsurgency ? - Team.ChaosInsurgency : Team.FoundationForces))) + if (customTeam.TeamsOwnership.Any(t => t == (Team)ev.NextKnownTeam)) { ev.MaxWaveSize = customTeam.Size; return; diff --git a/Exiled.CustomModules/API/Features/World.cs b/Exiled.CustomModules/API/Features/World.cs index 56ee3dd8ef..f11494bd92 100644 --- a/Exiled.CustomModules/API/Features/World.cs +++ b/Exiled.CustomModules/API/Features/World.cs @@ -234,7 +234,7 @@ private void OnEndingRound(EndingRoundEventArgs ev) if (!ev.IsAllowed) return; - foreach (CustomRole role in CustomRole.Get(cr => cr.TeamsOwnership.Length != 1 && cr.Instances > 1)) + foreach (CustomRole role in CustomRole.Get(cr => cr.Instances > 1)) { if (role.Owners.First().RoleBehaviour.EvaluateEndingConditions()) continue;