From 6049baca00d3141a8a7401bdf4c12d6cefc77cd7 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Thu, 23 Apr 2026 09:28:02 +0200 Subject: [PATCH] Add Shadow --- CustomRoles.cs | 1 + Modules/CustomRolesHelper.cs | 2 + Resources/Lang/en_US.jsonc | 13 ++ Roles/HideAndSeek/Seeker.cs | 2 +- Roles/Standard/Coven/CovenLeader.cs | 2 +- Roles/Standard/Coven/Empress.cs | 2 +- Roles/Standard/Coven/Enchanter.cs | 2 +- Roles/Standard/Coven/Illusionist.cs | 2 +- Roles/Standard/Coven/MoonDancer.cs | 2 +- Roles/Standard/Coven/Poache.cs | 2 +- Roles/Standard/Coven/PotionMaster.cs | 2 +- Roles/Standard/Coven/Reaper.cs | 4 +- Roles/Standard/Coven/Shadow.cs | 202 ++++++++++++++++++ Roles/Standard/Coven/SpellCaster.cs | 2 +- Roles/Standard/Coven/Timelord.cs | 2 +- Roles/Standard/Coven/VoodooMaster.cs | 2 +- .../Crewmate/Investigate/Investigator.cs | 2 +- .../Standard/Crewmate/Investigate/Witness.cs | 2 +- Roles/Standard/Crewmate/Power/CopyCat.cs | 2 +- Roles/Standard/Crewmate/Support/Crusader.cs | 3 +- Roles/Standard/Crewmate/Support/Jailor.cs | 2 +- Roles/Standard/Impostor/Concealing/Penguin.cs | 2 +- Roles/Standard/Impostor/Concealing/Venerer.cs | 12 +- Roles/Standard/Impostor/Killing/Arrogance.cs | 2 +- Roles/Standard/Impostor/Killing/Bomber.cs | 2 +- Roles/Standard/Impostor/Killing/Inhibitor.cs | 2 +- Roles/Standard/Impostor/Killing/Nemesis.cs | 2 +- Roles/Standard/Impostor/Killing/Ninja.cs | 10 +- Roles/Standard/Impostor/Killing/Saboteur.cs | 2 +- Roles/Standard/Impostor/Madmate/Parasite.cs | 2 +- Roles/Standard/Impostor/Madmate/Renegade.cs | 2 +- Roles/Standard/Neutral/Benign/Dealer.cs | 2 +- Roles/Standard/Neutral/Benign/Follower.cs | 6 +- Roles/Standard/Neutral/Benign/Maverick.cs | 2 +- Roles/Standard/Neutral/Benign/Pursuer.cs | 7 +- Roles/Standard/Neutral/Benign/Romantic.cs | 2 +- Roles/Standard/Neutral/Benign/SoulHunter.cs | 2 +- Roles/Standard/Neutral/Evil/Gaslighter.cs | 2 +- Roles/Standard/Neutral/Evil/Innocent.cs | 2 +- Roles/Standard/Neutral/Killing/Virus.cs | 2 +- 40 files changed, 267 insertions(+), 53 deletions(-) create mode 100644 Roles/Standard/Coven/Shadow.cs diff --git a/CustomRoles.cs b/CustomRoles.cs index 397831b22..5a52d7157 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -435,6 +435,7 @@ public enum CustomRoles Poache, PotionMaster, Reaper, + Shadow, Siren, SpellCaster, Summoner, diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index fff67a881..92a6cd163 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -626,6 +626,7 @@ internal static class CustomRolesHelper CustomRoles.Wyrd => RoleTypes.Shapeshifter, CustomRoles.MoonDancer => RoleTypes.Phantom, CustomRoles.Empress => RoleTypes.Phantom, + CustomRoles.Shadow => RoleTypes.Phantom, _ => RoleTypes.GuardianAngel }; @@ -1545,6 +1546,7 @@ internal static class CustomRolesHelper CustomRoles.Wyrd or CustomRoles.Empress or CustomRoles.Summoner or + CustomRoles.Shadow or CustomRoles.MoonDancer; } diff --git a/Resources/Lang/en_US.jsonc b/Resources/Lang/en_US.jsonc index 799ed0fd7..afb1d771c 100644 --- a/Resources/Lang/en_US.jsonc +++ b/Resources/Lang/en_US.jsonc @@ -150,6 +150,7 @@ "Prefix.Dynamo": "Dynamo", "Prefix.Egoist": "Egoist", "Prefix.Energetic": "Energetic", + "Prefix.Entombed": "Entombed", "Prefix.EvilSpirit": "Evil Spirit", "Prefix.Examiner": "Examiner", "Prefix.Facilitator": "Facilitator", @@ -202,6 +203,7 @@ "Prefix.Stressed": "Stressed", "Prefix.Sunglasses": "Sunglasses", "Prefix.Swift": "Swift", + "Prefix.Talkative": "Talkative", "Prefix.TaskMaster": "Task Master", "Prefix.Taskcounter": "Taskcounter", "Prefix.Tiebreaker": "Tiebreaker", @@ -213,6 +215,7 @@ "Prefix.Undead": "Undead", "Prefix.Underdog": "Underdog", "Prefix.Unlucky": "Unlucky", + "Prefix.Urgent": "Urgent", "Prefix.Venom": "Venom", "Prefix.Warden": "Warden", "Prefix.Watcher": "Watcher", @@ -3473,6 +3476,16 @@ "ReaperInfo": "Curse, collect souls, become Death", "ReaperInfoLong": "(Coven):\\nCurse a player; when a cursed player dies, you gain a soul. Upon reaching a specific number of souls (set by the host) (or if you're the last killer alive), you become Death. You cannot have the Necronomicon enhance your powers.", "Reaper.SoulsRequired": "Number of Souls required to transform into Death", + "Shadow": "Shadow", + "ShadowInfo": "Eliminate players from the shadows", + "ShadowInfoLong": "(Coven):\\nVanish to camouflage yourself. You may be able to camouflage your team using your kill button on them. With the Necronomicon, you can kill, and become invisible after doing so. Your camouflaging abilities may be switched to invisibility as well. (With the ability to camouflage your teammates, single click with your kill button to use it, and double click with it to kill normally.)", + "Shadow.SelfCamoCooldown": "Self Camouflage Cooldown", + "Shadow.SelfCamoDuration": "Self Camouflage Duration", + "Shadow.CanCamoOthersWithKillButton": "Can Camouflage Other <#7b3fbb>Coven Members Via Kill Button", + "Shadow.OthersCooldown": "Cooldown For Camouflaging Others", + "Shadow.OthersCamoDuration": "Duration Of Others' Camouflage", + "Shadow.InvisDuration": "Invisibility Duration", + "Shadow.SwitchCamoAbilityToInvisWithNecronomicon": "Switch Camouflaging Ability To Invisibility Upon Gaining The Necronomicon", "Siren": "Siren", "SirenInfo": "Sing to convert with stages", "SirenInfoLong": "(Coven):\\nThe Siren has an entrancing voice. Use the Sing ability (via the Vanish button) to affect nearby players.\\n- On the first hearing, non-Coven players are blinded and slowed for a short time.\\n- On the second, they are again blinded and slowed, and cannot report bodies temporarily.\\n- On the third, they become Entranced, converting to the Coven.\\n\\nWith the Necronomicon, the Siren gains the ability to kill normally, and her Sing is boosted by two stages:\\n- Players who've heard no songs are treated as if they've heard two.\\n- Players who've heard one song are treated as if they've heard three and become Entranced.\\nThe Siren sees a tracker near each player's name showing their current stage (0/3, 1/3, 2/3, Entranced).", diff --git a/Roles/HideAndSeek/Seeker.cs b/Roles/HideAndSeek/Seeker.cs index dac995c2b..616992495 100644 --- a/Roles/HideAndSeek/Seeker.cs +++ b/Roles/HideAndSeek/Seeker.cs @@ -71,7 +71,7 @@ internal class Seeker : RoleBase, IHideAndSeekRole public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) diff --git a/Roles/Standard/Coven/CovenLeader.cs b/Roles/Standard/Coven/CovenLeader.cs index 8f191cd86..c1631a80a 100644 --- a/Roles/Standard/Coven/CovenLeader.cs +++ b/Roles/Standard/Coven/CovenLeader.cs @@ -32,7 +32,7 @@ public class CovenLeader : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Standard/Coven/Empress.cs b/Roles/Standard/Coven/Empress.cs index f65f0db2d..8177d85a8 100644 --- a/Roles/Standard/Coven/Empress.cs +++ b/Roles/Standard/Coven/Empress.cs @@ -85,7 +85,7 @@ public class Empress : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Coven/Enchanter.cs b/Roles/Standard/Coven/Enchanter.cs index f4c42e000..f0422b117 100644 --- a/Roles/Standard/Coven/Enchanter.cs +++ b/Roles/Standard/Coven/Enchanter.cs @@ -46,7 +46,7 @@ public class Enchanter : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Coven/Illusionist.cs b/Roles/Standard/Coven/Illusionist.cs index b2447f2e0..c454bb11c 100644 --- a/Roles/Standard/Coven/Illusionist.cs +++ b/Roles/Standard/Coven/Illusionist.cs @@ -51,7 +51,7 @@ public class Illusionist : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Coven/MoonDancer.cs b/Roles/Standard/Coven/MoonDancer.cs index 92be948d4..0635079e2 100644 --- a/Roles/Standard/Coven/MoonDancer.cs +++ b/Roles/Standard/Coven/MoonDancer.cs @@ -54,7 +54,7 @@ public class MoonDancer : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Standard/Coven/Poache.cs b/Roles/Standard/Coven/Poache.cs index 8ce39297c..1be22f3c3 100644 --- a/Roles/Standard/Coven/Poache.cs +++ b/Roles/Standard/Coven/Poache.cs @@ -52,7 +52,7 @@ public class Poache : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Coven/PotionMaster.cs b/Roles/Standard/Coven/PotionMaster.cs index 79ce3850e..9897db315 100644 --- a/Roles/Standard/Coven/PotionMaster.cs +++ b/Roles/Standard/Coven/PotionMaster.cs @@ -64,7 +64,7 @@ public class PotionMaster : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Coven/Reaper.cs b/Roles/Standard/Coven/Reaper.cs index d02069aef..1b31faaa8 100644 --- a/Roles/Standard/Coven/Reaper.cs +++ b/Roles/Standard/Coven/Reaper.cs @@ -60,7 +60,7 @@ public class Reaper : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) @@ -134,7 +134,7 @@ public class Death : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Coven/Shadow.cs b/Roles/Standard/Coven/Shadow.cs new file mode 100644 index 000000000..17da3815d --- /dev/null +++ b/Roles/Standard/Coven/Shadow.cs @@ -0,0 +1,202 @@ +using AmongUs.GameOptions; +using System.Collections.Generic; +using EHR.Modules.Extensions; + +namespace EHR.Roles; + +public class Shadow : CovenBase +{ + public static bool On; + + private static OptionItem KillCooldown; + private static OptionItem SelfCamoCooldown; + private static OptionItem SelfCamoDuration; + private static OptionItem CanCamoOthersWithKillButton; + private static OptionItem OthersCooldown; + private static OptionItem OthersCamoDuration; + private static OptionItem InvisDuration; + private static OptionItem SwitchCamoAbilityToInvisWithNecronomicon; + private static OptionItem CanVentBeforeNecronomicon; + private static OptionItem CanVentAfterNecronomicon; + + protected override NecronomiconReceivePriorities NecronomiconReceivePriority => NecronomiconReceivePriorities.Random; + + public override bool IsEnable => On; + + private byte ShadowId; + private NetworkedPlayerInfo.PlayerOutfit OriginalOutfit; + private CountdownTimer SelfTimer; + private byte TargetId; + private NetworkedPlayerInfo.PlayerOutfit OriginalTargetOutfit; + private CountdownTimer OthersCamoTimer; + + public override void SetupCustomOption() + { + StartSetup(658700) + .AutoSetupOption(ref KillCooldown, 30f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds) + .AutoSetupOption(ref SelfCamoCooldown, 15f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds) + .AutoSetupOption(ref SelfCamoDuration, 7f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds) + .AutoSetupOption(ref CanCamoOthersWithKillButton, true) + .AutoSetupOption(ref OthersCooldown, 30f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds, overrideParent: CanCamoOthersWithKillButton) + .AutoSetupOption(ref OthersCamoDuration, 7f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds, overrideParent: CanCamoOthersWithKillButton) + .AutoSetupOption(ref InvisDuration, 5f, new FloatValueRule(0.5f, 120f, 0.5f), OptionFormat.Seconds) + .AutoSetupOption(ref SwitchCamoAbilityToInvisWithNecronomicon, true) + .AutoSetupOption(ref CanVentBeforeNecronomicon, false) + .AutoSetupOption(ref CanVentAfterNecronomicon, true); + } + + public override void Init() + { + On = false; + } + + public override void Add(byte playerId) + { + On = true; + ShadowId = playerId; + OriginalOutfit = null; + SelfTimer = null; + TargetId = byte.MaxValue; + OriginalTargetOutfit = null; + OthersCamoTimer = null; + } + + public override void ApplyGameOptions(IGameOptions opt, byte playerId) + { + AURoleOptions.PhantomCooldown = SelfCamoCooldown.GetFloat(); + } + + public override bool CanUseImpostorVentButton(PlayerControl pc) + { + return HasNecronomicon ? CanVentAfterNecronomicon.GetBool() : CanVentBeforeNecronomicon.GetBool(); + } + + public override bool CanUseKillButton(PlayerControl pc) + { + return HasNecronomicon || CanCamoOthersWithKillButton.GetBool(); + } + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = HasNecronomicon switch + { + false when !CanCamoOthersWithKillButton.GetBool() => 300f, + false => OthersCooldown.GetFloat(), + _ => KillCooldown.GetFloat() + }; + } + + public override bool OnVanish(PlayerControl pc) + { + if (SelfTimer != null) return false; + + if (HasNecronomicon && SwitchCamoAbilityToInvisWithNecronomicon.GetBool()) + { + MakeSelfInvisible(pc); + return false; + } + + if (Camouflage.IsCamouflage) return false; + + OriginalOutfit = Camouflage.PlayerSkins[pc.PlayerId]; + Utils.RpcChangeSkin(pc, new NetworkedPlayerInfo.PlayerOutfit().Set(Main.AllPlayerNames.GetValueOrDefault(pc.PlayerId, pc.GetRealName()), 15, "", "", "", "", "")); + Utils.NotifyRoles(SpecifyTarget: pc); + + SelfTimer = new CountdownTimer(SelfCamoDuration.GetFloat(), () => + { + SelfTimer = null; + if (Camouflage.IsCamouflage || !pc) return; + Utils.RpcChangeSkin(pc, OriginalOutfit); + Utils.NotifyRoles(SpecifyTarget: pc); + pc.RpcResetAbilityCooldown(); + }, cancelOnMeeting: false, onCanceled: () => SelfTimer = null); + + return false; + } + + private void MakeSelfInvisible(PlayerControl pc) + { + pc.RpcMakeInvisible(); + SelfTimer = new CountdownTimer(InvisDuration.GetFloat(), () => + { + SelfTimer = null; + if (!pc) return; + pc.RpcMakeVisible(); + pc.RpcResetAbilityCooldown(); + }, onCanceled: () => SelfTimer = null); + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + if (!HasNecronomicon) + { + UseAbility(); + return false; + } + + if (!CanCamoOthersWithKillButton.GetBool() || killer.CheckDoubleTrigger(target, UseAbility)) + { + if (SelfTimer == null) MakeSelfInvisible(killer); + return true; + } + + return false; + + void UseAbility() + { + if (OthersCamoTimer != null || !target.Is(Team.Coven)) return; + + if (HasNecronomicon && SwitchCamoAbilityToInvisWithNecronomicon.GetBool()) + { + target.RpcMakeInvisible(); + OthersCamoTimer = new CountdownTimer(InvisDuration.GetFloat(), () => + { + OthersCamoTimer = null; + if (!target) return; + target.RpcMakeVisible(); + }, onCanceled: () => OthersCamoTimer = null); + return; + } + + if (Camouflage.IsCamouflage) return; + + killer.SetKillCooldown(OthersCooldown.GetFloat()); + + TargetId = target.PlayerId; + OriginalTargetOutfit = Camouflage.PlayerSkins[target.PlayerId]; + Utils.RpcChangeSkin(target, new NetworkedPlayerInfo.PlayerOutfit().Set(Main.AllPlayerNames.GetValueOrDefault(target.PlayerId, target.GetRealName()), 15, "", "", "", "", "")); + Utils.NotifyRoles(SpecifyTarget: target); + + OthersCamoTimer = new CountdownTimer(OthersCamoDuration.GetFloat(), () => + { + OthersCamoTimer = null; + if (Camouflage.IsCamouflage || !target) return; + Utils.RpcChangeSkin(target, OriginalTargetOutfit); + Utils.NotifyRoles(SpecifyTarget: target); + }, cancelOnMeeting: false, onCanceled: () => OthersCamoTimer = null); + } + } + + public override void OnReportDeadBody() + { + if (HasNecronomicon && SwitchCamoAbilityToInvisWithNecronomicon.GetBool()) return; + + if (SelfTimer != null) + { + SelfTimer.Dispose(); + SelfTimer = null; + PlayerControl pc = ShadowId.GetPlayer(); + if (Camouflage.IsCamouflage || !pc) return; + Utils.RpcChangeSkin(pc, OriginalOutfit); + } + + if (OthersCamoTimer != null) + { + OthersCamoTimer.Dispose(); + OthersCamoTimer = null; + PlayerControl pc = TargetId.GetPlayer(); + if (Camouflage.IsCamouflage || !pc) return; + Utils.RpcChangeSkin(pc, OriginalOutfit); + } + } +} \ No newline at end of file diff --git a/Roles/Standard/Coven/SpellCaster.cs b/Roles/Standard/Coven/SpellCaster.cs index c7b651dfa..8508c5f34 100644 --- a/Roles/Standard/Coven/SpellCaster.cs +++ b/Roles/Standard/Coven/SpellCaster.cs @@ -55,7 +55,7 @@ public class SpellCaster : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Coven/Timelord.cs b/Roles/Standard/Coven/Timelord.cs index 089f17b0e..8f035a998 100644 --- a/Roles/Standard/Coven/Timelord.cs +++ b/Roles/Standard/Coven/Timelord.cs @@ -41,7 +41,7 @@ public class Timelord : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Coven/VoodooMaster.cs b/Roles/Standard/Coven/VoodooMaster.cs index 41288b2a6..8ef59f2b2 100644 --- a/Roles/Standard/Coven/VoodooMaster.cs +++ b/Roles/Standard/Coven/VoodooMaster.cs @@ -42,7 +42,7 @@ public class VoodooMaster : CovenBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Crewmate/Investigate/Investigator.cs b/Roles/Standard/Crewmate/Investigate/Investigator.cs index 690631bf1..f522f29e8 100644 --- a/Roles/Standard/Crewmate/Investigate/Investigator.cs +++ b/Roles/Standard/Crewmate/Investigate/Investigator.cs @@ -71,7 +71,7 @@ public class Investigator : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Crewmate/Investigate/Witness.cs b/Roles/Standard/Crewmate/Investigate/Witness.cs index af5731a39..be4c2da9e 100644 --- a/Roles/Standard/Crewmate/Investigate/Witness.cs +++ b/Roles/Standard/Crewmate/Investigate/Witness.cs @@ -54,7 +54,7 @@ internal class Witness : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Crewmate/Power/CopyCat.cs b/Roles/Standard/Crewmate/Power/CopyCat.cs index a23b9af44..c41e5043d 100644 --- a/Roles/Standard/Crewmate/Power/CopyCat.cs +++ b/Roles/Standard/Crewmate/Power/CopyCat.cs @@ -80,7 +80,7 @@ public class CopyCat : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } private void ResetRole() diff --git a/Roles/Standard/Crewmate/Support/Crusader.cs b/Roles/Standard/Crewmate/Support/Crusader.cs index 3b56c7861..5b4027ba9 100644 --- a/Roles/Standard/Crewmate/Support/Crusader.cs +++ b/Roles/Standard/Crewmate/Support/Crusader.cs @@ -53,8 +53,7 @@ public class Crusader : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return !Main.PlayerStates[pc.PlayerId].IsDead - && pc.GetAbilityUseLimit() >= 1; + return pc.GetAbilityUseLimit() >= 1; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Crewmate/Support/Jailor.cs b/Roles/Standard/Crewmate/Support/Jailor.cs index 037cf323a..62054615a 100644 --- a/Roles/Standard/Crewmate/Support/Jailor.cs +++ b/Roles/Standard/Crewmate/Support/Jailor.cs @@ -65,7 +65,7 @@ public class Jailor : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } private static void SendRPC(byte jailerId, byte targetId) diff --git a/Roles/Standard/Impostor/Concealing/Penguin.cs b/Roles/Standard/Impostor/Concealing/Penguin.cs index 119a7a4f6..b92e6ae10 100644 --- a/Roles/Standard/Impostor/Concealing/Penguin.cs +++ b/Roles/Standard/Impostor/Concealing/Penguin.cs @@ -118,7 +118,7 @@ public class Penguin : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool CanUseSabotage(PlayerControl pc) diff --git a/Roles/Standard/Impostor/Concealing/Venerer.cs b/Roles/Standard/Impostor/Concealing/Venerer.cs index 0262758fe..b83598f74 100644 --- a/Roles/Standard/Impostor/Concealing/Venerer.cs +++ b/Roles/Standard/Impostor/Concealing/Venerer.cs @@ -98,7 +98,7 @@ public class Venerer : RoleBase Utils.NotifyRoles(SpecifyTarget: pc); LateTask.New(() => { - if (!ChangedSkin || pc == null || !pc.IsAlive() || Camouflage.IsCamouflage) return; + if (!ChangedSkin || !pc || !pc.IsAlive() || Camouflage.IsCamouflage) return; Utils.RpcChangeSkin(pc, outfit); ChangedSkin = false; Utils.NotifyRoles(SpecifyTarget: pc); @@ -110,7 +110,7 @@ public class Venerer : RoleBase pc.MarkDirtySettings(); LateTask.New(() => { - if (pc == null || !pc.IsAlive()) return; + if (!pc || !pc.IsAlive()) return; Main.AllPlayerSpeed[pc.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod); if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks) pc.MarkDirtySettings(); }, AbilityDuration.GetInt(), log: false); @@ -137,14 +137,14 @@ public class Venerer : RoleBase frozenPlayers.Except(nearbyPlayers).Do(x => { PlayerControl p = Utils.GetPlayerById(x); - if (p == null || !p.IsAlive()) return; + if (!p || !p.IsAlive()) return; Main.AllPlayerSpeed[p.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod); p.MarkDirtySettings(); }); nearbyPlayers.Except(frozenPlayers).Do(x => { PlayerControl p = Utils.GetPlayerById(x); - if (p == null || !p.IsAlive()) return; + if (!p || !p.IsAlive()) return; Main.AllPlayerSpeed[p.PlayerId] = DecreasedSpeed.GetFloat(); p.MarkDirtySettings(); }); @@ -157,7 +157,7 @@ public class Venerer : RoleBase frozenPlayers.Do(x => { PlayerControl p = Utils.GetPlayerById(x); - if (p == null || !p.IsAlive()) return; + if (!p || !p.IsAlive()) return; Main.AllPlayerSpeed[p.PlayerId] = Main.RealOptionsData.GetFloat(FloatOptionNames.PlayerSpeedMod); if (GameStates.IsInTask && !ExileController.Instance && !AntiBlackout.SkipTasks) p.MarkDirtySettings(); }); @@ -171,7 +171,7 @@ public class Venerer : RoleBase { ChangedSkin = false; PlayerControl pc = VenererId.GetPlayer(); - if (pc == null || !pc.IsAlive()) return; + if (!pc || !pc.IsAlive()) return; Utils.RpcChangeSkin(pc, Camouflage.PlayerSkins[VenererId]); } } diff --git a/Roles/Standard/Impostor/Killing/Arrogance.cs b/Roles/Standard/Impostor/Killing/Arrogance.cs index e2736179e..4f9d38454 100644 --- a/Roles/Standard/Impostor/Killing/Arrogance.cs +++ b/Roles/Standard/Impostor/Killing/Arrogance.cs @@ -126,7 +126,7 @@ public class Arrogance : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void OnMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Impostor/Killing/Bomber.cs b/Roles/Standard/Impostor/Killing/Bomber.cs index 36402c6e2..3eab4ca27 100644 --- a/Roles/Standard/Impostor/Killing/Bomber.cs +++ b/Roles/Standard/Impostor/Killing/Bomber.cs @@ -77,7 +77,7 @@ internal class Bomber : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return base.CanUseKillButton(pc) && !IsNuker && BomberCanKill.GetBool(); + return !IsNuker && BomberCanKill.GetBool(); } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Impostor/Killing/Inhibitor.cs b/Roles/Standard/Impostor/Killing/Inhibitor.cs index fec12ebfc..83e036dd9 100644 --- a/Roles/Standard/Impostor/Killing/Inhibitor.cs +++ b/Roles/Standard/Impostor/Killing/Inhibitor.cs @@ -50,7 +50,7 @@ internal class Inhibitor : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return base.CanUseKillButton(pc) && !Utils.IsAnySabotageActive(); + return !Utils.IsAnySabotageActive(); } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Impostor/Killing/Nemesis.cs b/Roles/Standard/Impostor/Killing/Nemesis.cs index ec6f27d55..d13cfcb0b 100644 --- a/Roles/Standard/Impostor/Killing/Nemesis.cs +++ b/Roles/Standard/Impostor/Killing/Nemesis.cs @@ -49,7 +49,7 @@ internal class Nemesis : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Standard/Impostor/Killing/Ninja.cs b/Roles/Standard/Impostor/Killing/Ninja.cs index e21dfc92b..3fe4b4298 100644 --- a/Roles/Standard/Impostor/Killing/Ninja.cs +++ b/Roles/Standard/Impostor/Killing/Ninja.cs @@ -117,13 +117,13 @@ internal class Ninja : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - if (pc == null || !pc.IsAlive()) return false; + if (!pc || !pc.IsAlive()) return false; return CanKillAfterAssassinate || (!pc.IsShifted() && (pc.Data.Role as PhantomRole) is null or { IsInvisible: false }); } public override void AfterMeetingTasks() { - if (MarkedPlayer != byte.MaxValue && MarkedPlayer.GetPlayer() == null) + if (MarkedPlayer != byte.MaxValue && !MarkedPlayer.GetPlayer()) { MarkedPlayer = byte.MaxValue; SendRPC(NinjaId); @@ -185,14 +185,14 @@ internal class Ninja : RoleBase public override bool OnVanish(PlayerControl pc) { - if (pc == null || !pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) return false; + if (!pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) return false; if (!IsUndertaker) { float time = InvisibilityTimeAfterAssassinateOpt.GetFloat(); PlayerControl target = Utils.GetPlayerById(MarkedPlayer); - if (time >= 1f && target != null && target.IsAlive() && !Pelican.IsEaten(target.PlayerId) && !target.inVent && pc.RpcCheckAndMurder(target, check: true)) + if (time >= 1f && target && target.IsAlive() && !Pelican.IsEaten(target.PlayerId) && !target.inVent && pc.RpcCheckAndMurder(target, check: true)) { pc.RpcMakeInvisible(phantom: true); @@ -239,7 +239,7 @@ internal class Ninja : RoleBase PlayerControl target = Utils.GetPlayerById(MarkedPlayer); bool tpSuccess = IsUndertaker ? target.TP(pc) : pc.TP(target); - if (!(target == null || !target.IsAlive() || Pelican.IsEaten(target.PlayerId) || target.inVent || !GameStates.IsInTask) && tpSuccess && pc.RpcCheckAndMurder(target)) + if (!(!target || !target.IsAlive() || Pelican.IsEaten(target.PlayerId) || target.inVent || !GameStates.IsInTask) && tpSuccess && pc.RpcCheckAndMurder(target)) { MarkedPlayer = byte.MaxValue; SendRPC(pc.PlayerId); diff --git a/Roles/Standard/Impostor/Killing/Saboteur.cs b/Roles/Standard/Impostor/Killing/Saboteur.cs index 6e3451e47..475e2ae11 100644 --- a/Roles/Standard/Impostor/Killing/Saboteur.cs +++ b/Roles/Standard/Impostor/Killing/Saboteur.cs @@ -37,7 +37,7 @@ internal class Saboteur : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return base.CanUseKillButton(pc) && Utils.IsAnySabotageActive(); + return Utils.IsAnySabotageActive(); } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Impostor/Madmate/Parasite.cs b/Roles/Standard/Impostor/Madmate/Parasite.cs index 2cb9366f7..629ebfbf6 100644 --- a/Roles/Standard/Impostor/Madmate/Parasite.cs +++ b/Roles/Standard/Impostor/Madmate/Parasite.cs @@ -58,7 +58,7 @@ internal class Parasite : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) diff --git a/Roles/Standard/Impostor/Madmate/Renegade.cs b/Roles/Standard/Impostor/Madmate/Renegade.cs index 611184d79..06e0d6fc0 100644 --- a/Roles/Standard/Impostor/Madmate/Renegade.cs +++ b/Roles/Standard/Impostor/Madmate/Renegade.cs @@ -31,6 +31,6 @@ internal class Renegade : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } } \ No newline at end of file diff --git a/Roles/Standard/Neutral/Benign/Dealer.cs b/Roles/Standard/Neutral/Benign/Dealer.cs index 0fbb1524d..cf352d2ce 100644 --- a/Roles/Standard/Neutral/Benign/Dealer.cs +++ b/Roles/Standard/Neutral/Benign/Dealer.cs @@ -51,7 +51,7 @@ public class Dealer : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Neutral/Benign/Follower.cs b/Roles/Standard/Neutral/Benign/Follower.cs index b6e6554d7..80cd97a20 100644 --- a/Roles/Standard/Neutral/Benign/Follower.cs +++ b/Roles/Standard/Neutral/Benign/Follower.cs @@ -131,7 +131,7 @@ public class Follower : RoleBase BetTimes--; PlayerControl betPlayer = Utils.GetPlayerById(BetPlayer); - if (betPlayer != null) + if (betPlayer) { Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: betPlayer, ForceLoop: true); Utils.NotifyRoles(SpecifySeer: betPlayer, SpecifyTarget: killer, ForceLoop: true); @@ -172,9 +172,7 @@ public class Follower : RoleBase public override string GetProgressText(byte playerId, bool comms) { PlayerControl player = Utils.GetPlayerById(playerId); - if (Main.PlayerStates[playerId].Role is not Follower tc) return string.Empty; - - return player == null ? string.Empty : Utils.ColorString(tc.CanUseKillButton(player) ? Utils.GetRoleColor(CustomRoles.Follower) : Color.gray, $"({tc.BetTimes})"); + return !player ? string.Empty : Utils.ColorString(CanUseKillButton(player) ? Utils.GetRoleColor(CustomRoles.Follower) : Color.gray, $"({BetTimes})"); } public override void SetButtonTexts(HudManager hud, byte id) diff --git a/Roles/Standard/Neutral/Benign/Maverick.cs b/Roles/Standard/Neutral/Benign/Maverick.cs index c8d046396..9dd810a06 100644 --- a/Roles/Standard/Neutral/Benign/Maverick.cs +++ b/Roles/Standard/Neutral/Benign/Maverick.cs @@ -67,7 +67,7 @@ public class Maverick : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool CanUseSabotage(PlayerControl pc) diff --git a/Roles/Standard/Neutral/Benign/Pursuer.cs b/Roles/Standard/Neutral/Benign/Pursuer.cs index daa67bb70..58ae44b83 100644 --- a/Roles/Standard/Neutral/Benign/Pursuer.cs +++ b/Roles/Standard/Neutral/Benign/Pursuer.cs @@ -50,8 +50,7 @@ public class Pursuer : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return !Main.PlayerStates[pc.PlayerId].IsDead - && pc.GetAbilityUseLimit() >= 1; + return pc.GetAbilityUseLimit() >= 1; } public override void SetKillCooldown(byte id) @@ -61,7 +60,7 @@ public class Pursuer : RoleBase private bool CanBeClient(PlayerControl pc) { - return pc != null && pc.IsAlive() && !GameStates.IsMeeting && !clientList.Contains(pc.PlayerId); + return pc && pc.IsAlive() && !GameStates.IsMeeting && !clientList.Contains(pc.PlayerId); } private static bool CanSeel(byte playerId) @@ -78,7 +77,7 @@ public class Pursuer : RoleBase private void SeelToClient(PlayerControl pc, PlayerControl target) { - if (pc == null || target == null || !pc.Is(CustomRoles.Pursuer)) return; + if (!pc || !target || !pc.Is(CustomRoles.Pursuer)) return; pc.RpcRemoveAbilityUse(); clientList.Add(target.PlayerId); diff --git a/Roles/Standard/Neutral/Benign/Romantic.cs b/Roles/Standard/Neutral/Benign/Romantic.cs index 063bd3c22..5af6d4d68 100644 --- a/Roles/Standard/Neutral/Benign/Romantic.cs +++ b/Roles/Standard/Neutral/Benign/Romantic.cs @@ -258,7 +258,7 @@ public class Romantic : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } private static void ChangeRole() diff --git a/Roles/Standard/Neutral/Benign/SoulHunter.cs b/Roles/Standard/Neutral/Benign/SoulHunter.cs index c21092d0f..f71021776 100644 --- a/Roles/Standard/Neutral/Benign/SoulHunter.cs +++ b/Roles/Standard/Neutral/Benign/SoulHunter.cs @@ -92,7 +92,7 @@ internal class SoulHunter : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public static bool IsSoulHunterTarget(byte id) diff --git a/Roles/Standard/Neutral/Evil/Gaslighter.cs b/Roles/Standard/Neutral/Evil/Gaslighter.cs index b5729f157..21f4f028e 100644 --- a/Roles/Standard/Neutral/Evil/Gaslighter.cs +++ b/Roles/Standard/Neutral/Evil/Gaslighter.cs @@ -64,7 +64,7 @@ public class Gaslighter : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void SetKillCooldown(byte id) diff --git a/Roles/Standard/Neutral/Evil/Innocent.cs b/Roles/Standard/Neutral/Evil/Innocent.cs index e9aff4e2c..e695817e6 100644 --- a/Roles/Standard/Neutral/Evil/Innocent.cs +++ b/Roles/Standard/Neutral/Evil/Innocent.cs @@ -50,7 +50,7 @@ internal class Innocent : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) diff --git a/Roles/Standard/Neutral/Killing/Virus.cs b/Roles/Standard/Neutral/Killing/Virus.cs index 8bd2df5bd..2777b279f 100644 --- a/Roles/Standard/Neutral/Killing/Virus.cs +++ b/Roles/Standard/Neutral/Killing/Virus.cs @@ -101,7 +101,7 @@ public class Virus : RoleBase public override bool CanUseKillButton(PlayerControl pc) { - return pc.IsAlive(); + return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId)