diff --git a/EXILED/Exiled.API/Features/Player.cs b/EXILED/Exiled.API/Features/Player.cs index 6a46c5004..8f21dd68d 100644 --- a/EXILED/Exiled.API/Features/Player.cs +++ b/EXILED/Exiled.API/Features/Player.cs @@ -1941,7 +1941,21 @@ public void TrySetCustomRoleFriendlyFire(string roleTypeId, Dictionary /// - public void SetAppearance(Func generator) => FakeRoleGenerator.Add(generator); + public void SetAppearance(Func generator) + { + FakeRoleGenerator.Add(generator); + + foreach (Player viewer in Enumerable) + { + RoleData data = generator(viewer); + + if (data.Role == RoleTypeId.None) + continue; + + if (viewer != this || data.DataAuthority.HasFlag(RoleData.Authority.AffectSelf)) + FakeRoles[viewer] = data; + } + } /// /// Fakes this players role to other viewers. @@ -1950,7 +1964,7 @@ public void TrySetCustomRoleFriendlyFire(string roleTypeId, DictionaryThe fake role. /// How to handle edge cases. /// The Unit ID of the player, if is an NTF role. - public void SetAppearance(IEnumerable viewers, RoleTypeId fakeRole, RoleData.Authority authority = RoleData.Authority.None, byte unitId = 0) + public void SetAppearance(IEnumerable viewers, RoleTypeId fakeRole, RoleData.Authority authority = RoleData.Authority.None, byte? unitId = null) { foreach (Player player in viewers) { @@ -1965,7 +1979,7 @@ public void SetAppearance(IEnumerable viewers, RoleTypeId fakeRole, Role /// The fake role. /// How to handle edge cases. /// The Unit ID of the player, if is an NTF role. - public void SetAppearance(Player player, RoleTypeId fakeRole, RoleData.Authority authority = RoleData.Authority.None, byte unitId = 0) + public void SetAppearance(Player player, RoleTypeId fakeRole, RoleData.Authority authority = RoleData.Authority.None, byte? unitId = null) => FakeRoles[player] = new RoleData(fakeRole, authority, unitId); /// diff --git a/EXILED/Exiled.API/Features/Plugin.cs b/EXILED/Exiled.API/Features/Plugin.cs index cebeab971..bcbbcf723 100644 --- a/EXILED/Exiled.API/Features/Plugin.cs +++ b/EXILED/Exiled.API/Features/Plugin.cs @@ -151,7 +151,7 @@ public virtual void OnRegisteringCommands() { if (e.Message.StartsWith("An")) { - Log.Error($"Command with same name has already registered! Command: {command.Command}"); + Log.Error($"Command with same name has already registered! Command: {command.Command}. Type: {command.GetType().FullName}"); } else { diff --git a/EXILED/Exiled.API/Structs/RoleData.cs b/EXILED/Exiled.API/Structs/RoleData.cs index 043fe219a..4b802cf18 100644 --- a/EXILED/Exiled.API/Structs/RoleData.cs +++ b/EXILED/Exiled.API/Structs/RoleData.cs @@ -24,7 +24,7 @@ public struct RoleData : IEquatable /// The authority of the role data. /// The fake UnitID, if is an NTF role. /// An action used to write custom data if this role data is used to send a fake role. For 99% of uses, just leave this as null. - public RoleData(RoleTypeId role = RoleTypeId.None, Authority authority = Authority.None, byte unitId = 0, Action customData = null) + public RoleData(RoleTypeId role = RoleTypeId.None, Authority authority = Authority.None, byte? unitId = null, Action customData = null) { Role = role; DataAuthority = authority; @@ -37,7 +37,7 @@ public RoleData(RoleTypeId role = RoleTypeId.None, Authority authority = Authori /// /// Simply having an authority does not make a direct impact. This enum largely exists to constrict possibly /// unwanted behavior, so make sure your RoleData actually does what behavior you want. - /// (I. E. will not make a RoleData affect the viewer UNLESS they are the target). + /// (I. E. will not make a RoleData affect the viewer UNLESS they are the target of an existing RoleData). [Flags] public enum Authority { @@ -86,7 +86,7 @@ public enum Authority /// /// Gets or sets the UnitID of the fake role, if is an NTF role. /// - public byte UnitId { get; set; } + public byte? UnitId { get; set; } /// /// Gets or sets the authority of this instance. see for details. diff --git a/EXILED/Exiled.Events/Events.cs b/EXILED/Exiled.Events/Events.cs index 69e845811..85dcbdda3 100644 --- a/EXILED/Exiled.Events/Events.cs +++ b/EXILED/Exiled.Events/Events.cs @@ -70,7 +70,6 @@ public override void OnEnabled() Handlers.Server.RoundStarted += Handlers.Internal.Round.OnRoundStarted; Handlers.Player.ChangingRole += Handlers.Internal.Round.OnChangingRole; Handlers.Player.Spawned += Handlers.Internal.Round.OnSpawned; - Handlers.Player.Died += Handlers.Internal.Round.OnDied; Handlers.Player.SpawningRagdoll += Handlers.Internal.Round.OnSpawningRagdoll; Handlers.Scp049.ActivatingSense += Handlers.Internal.Round.OnActivatingSense; Handlers.Player.Verified += Handlers.Internal.Round.OnVerified; @@ -125,7 +124,6 @@ public override void OnDisabled() Handlers.Server.RoundStarted -= Handlers.Internal.Round.OnRoundStarted; Handlers.Player.ChangingRole -= Handlers.Internal.Round.OnChangingRole; Handlers.Player.Spawned -= Handlers.Internal.Round.OnSpawned; - Handlers.Player.Died -= Handlers.Internal.Round.OnDied; Handlers.Player.SpawningRagdoll -= Handlers.Internal.Round.OnSpawningRagdoll; Handlers.Scp049.ActivatingSense -= Handlers.Internal.Round.OnActivatingSense; Handlers.Player.Verified -= Handlers.Internal.Round.OnVerified; diff --git a/EXILED/Exiled.Events/Handlers/Internal/Round.cs b/EXILED/Exiled.Events/Handlers/Internal/Round.cs index f2f8970c5..6b687f0de 100644 --- a/EXILED/Exiled.Events/Handlers/Internal/Round.cs +++ b/EXILED/Exiled.Events/Handlers/Internal/Round.cs @@ -110,31 +110,22 @@ public static void OnSpawned(SpawnedEventArgs ev) { foreach (Player viewer in Player.Enumerable.Where(p => !p.IsNPC && !p.IsHost)) { - foreach (Func generator in ev.Player.FakeRoleGenerator) + if (viewer.FakeRoles.TryGetValue(ev.Player, out RoleData existing) && !existing.DataAuthority.HasFlag(RoleData.Authority.Persist)) + viewer.FakeRoles.Remove(ev.Player); + + foreach (Func generator in viewer.FakeRoleGenerator) { - RoleData data = generator(viewer); + RoleData data = generator(ev.Player); if (data.Role == RoleTypeId.None) continue; - if (viewer != ev.Player) - { + if (viewer != ev.Player || data.DataAuthority.HasFlag(RoleData.Authority.AffectSelf)) viewer.FakeRoles[ev.Player] = data; - } } } } - /// - public static void OnDied(DiedEventArgs ev) - { - foreach (Player viewer in Player.Enumerable.Where(p => !p.IsNPC && !p.IsHost)) - { - if (viewer.FakeRoles.TryGetValue(ev.Player, out RoleData data) && !data.DataAuthority.HasFlag(RoleData.Authority.Persist)) - viewer.FakeRoles.Remove(ev.Player); - } - } - /// public static void OnSpawningRagdoll(SpawningRagdollEventArgs ev) { @@ -179,10 +170,8 @@ public static void OnVerified(VerifiedEventArgs ev) if (data.Role == RoleTypeId.None) continue; - if (player != ev.Player) - { + if (player != ev.Player || data.DataAuthority.HasFlag(RoleData.Authority.AffectSelf)) ev.Player.FakeRoles[player] = data; - } } } } @@ -237,8 +226,8 @@ public static RoleTypeId OnRoleSyncEvent(ReferenceHub targetHub, ReferenceHub vi switch (roleBase) { - case PlayerRoles.HumanRole { UsesUnitNames: true } when data.UnitId != 0: - writer.WriteByte(data.UnitId); + case PlayerRoles.HumanRole { UsesUnitNames: true } when data.UnitId.HasValue: + writer.WriteByte(data.UnitId.Value); break; // W stylecop :heart: