Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public abstract class CustomRole
/// </summary>
public static HashSet<CustomRole> Registered { get; } = new();

/// <summary>
/// Gets or sets a value indicating whether the role is enabled.
/// </summary>
public virtual bool IsEnabled { get; set; } = true;

/// <summary>
/// Gets or sets the custom RoleID of the role.
/// </summary>
Expand Down Expand Up @@ -323,6 +328,41 @@ public static IEnumerable<CustomRole> RegisterRoles(bool byAttribute = false)
return roles;
}

/// <summary>
/// Registers all the <see cref="CustomRole"/>'s present in the current plugin's config.
/// </summary>
/// <param name="source">The source containing the custom roles.</param>
/// <param name="ignoredRoles">An optional collection of <see cref="CustomRole"/>s to ignore during registration.</param>
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="CustomRole"/> which contains all registered <see cref="CustomRole"/>'s.</returns>
public static IEnumerable<CustomRole> RegisterRolesFromSource(object source, IEnumerable<CustomRole>? ignoredRoles = null)
{
List<CustomRole> roles = new();

if (source == null)
return roles;

HashSet<Type>? ignoredTypes = ignoredRoles?.Select(x => x.GetType()).ToHashSet();

PropertyInfo[] properties = source.GetType().GetProperties();

foreach (PropertyInfo property in properties)
{
if (!typeof(CustomRole).IsAssignableFrom(property.PropertyType))
continue;

if (property.GetValue(source) is not CustomRole sourceRole)
continue;

if (ignoredTypes != null && ignoredTypes.Contains(sourceRole.GetType()))
continue;

if (sourceRole.TryRegister())
roles.Add(sourceRole);
}

return roles;
}

/// <summary>
/// Registers all the <see cref="CustomRole"/>'s present in the current assembly.
/// </summary>
Expand Down Expand Up @@ -486,6 +526,41 @@ public static IEnumerable<CustomRole> UnregisterRoles(IEnumerable<Type> targetTy
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="CustomRole"/> which contains all unregistered <see cref="CustomRole"/>'s.</returns>
public static IEnumerable<CustomRole> UnregisterRoles(IEnumerable<CustomRole> targetRoles, bool isIgnored = false) => UnregisterRoles(targetRoles.Select(x => x.GetType()), isIgnored);

/// <summary>
/// Unregisters all the <see cref="CustomRole"/>'s present in the current plugin's config.
/// </summary>
/// <param name="source">The source containing the target roles.</param>
/// <param name="ignoredRoles">An optional collection of <see cref="CustomRole"/>s to ignore during unregisteration.</param>
/// <returns>A <see cref="IEnumerable{T}"/> of <see cref="CustomRole"/> which contains all unregistered <see cref="CustomRole"/>'s.</returns>
public static IEnumerable<CustomRole> UnregisterFromSource(object source, IEnumerable<CustomRole>? ignoredRoles = null)
{
List<CustomRole> roles = new();

if (source == null)
return roles;

HashSet<Type>? ignoredTypes = ignoredRoles?.Select(x => x.GetType()).ToHashSet();

PropertyInfo[] properties = source.GetType().GetProperties();

foreach (PropertyInfo property in properties)
{
if (!typeof(CustomRole).IsAssignableFrom(property.PropertyType))
continue;

if (property.GetValue(source) is not CustomRole sourceRole)
continue;

if (ignoredTypes != null && ignoredTypes.Contains(sourceRole.GetType()))
continue;

if (sourceRole.TryUnregister())
roles.Add(sourceRole);
}

return roles;
}

/// <summary>
/// ResyncCustomRole Friendly Fire with Player (Append, or Overwrite).
/// </summary>
Expand Down Expand Up @@ -810,6 +885,12 @@ internal bool TryRegister()
if (!CustomRoles.Instance!.Config.IsEnabled)
return false;

if (!IsEnabled)
{
Log.Debug($"Custom role {Name} is not enabled and will not be registered.");
return false;
}

if (!Registered.Contains(this))
{
if (Registered.Any(r => r.Id == Id))
Expand Down
32 changes: 7 additions & 25 deletions EXILED/Exiled.CustomRoles/Events/PlayerHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Exiled.CustomRoles.Events
using Exiled.CustomRoles.API.Features;
using Exiled.Events.EventArgs.Player;

using UnityEngine;

/// <summary>
/// Handles general events for players.
/// </summary>
Expand Down Expand Up @@ -66,34 +68,28 @@ internal void OnSpawningRagdoll(SpawningRagdollEventArgs ev)
internal void OnSpawned(SpawnedEventArgs ev)
{
if (!ValidSpawnReasons.Contains(ev.Reason) || ev.Player.HasAnyCustomRole())
{
return;
}

float totalChance = 0f;
List<CustomRole> eligibleRoles = new(8);

foreach (CustomRole role in CustomRole.Registered)
{
if (role.Role == ev.Player.Role.Type && !role.IgnoreSpawnSystem && role.SpawnChance > 0 && !role.Check(ev.Player) && (role.SpawnProperties is null || role.SpawnedPlayers < role.SpawnProperties.Limit) && (role.MinPlayers is 0 || Server.PlayerConnectedCount >= role.MinPlayers))
if (role.Role == ev.Player.Role.Type && !role.IgnoreSpawnSystem && role.SpawnChance > 0 && (role.SpawnProperties is null || role.SpawnedPlayers < role.SpawnProperties.Limit) && (role.MinPlayers is 0 || Server.PlayerConnectedCount >= role.MinPlayers))
{
eligibleRoles.Add(role);
totalChance += role.SpawnChance;
}
}

if (eligibleRoles.Count == 0)
{
return;
}

float lotterySize = Math.Max(100f, totalChance);
float lotterySize = Mathf.Max(100f, totalChance);
float randomRoll = (float)Loader.Loader.Random.NextDouble() * lotterySize;

if (randomRoll >= totalChance)
{
return;
}

foreach (CustomRole candidateRole in eligibleRoles)
{
Expand All @@ -103,23 +99,9 @@ internal void OnSpawned(SpawnedEventArgs ev)
continue;
}

if (candidateRole.SpawnProperties is null)
{
candidateRole.AddRole(ev.Player);
break;
}

int newSpawnCount = candidateRole.SpawnedPlayers++;
if (newSpawnCount <= candidateRole.SpawnProperties.Limit)
{
candidateRole.AddRole(ev.Player);
break;
}
else
{
candidateRole.SpawnedPlayers--;
randomRoll -= candidateRole.SpawnChance;
}
candidateRole.SpawnedPlayers++;
candidateRole.AddRole(ev.Player);
break;
Comment thread
Someone-193 marked this conversation as resolved.
}
}
}
Expand Down
Loading