Skip to content

Commit b8387ee

Browse files
committed
added spawnreason and flags
1 parent daaa1eb commit b8387ee

File tree

1 file changed

+110
-81
lines changed

1 file changed

+110
-81
lines changed

EXILED/Exiled.CustomRoles/API/Features/CustomRole.cs

Lines changed: 110 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,16 @@ namespace Exiled.CustomRoles.API.Features
3737
/// </summary>
3838
public abstract class CustomRole
3939
{
40-
private const float AddRoleDelay = 0.25f;
40+
/// <summary>
41+
/// The delay after which ammo and items are added to the player.
42+
/// </summary>
43+
public const float AddRoleItemAndAmmoDelay = 0.25f;
4144

42-
private static Dictionary<Type, CustomRole?> typeLookupTable = new();
45+
private static readonly Dictionary<Type, CustomRole?> TypeLookupTable = new();
4346

44-
private static Dictionary<string, CustomRole?> stringLookupTable = new();
47+
private static readonly Dictionary<string, CustomRole?> StringLookupTable = new();
4548

46-
private static Dictionary<uint, CustomRole?> idLookupTable = new();
49+
private static readonly Dictionary<uint, CustomRole?> IdLookupTable = new();
4750

4851
/// <summary>
4952
/// Gets a list of all registered custom roles.
@@ -144,7 +147,7 @@ public abstract class CustomRole
144147
/// <summary>
145148
/// Gets or sets a value indicating broadcast that will be shown to the player.
146149
/// </summary>
147-
public virtual Broadcast Broadcast { get; set; } = new Broadcast();
150+
public virtual Broadcast? Broadcast { get; set; } = new Broadcast();
148151

149152
/// <summary>
150153
/// Gets or sets a value indicating whether players will receive a message for getting a custom item, when gaining it through the inventory config for this role.
@@ -183,9 +186,9 @@ public abstract class CustomRole
183186
/// <returns>The role, or <see langword="null"/> if it doesn't exist.</returns>
184187
public static CustomRole? Get(uint id)
185188
{
186-
if (!idLookupTable.ContainsKey(id))
187-
idLookupTable.Add(id, Registered?.FirstOrDefault(r => r.Id == id));
188-
return idLookupTable[id];
189+
if (!IdLookupTable.ContainsKey(id))
190+
IdLookupTable.Add(id, Registered?.FirstOrDefault(r => r.Id == id));
191+
return IdLookupTable[id];
189192
}
190193

191194
/// <summary>
@@ -195,9 +198,9 @@ public abstract class CustomRole
195198
/// <returns>The role, or <see langword="null"/> if it doesn't exist.</returns>
196199
public static CustomRole? Get(Type t)
197200
{
198-
if (!typeLookupTable.ContainsKey(t))
199-
typeLookupTable.Add(t, Registered?.FirstOrDefault(r => r.GetType() == t));
200-
return typeLookupTable[t];
201+
if (!TypeLookupTable.ContainsKey(t))
202+
TypeLookupTable.Add(t, Registered?.FirstOrDefault(r => r.GetType() == t));
203+
return TypeLookupTable[t];
201204
}
202205

203206
/// <summary>
@@ -207,9 +210,9 @@ public abstract class CustomRole
207210
/// <returns>The role, or <see langword="null"/> if it doesn't exist.</returns>
208211
public static CustomRole? Get(string name)
209212
{
210-
if (!stringLookupTable.ContainsKey(name))
211-
stringLookupTable.Add(name, Registered?.FirstOrDefault(r => r.Name == name));
212-
return stringLookupTable[name];
213+
if (!StringLookupTable.ContainsKey(name))
214+
StringLookupTable.Add(name, Registered?.FirstOrDefault(r => r.Name == name));
215+
return StringLookupTable[name];
213216
}
214217

215218
/// <summary>
@@ -481,9 +484,9 @@ public static void ForceSyncSetPlayerFriendlyFire(CustomRole roleToSync, Player
481484
/// </summary>
482485
public virtual void Init()
483486
{
484-
idLookupTable.Add(Id, this);
485-
typeLookupTable.Add(GetType(), this);
486-
stringLookupTable.Add(Name, this);
487+
IdLookupTable.Add(Id, this);
488+
TypeLookupTable.Add(GetType(), this);
489+
StringLookupTable.Add(Name, this);
487490
SubscribeEvents();
488491
}
489492

@@ -492,68 +495,75 @@ public virtual void Init()
492495
/// </summary>
493496
public virtual void Destroy()
494497
{
495-
idLookupTable.Remove(Id);
496-
typeLookupTable.Remove(GetType());
497-
stringLookupTable.Remove(Name);
498+
IdLookupTable.Remove(Id);
499+
TypeLookupTable.Remove(GetType());
500+
StringLookupTable.Remove(Name);
498501
UnsubscribeEvents();
499502
}
500503

501504
/// <summary>
502505
/// Handles setup of the role, including spawn location, inventory and registering event handlers and add FF rules.
503506
/// </summary>
504507
/// <param name="player">The <see cref="Player"/> to add the role to.</param>
505-
public virtual void AddRole(Player player)
508+
public virtual void AddRole(Player player) => AddRole(player, SpawnReason.ForceClass, false, RoleSpawnFlags.All);
509+
510+
/// <summary>
511+
/// Handles setup of the role, including spawn location, inventory and registering event handlers and add FF rules.
512+
/// </summary>
513+
/// <param name="player">The <see cref="Player"/> to add the role to.</param>
514+
/// <param name="spawnReason">The <see cref="SpawnReason"/>.</param>
515+
/// <param name="overrideFlags">Whether it should use <paramref name="overrideSpawnFlags"/> or not.</param>
516+
/// <param name="overrideSpawnFlags">The <see cref="RoleSpawnFlags"/> to apply if <paramref name="overrideFlags"/> is <see langword="true"/>.</param>
517+
public virtual void AddRole(Player player, SpawnReason spawnReason = SpawnReason.ForceClass, bool overrideFlags = false, RoleSpawnFlags overrideSpawnFlags = RoleSpawnFlags.All)
506518
{
507519
Log.Debug($"{Name}: Adding role to {player.Nickname}.");
508520
player.UniqueRole = Name;
509521

510-
if (Role != RoleTypeId.None)
522+
RoleSpawnFlags keptSpawnFlags = overrideSpawnFlags;
523+
524+
if (Role == RoleTypeId.None)
511525
{
512-
if (KeepPositionOnSpawn)
513-
{
514-
if (KeepInventoryOnSpawn)
515-
player.Role.Set(Role, SpawnReason.ForceClass, RoleSpawnFlags.None);
516-
else
517-
player.Role.Set(Role, SpawnReason.ForceClass, RoleSpawnFlags.AssignInventory);
518-
}
519-
else
526+
keptSpawnFlags = RoleSpawnFlags.None;
527+
}
528+
else
529+
{
530+
if (!overrideFlags)
520531
{
521-
if (KeepInventoryOnSpawn && player.IsAlive)
522-
player.Role.Set(Role, SpawnReason.ForceClass, RoleSpawnFlags.UseSpawnpoint);
532+
if (KeepPositionOnSpawn)
533+
keptSpawnFlags = KeepInventoryOnSpawn ? RoleSpawnFlags.None : RoleSpawnFlags.AssignInventory;
523534
else
524-
player.Role.Set(Role, SpawnReason.ForceClass, RoleSpawnFlags.All);
535+
keptSpawnFlags = KeepInventoryOnSpawn && player.IsAlive ? RoleSpawnFlags.UseSpawnpoint : RoleSpawnFlags.All;
525536
}
537+
538+
player.Role.Set(Role, spawnReason, keptSpawnFlags);
526539
}
527540

528541
player.UniqueRole = Name;
529542
TrackedPlayers.Add(player);
530543

531-
Timing.CallDelayed(
532-
AddRoleDelay,
533-
() =>
534-
{
535-
if (!KeepInventoryOnSpawn)
544+
if (keptSpawnFlags.HasFlag(RoleSpawnFlags.AssignInventory))
545+
{
546+
Timing.CallDelayed(
547+
AddRoleItemAndAmmoDelay,
548+
() =>
536549
{
537550
Log.Debug($"{Name}: Clearing {player.Nickname}'s inventory.");
538551
player.ClearInventory();
539-
}
540552

541-
foreach (string itemName in Inventory)
542-
{
543-
Log.Debug($"{Name}: Adding {itemName} to inventory.");
544-
TryAddItem(player, itemName);
545-
}
553+
foreach (string itemName in Inventory)
554+
{
555+
Log.Debug($"{Name}: Adding {itemName} to inventory.");
556+
TryAddItem(player, itemName);
557+
}
546558

547-
if (Ammo.Count > 0)
548-
{
549559
Log.Debug($"{Name}: Adding Ammo to {player.Nickname} inventory.");
550560
foreach (AmmoType type in EnumUtils<AmmoType>.Values)
551561
{
552562
if (type != AmmoType.None)
553563
player.SetAmmo(type, Ammo.ContainsKey(type) ? Ammo[type] == ushort.MaxValue ? InventoryLimits.GetAmmoLimit(type.GetItemType(), player.ReferenceHub) : Ammo[type] : (ushort)0);
554564
}
555-
}
556-
});
565+
});
566+
}
557567

558568
Log.Debug($"{Name}: Setting health values.");
559569
player.Health = MaxHealth;
@@ -563,9 +573,7 @@ public virtual void AddRole(Player player)
563573
fpcRole.Gravity = Gravity.Value;
564574
Vector3 position = GetSpawnPosition();
565575
if (position != Vector3.zero)
566-
{
567576
player.Position = position;
568-
}
569577

570578
Log.Debug($"{Name}: Setting player info");
571579

@@ -580,7 +588,7 @@ public virtual void AddRole(Player player)
580588

581589
ShowMessage(player);
582590
ShowBroadcast(player);
583-
RoleAdded(player);
591+
RoleAdded(player, spawnReason, keptSpawnFlags);
584592
player.TryAddCustomRoleFriendlyFire(Name, CustomRoleFFMultiplier);
585593

586594
if (!string.IsNullOrEmpty(ConsoleMessage))
@@ -611,56 +619,49 @@ public virtual void AddRole(Player player)
611619
/// Removes the role from a specific player and FF rules.
612620
/// </summary>
613621
/// <param name="player">The <see cref="Player"/> to remove the role from.</param>
614-
public virtual void RemoveRole(Player player)
622+
public virtual void RemoveRole(Player player) => RemoveRole(player, SpawnReason.ForceClass, RoleSpawnFlags.All);
623+
624+
/// <summary>
625+
/// Removes the role from a specific player and FF rules.
626+
/// </summary>
627+
/// <param name="player">The <see cref="Player"/> to remove the role from.</param>
628+
/// <param name="spawnReason">The <see cref="SpawnReason"/>.</param>
629+
/// <param name="roleSpawnFlags">The <see cref="RoleSpawnFlags"/> to apply.</param>
630+
public virtual void RemoveRole(Player player, SpawnReason spawnReason = SpawnReason.ForceClass, RoleSpawnFlags roleSpawnFlags = RoleSpawnFlags.All)
615631
{
616-
if (!TrackedPlayers.Contains(player))
632+
if (!TrackedPlayers.Remove(player))
617633
return;
634+
618635
Log.Debug($"{Name}: Removing role from {player.Nickname}");
619-
TrackedPlayers.Remove(player);
620636
player.CustomInfo = string.Empty;
621637
player.InfoArea |= PlayerInfoArea.Role | PlayerInfoArea.Nickname;
622638
player.Scale = Vector3.one;
623639
if (CustomAbilities is not null)
624640
{
625641
foreach (CustomAbility ability in CustomAbilities)
626-
{
627642
ability.RemoveAbility(player);
628-
}
629643
}
630644

631-
RoleRemoved(player);
645+
RoleRemoved(player, spawnReason, roleSpawnFlags);
632646
player.UniqueRole = string.Empty;
633647
player.TryRemoveCustomeRoleFriendlyFire(Name);
634648

635649
if (RemovalKillsPlayer)
636-
player.Role.Set(RoleTypeId.Spectator);
650+
player.Role.Set(RoleTypeId.Spectator, spawnReason, roleSpawnFlags);
637651
}
638652

639653
/// <summary>
640654
/// Tries to add <see cref="RoleTypeId"/> to CustomRole FriendlyFire rules.
641655
/// </summary>
642656
/// <param name="roleToAdd"> Role to add. </param>
643657
/// <param name="ffMult"> Friendly fire multiplier. </param>
644-
public void SetFriendlyFire(RoleTypeId roleToAdd, float ffMult)
645-
{
646-
if (CustomRoleFFMultiplier.ContainsKey(roleToAdd))
647-
{
648-
CustomRoleFFMultiplier[roleToAdd] = ffMult;
649-
}
650-
else
651-
{
652-
CustomRoleFFMultiplier.Add(roleToAdd, ffMult);
653-
}
654-
}
658+
public void SetFriendlyFire(RoleTypeId roleToAdd, float ffMult) => CustomRoleFFMultiplier[roleToAdd] = ffMult;
655659

656660
/// <summary>
657661
/// Wrapper to call <see cref="SetFriendlyFire(RoleTypeId, float)"/>.
658662
/// </summary>
659663
/// <param name="roleFF"> Role with FF to add even if it exists. </param>
660-
public void SetFriendlyFire(KeyValuePair<RoleTypeId, float> roleFF)
661-
{
662-
SetFriendlyFire(roleFF.Key, roleFF.Value);
663-
}
664+
public void SetFriendlyFire(KeyValuePair<RoleTypeId, float> roleFF) => SetFriendlyFire(roleFF.Key, roleFF.Value);
664665

665666
/// <summary>
666667
/// Tries to add <see cref="RoleTypeId"/> to CustomRole FriendlyFire rules.
@@ -671,9 +672,7 @@ public void SetFriendlyFire(KeyValuePair<RoleTypeId, float> roleFF)
671672
public bool TryAddFriendlyFire(RoleTypeId roleToAdd, float ffMult)
672673
{
673674
if (CustomRoleFFMultiplier.ContainsKey(roleToAdd))
674-
{
675675
return false;
676-
}
677676

678677
CustomRoleFFMultiplier.Add(roleToAdd, ffMult);
679678
return true;
@@ -719,9 +718,7 @@ public bool TryAddFriendlyFire(Dictionary<RoleTypeId, float> ffRules, bool overw
719718
if (!overwrite)
720719
{
721720
foreach (KeyValuePair<RoleTypeId, float> roleFF in temporaryFriendlyFireRules)
722-
{
723721
TryAddFriendlyFire(roleFF);
724-
}
725722
}
726723

727724
DictionaryPool<RoleTypeId, float>.Pool.Return(temporaryFriendlyFireRules);
@@ -898,12 +895,30 @@ protected virtual void UnsubscribeEvents()
898895
/// Shows the spawn broadcast to the player.
899896
/// </summary>
900897
/// <param name="player">The <see cref="Player"/> to show the message to.</param>
901-
protected virtual void ShowBroadcast(Player player) => player.Broadcast(Broadcast);
898+
protected virtual void ShowBroadcast(Player player)
899+
{
900+
if (Broadcast != null && Broadcast.Duration > 0 && !string.IsNullOrEmpty(Broadcast.Content))
901+
player.Broadcast(Broadcast);
902+
}
903+
904+
/// <summary>
905+
/// Called after the role has been added to the player.
906+
/// </summary>
907+
/// <param name="player">The <see cref="Player"/> the role was added to.</param>
908+
/// <param name="spawnReason">The <see cref="SpawnReason"/>.</param>
909+
/// <param name="roleSpawnFlags">The <see cref="RoleSpawnFlags"/> to apply.</param>
910+
protected virtual void RoleAdded(Player player, SpawnReason spawnReason, RoleSpawnFlags roleSpawnFlags)
911+
{
912+
#pragma warning disable CS0618
913+
RoleAdded(player);
914+
#pragma warning restore CS0618
915+
}
902916

903917
/// <summary>
904918
/// Called after the role has been added to the player.
905919
/// </summary>
906920
/// <param name="player">The <see cref="Player"/> the role was added to.</param>
921+
[Obsolete("Use RoleAdded(Player, SpawnReason, RoleSpawnFlags) instead.")]
907922
protected virtual void RoleAdded(Player player)
908923
{
909924
}
@@ -912,6 +927,20 @@ protected virtual void RoleAdded(Player player)
912927
/// Called 1 frame before the role is removed from the player.
913928
/// </summary>
914929
/// <param name="player">The <see cref="Player"/> the role was removed from.</param>
930+
/// <param name="spawnReason">The <see cref="SpawnReason"/>.</param>
931+
/// <param name="roleSpawnFlags">The <see cref="RoleSpawnFlags"/> to apply.</param>
932+
protected virtual void RoleRemoved(Player player, SpawnReason spawnReason, RoleSpawnFlags roleSpawnFlags)
933+
{
934+
#pragma warning disable CS0618
935+
RoleRemoved(player);
936+
#pragma warning restore CS0618
937+
}
938+
939+
/// <summary>
940+
/// Called 1 frame before the role is removed from the player.
941+
/// </summary>
942+
/// <param name="player">The <see cref="Player"/> the role was removed from.</param>
943+
[Obsolete("Use RoleRemoved(Player, SpawnReason, RoleSpawnFlags) instead.")]
915944
protected virtual void RoleRemoved(Player player)
916945
{
917946
}
@@ -925,13 +954,13 @@ private void OnInternalChangingNickname(ChangingNicknameEventArgs ev)
925954
private void OnInternalSpawned(SpawnedEventArgs ev)
926955
{
927956
if (!IgnoreSpawnSystem && SpawnChance > 0 && !Check(ev.Player) && ev.Player.Role.Type == Role && Loader.Random.NextDouble() * 100 <= SpawnChance)
928-
AddRole(ev.Player);
957+
AddRole(ev.Player, ev.Reason, false);
929958
}
930959

931960
private void OnInternalChangingRole(ChangingRoleEventArgs ev)
932961
{
933962
if (ev.IsAllowed && ev.Reason != SpawnReason.Destroyed && Check(ev.Player) && ((ev.NewRole == RoleTypeId.Spectator && !KeepRoleOnDeath) || (ev.NewRole != RoleTypeId.Spectator && !KeepRoleOnChangingRole)))
934-
RemoveRole(ev.Player);
963+
RemoveRole(ev.Player, ev.Reason, ev.SpawnFlags);
935964
}
936965

937966
private void OnSpawningRagdoll(SpawningRagdollEventArgs ev)
@@ -942,4 +971,4 @@ private void OnSpawningRagdoll(SpawningRagdollEventArgs ev)
942971

943972
private void OnDestroying(DestroyingEventArgs ev) => RemoveRole(ev.Player);
944973
}
945-
}
974+
}

0 commit comments

Comments
 (0)