diff --git a/CTA/CustomTeamAssigner/CustomRoles.cs b/CTA/CustomTeamAssigner/CustomRoles.cs index 013df0587..82babeba9 100644 --- a/CTA/CustomTeamAssigner/CustomRoles.cs +++ b/CTA/CustomTeamAssigner/CustomRoles.cs @@ -66,7 +66,7 @@ public enum CustomRoles Gangster, Generator, Godfather, - Greedier, + Greedy, Hangman, Hitman, Hypnotist, @@ -184,7 +184,6 @@ public enum CustomRoles DonutDelivery, Doorjammer, DoubleAgent, - DovesOfNeace, Drainer, Druid, Electric, @@ -213,7 +212,7 @@ public enum CustomRoles Jailor, Journalist, Judge, - LazyGuy, + LazyGuy, // Needy Leery, Lighter, Lookout, @@ -239,6 +238,7 @@ public enum CustomRoles Observer, Oracle, Oxyman, + Pacifist, // DovesOfNeace Paranoid, Perceiver, PortalMaker, @@ -495,7 +495,7 @@ public enum CustomRoles AntiTP, Asthmatic, Autopsy, - Avanger, + Avenger, Bait, BananaMan, Beartrap, diff --git a/CTA/CustomTeamAssigner/Utils.cs b/CTA/CustomTeamAssigner/Utils.cs index 6ff2d3861..de8820d2c 100644 --- a/CTA/CustomTeamAssigner/Utils.cs +++ b/CTA/CustomTeamAssigner/Utils.cs @@ -25,10 +25,10 @@ namespace CustomTeamAssigner { { CustomRoles.LovingCrewmate, "Lover" }, { CustomRoles.LovingImpostor, "Loving Impostor" }, - { CustomRoles.Divinator, "Fortune Teller" }, - { CustomRoles.Needy, "Lazy Guy" }, + { CustomRoles.FortuneTeller, "Fortune Teller" }, + { CustomRoles.LazyGuy, "Lazy Guy" }, { CustomRoles.ToiletMaster, "Toilet Master" }, - { CustomRoles.Mediumshiper, "Medium" }, + { CustomRoles.Medium, "Medium" }, { CustomRoles.PlagueDoctor, "Infection"} }; diff --git a/CustomRoles.cs b/CustomRoles.cs index 013df0587..8c57ef695 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -53,7 +53,7 @@ public enum CustomRoles Dazzler, Echo, Escapist, - Eraser, + EvilEraser, EvilGuesser, EvilTracker, Exclusionary, @@ -66,7 +66,7 @@ public enum CustomRoles Gangster, Generator, Godfather, - Greedier, + Greedy, Hangman, Hitman, Hypnotist, @@ -176,6 +176,7 @@ public enum CustomRoles Coroner, Crusader, Dad, + Decryptor, Demolitionist, Deputy, Detour, @@ -184,7 +185,6 @@ public enum CustomRoles DonutDelivery, Doorjammer, DoubleAgent, - DovesOfNeace, Drainer, Druid, Electric, @@ -219,7 +219,6 @@ public enum CustomRoles Lookout, LovingCrewmate, Luckey, - Decryptor, Markseeker, Marshall, Mathematician, @@ -239,6 +238,7 @@ public enum CustomRoles Observer, Oracle, Oxyman, + Pacifist, Paranoid, Perceiver, PortalMaker, @@ -335,7 +335,6 @@ public enum CustomRoles Lawyer, Magician, Magistrate, - Vector, Maverick, Medusa, Mycologist, @@ -392,6 +391,7 @@ public enum CustomRoles Tiger, Traitor, Tremor, + Vector, Vengeance, VengefulRomantic, Virus, @@ -495,7 +495,7 @@ public enum CustomRoles AntiTP, Asthmatic, Autopsy, - Avanger, + Avenger, Bait, BananaMan, Beartrap, diff --git a/Main.cs b/Main.cs index 57c06c7b5..718b5019d 100644 --- a/Main.cs +++ b/Main.cs @@ -491,7 +491,7 @@ public class Main : BasePlugin { CustomRoles.Mortician, "#333c49" }, { CustomRoles.Medium, "#a200ff" }, { CustomRoles.Observer, "#a8e0fa" }, - { CustomRoles.DovesOfNeace, "#ffffff" }, + { CustomRoles.Pacifist, "#ffffff" }, { CustomRoles.Jailor, "#aa900d" }, { CustomRoles.Monarch, "#FFA500" }, { CustomRoles.Coroner, "#8B0000" }, @@ -710,7 +710,7 @@ public class Main : BasePlugin { CustomRoles.Undead, "#ed9abd" }, { CustomRoles.Cleansed, "#98FF98" }, { CustomRoles.Fool, "#e6e7ff" }, - { CustomRoles.Avanger, "#ffab1c" }, + { CustomRoles.Avenger, "#ffab1c" }, { CustomRoles.Youtuber, "#fb749b" }, { CustomRoles.Egoist, "#5600ff" }, { CustomRoles.Stealer, "#ff1919" }, diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 438e79e58..10061e19a 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -86,7 +86,7 @@ internal static class CustomRolesHelper CustomRoles.Chameleon => new Swooper(), CustomRoles.BloodKnight => new Wildling(), CustomRoles.HexMaster => new Witch(), - CustomRoles.Pulse => new Greedier(), + CustomRoles.Pulse => new Greedy(), CustomRoles.Jinx => new CursedWolf(), CustomRoles.Juggernaut => new Arrogance(), CustomRoles.Medusa => new Cleaner(), @@ -321,7 +321,7 @@ internal static class CustomRolesHelper CustomRoles.FortuneTeller => CustomRoles.Crewmate, CustomRoles.Oracle => CustomRoles.Crewmate, CustomRoles.Lightning => CustomRoles.Impostor, - CustomRoles.Greedier => CustomRoles.Impostor, + CustomRoles.Greedy => CustomRoles.Impostor, CustomRoles.Workaholic => CustomRoles.Engineer, CustomRoles.Amnesiac => Amnesiac.CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate, CustomRoles.Speedrunner => CustomRoles.Crewmate, @@ -331,7 +331,7 @@ internal static class CustomRolesHelper CustomRoles.SchrodingersCat => CustomRoles.Crewmate, CustomRoles.SoulCatcher => CustomRoles.Shapeshifter, CustomRoles.QuickShooter => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter, - CustomRoles.Eraser => CustomRoles.Impostor, + CustomRoles.EvilEraser => CustomRoles.Impostor, CustomRoles.Butcher => CustomRoles.Impostor, CustomRoles.Hangman => CustomRoles.Shapeshifter, CustomRoles.Sunnyboy => CustomRoles.Scientist, @@ -347,7 +347,7 @@ internal static class CustomRolesHelper CustomRoles.Cherokious => CustomRoles.Engineer, CustomRoles.Pawn => CustomRoles.Crewmate, CustomRoles.Observer => CustomRoles.Crewmate, - CustomRoles.DovesOfNeace => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer, + CustomRoles.Pacifist => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer, CustomRoles.Disperser => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter, CustomRoles.Camouflager => CustomRoles.Shapeshifter, CustomRoles.Dazzler => CustomRoles.Shapeshifter, @@ -796,11 +796,11 @@ internal static class CustomRolesHelper CustomRoles.Gangster or CustomRoles.Cleaner or CustomRoles.Lightning or - CustomRoles.Greedier or + CustomRoles.Greedy or CustomRoles.CursedWolf or CustomRoles.SoulCatcher or CustomRoles.QuickShooter or - CustomRoles.Eraser or + CustomRoles.EvilEraser or CustomRoles.Butcher or CustomRoles.Hangman or CustomRoles.Bard or @@ -916,7 +916,7 @@ internal static class CustomRolesHelper CustomRoles.FortuneTeller when FortuneTeller.CancelVote.GetBool() => true, CustomRoles.Soothsayer when Soothsayer.CancelVote.GetBool() => true, CustomRoles.Oracle when Oracle.CancelVote.GetBool() => true, - CustomRoles.Eraser when Eraser.CancelVote.GetBool() => true, + CustomRoles.EvilEraser when EvilEraser.CancelVote.GetBool() => true, CustomRoles.Tether when Tether.CancelVote.GetBool() => true, CustomRoles.Ricochet when Ricochet.CancelVote.GetBool() => true, CustomRoles.Cleanser when Cleanser.CancelVote.GetBool() => true, @@ -1286,7 +1286,7 @@ internal static class CustomRolesHelper { CustomRoles.Bomber when !Bomber.BomberCanKill.GetBool() => true, CustomRoles.Changeling when !Changeling.CanKillBeforeRoleChange.GetBool() => true, - CustomRoles.Eraser when Eraser.EraseMethod.GetValue() == 0 => true, + CustomRoles.EvilEraser when EvilEraser.EraseMethod.GetValue() == 0 => true, CustomRoles.Puppeteer when !Puppeteer.PuppeteerCanKillNormally.GetBool() => true, CustomRoles.Silencer when Silencer.SilenceMode.GetValue() == 0 => true, CustomRoles.Sniper when !Sniper.CanKillWithBullets.GetBool() => true, @@ -1635,7 +1635,7 @@ internal static class CustomRolesHelper CustomRoles.Councillor => RoleOptionType.Impostor_Killing, CustomRoles.EvilGuesser => RoleOptionType.Impostor_Killing, CustomRoles.Fireworker => RoleOptionType.Impostor_Killing, - CustomRoles.Greedier => RoleOptionType.Impostor_Killing, + CustomRoles.Greedy => RoleOptionType.Impostor_Killing, CustomRoles.Hitman => RoleOptionType.Impostor_Killing, CustomRoles.Inhibitor => RoleOptionType.Impostor_Killing, CustomRoles.Kamikaze => RoleOptionType.Impostor_Killing, @@ -1672,7 +1672,7 @@ internal static class CustomRolesHelper CustomRoles.Devourer => RoleOptionType.Impostor_Support, CustomRoles.Disperser => RoleOptionType.Impostor_Support, CustomRoles.Dazzler => RoleOptionType.Impostor_Support, - CustomRoles.Eraser => RoleOptionType.Impostor_Support, + CustomRoles.EvilEraser => RoleOptionType.Impostor_Support, CustomRoles.Freezer => RoleOptionType.Impostor_Support, CustomRoles.Gangster => RoleOptionType.Impostor_Support, CustomRoles.Godfather => RoleOptionType.Impostor_Support, @@ -1835,7 +1835,7 @@ internal static class CustomRolesHelper CustomRoles.Deputy => RoleOptionType.Crewmate_Support, CustomRoles.DonutDelivery => RoleOptionType.Crewmate_Support, CustomRoles.Doorjammer => RoleOptionType.Crewmate_Support, - CustomRoles.DovesOfNeace => RoleOptionType.Crewmate_Support, + CustomRoles.Pacifist => RoleOptionType.Crewmate_Support, CustomRoles.Electric => RoleOptionType.Crewmate_Support, CustomRoles.Escort => RoleOptionType.Crewmate_Support, CustomRoles.Farmer => RoleOptionType.Crewmate_Support, diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index 7609c9f7b..72c1cf22b 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -319,7 +319,7 @@ public static class GuessManager case CustomRoles.President when Main.PlayerStates[target.PlayerId].Role is President { IsRevealed: true }: ShowMessage("GuessPresident"); return true; - case CustomRoles.Eraser when Eraser.ErasedPlayers.Contains(target.PlayerId) && pc.Is(CustomRoles.Eraser): + case CustomRoles.EvilEraser when EvilEraser.ErasedPlayers.Contains(target.PlayerId) && pc.Is(CustomRoles.EvilEraser): case CustomRoles.NiceEraser when NiceEraser.ErasedPlayers.Contains(target.PlayerId) && pc.Is(CustomRoles.NiceEraser): ShowMessage("GuessErased"); return true; @@ -552,7 +552,7 @@ public static class GuessManager LateTask.New(() => Utils.SendMessage(string.Format(GetString("GuessKill"), Main.AllPlayerNames.GetValueOrDefault(dp.PlayerId, name)), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceGuesser), GetString("GuessKillTitle"))), 0.6f, "Guess Msg"); if (pc.Is(CustomRoles.Doomsayer) && pc.PlayerId != dp.PlayerId) LateTask.New(() => Utils.SendMessage(string.Format(GetString("DoomsayerGuessCountMsg"), Doomsayer.GuessingToWin[pc.PlayerId]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Doomsayer), GetString("DoomsayerGuessCountTitle"))), 0.7f, "Doomsayer Guess Msg 2"); - if (pc.Is(CustomRoles.Stealer) && pc.PlayerId != dp.PlayerId) LateTask.New(() => Utils.SendMessage(string.Format(GetString("StealerGetTicket"), (int)(Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == pc.PlayerId) * Options.VotesPerKill.GetFloat())), pc.PlayerId), 0.7f, log: false); + if (pc.Is(CustomRoles.Stealer) && pc.PlayerId != dp.PlayerId) LateTask.New(() => Utils.SendMessage(string.Format(GetString("StealerGetVote"), (int)(Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == pc.PlayerId) * Options.VotesPerKill.GetFloat())), pc.PlayerId), 0.7f, log: false); if (pc.Is(CustomRoles.Pickpocket) && pc.PlayerId != dp.PlayerId) LateTask.New(() => Utils.SendMessage(string.Format(GetString("PickpocketGetVote"), (int)(Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == pc.PlayerId) * Pickpocket.VotesPerKill.GetFloat())), pc.PlayerId), 0.7f, log: false); }, 0.2f, "Guesser Kill"); diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs index 0bb6128a3..b3c951913 100644 --- a/Modules/OptionHolder.cs +++ b/Modules/OptionHolder.cs @@ -458,8 +458,8 @@ public static class Options public static OptionItem BaitDelayNotify; public static OptionItem TorchVision; public static OptionItem TorchAffectedByLights; - public static OptionItem DovesOfNeaceCooldown; - public static OptionItem DovesOfNeaceMaxOfUseage; + public static OptionItem PacifistCooldown; + public static OptionItem PacifistMaxOfUsage; public static OptionItem killAttacker; public static OptionItem MimicCanSeeDeadRoles; public static OptionItem ResetDoorsEveryTurns; @@ -3477,13 +3477,13 @@ public static class Options public static OptionItem GrenadierAbilityUseGainWithEachTaskCompleted; public static OptionItem LighterAbilityUseGainWithEachTaskCompleted; public static OptionItem SecurityGuardAbilityUseGainWithEachTaskCompleted; - public static OptionItem DovesOfNeaceAbilityUseGainWithEachTaskCompleted; + public static OptionItem PacifistAbilityUseGainWithEachTaskCompleted; // Ability Use Gain every 5 seconds public static OptionItem GrenadierAbilityChargesWhenFinishedTasks; public static OptionItem LighterAbilityChargesWhenFinishedTasks; public static OptionItem SecurityGuardAbilityChargesWhenFinishedTasks; - public static OptionItem DovesOfNeaceAbilityChargesWhenFinishedTasks; + public static OptionItem PacifistAbilityChargesWhenFinishedTasks; public static OptionItem VeteranAbilityChargesWhenFinishedTasks; // ReSharper restore NotAccessedField.Global diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 571971709..d130d3fde 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -111,7 +111,7 @@ public enum CustomRPC SetGhostPlayer, SetStalkerKillCount, SetConsigliere, - SetGreedierOe, + SetGreedyOe, SetCollectorVotes, SetQuickShooterShotLimit, GuessKill, @@ -1024,11 +1024,11 @@ internal static class RPCHandlerPatch Stalker.ReceiveRPC(reader); break; } - case CustomRPC.SetGreedierOe: + case CustomRPC.SetGreedyOe: { byte id = reader.ReadByte(); bool isOdd = reader.ReadBoolean(); - (Main.PlayerStates[id].Role as Greedier)?.ReceiveRPC(isOdd); + (Main.PlayerStates[id].Role as Greedy)?.ReceiveRPC(isOdd); } break; diff --git a/Modules/Statistics.cs b/Modules/Statistics.cs index 5a223902f..5ad2e15c7 100644 --- a/Modules/Statistics.cs +++ b/Modules/Statistics.cs @@ -153,7 +153,7 @@ public static class Statistics switch (CustomWinnerHolder.WinnerTeam) { - case CustomWinner.None when Main.PlayerStates.Values.FindFirst(x => x.SubRoles.Contains(CustomRoles.Avanger), out PlayerState state) && state.GetRealKiller().GetPlayer().Is(CustomRoles.Butcher): + case CustomWinner.None when Main.PlayerStates.Values.FindFirst(x => x.SubRoles.Contains(CustomRoles.Avenger), out PlayerState state) && state.GetRealKiller().GetPlayer().Is(CustomRoles.Butcher): Achievements.Type.FuriousAvenger.CompleteAfterGameEnd(); break; case CustomWinner.Crewmate when won && apc.Count(x => x.IsImpostor() || x.IsNeutralKiller()) >= 2 && MeetingStates.MeetingNum < 3: diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 2a37e63fa..89debaf76 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -3414,7 +3414,7 @@ public static class Utils CustomRoles.TimeMaster => TimeMaster.TimeMasterSkillCooldown.GetInt(), CustomRoles.Perceiver => Perceiver.CD.GetInt(), CustomRoles.Convener => Convener.CD.GetInt(), - CustomRoles.DovesOfNeace => Options.DovesOfNeaceCooldown.GetInt(), + CustomRoles.Pacifist => Options.PacifistCooldown.GetInt(), CustomRoles.Alchemist => Alchemist.VentCooldown.GetInt(), CustomRoles.Hacker => playerId.IsPlayerModdedClient() ? -1 : Hacker.AbilityCD.GetInt(), CustomRoles.CameraMan => CameraMan.VentCooldown.GetInt(), diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index 540787249..13b64426f 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -235,7 +235,7 @@ internal static class ChatCommands new(["tl", "sp", "jj", "trial", "суд", "засудить", "审判", "判", "julgar"], "{id}", GetString("CommandDescription.Trial"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Trial.Id")]), new(["sw", "swap", "st", "свап", "свапнуть", "换票", "trocar"], "{id}", GetString("CommandDescription.Swap"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Swap.Id")]), new(["compare", "cp", "cmp", "сравнить", "ср", "检查", "comparar"], "{id1} {id2}", GetString("CommandDescription.Compare"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Compare.Id1"), GetString("CommandArgs.Compare.Id2")]), - new(["ms", "mediumship", "medium", "медиум", "回答"], "{answer}", GetString("CommandDescription.Medium"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Medium.Answer")]), + new(["ms", "medium", "медиум", "回答"], "{answer}", GetString("CommandDescription.Medium"), Command.UsageLevels.Everyone, Command.UsageTimes.InMeeting, (_, _, _) => { }, true, false, [GetString("CommandArgs.Medium.Answer")]), new(["rv", "месть", "отомстить", "复仇"], "{id}", GetString("CommandDescription.Revenge"), Command.UsageLevels.Everyone, Command.UsageTimes.AfterDeath, (_, _, _) => { }, true, false, [GetString("CommandArgs.Revenge.Id")]) ]; } diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index d8a6272e1..962f580fd 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -709,7 +709,7 @@ internal static class BeginCrewmatePatch CustomRoles.Astral or CustomRoles.Beacon or - CustomRoles.DovesOfNeace or + CustomRoles.Pacifist or CustomRoles.Medium or CustomRoles.Observer or CustomRoles.Spiritcaller or diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index 4695aef6f..bc8557e20 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -167,7 +167,7 @@ internal static class CheckForEndVotingPatch TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.DidntVote, ps.TargetPlayerId); if (CheckRole(ps.TargetPlayerId, CustomRoles.FortuneTeller) && FortuneTeller.HideVote.GetBool()) continue; - if (CheckRole(ps.TargetPlayerId, CustomRoles.Eraser) && Eraser.HideVote.GetBool()) continue; + if (CheckRole(ps.TargetPlayerId, CustomRoles.EvilEraser) && EvilEraser.HideVote.GetBool()) continue; if (CheckRole(ps.TargetPlayerId, CustomRoles.NiceEraser) && NiceEraser.HideVote.GetBool()) continue; if (CheckRole(ps.TargetPlayerId, CustomRoles.Scout) && Scout.HideVote.GetBool()) continue; if (CheckRole(ps.TargetPlayerId, CustomRoles.Oracle) && Oracle.HideVote.GetBool()) continue; @@ -556,7 +556,7 @@ internal static class CheckForEndVotingPatch if (CustomRoles.Lovers.IsEnable() && !Main.IsLoversDead && Main.LoversPlayers.Exists(lp => lp.PlayerId == id)) FixedUpdatePatch.LoversSuicide(playerId, true, true); - if (Main.PlayerStates.TryGetValue(id, out PlayerState state) && state.SubRoles.Contains(CustomRoles.Avanger)) + if (Main.PlayerStates.TryGetValue(id, out PlayerState state) && state.SubRoles.Contains(CustomRoles.Avenger)) RevengeOnExile(playerId /*, deathReason*/); } catch (Exception e) { Utils.ThrowException(e); } diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 265bb05e3..66bdf2b4e 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -735,14 +735,14 @@ internal static class MurderPlayerPatch Speedrun.ResetTimer(killer); if (killer.Is(CustomRoles.Stealer) && killer.PlayerId != target.PlayerId) - killer.Notify(string.Format(GetString("StealerGetTicket"), ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * Options.VotesPerKill.GetFloat()).ToString("0.0#####"))); + killer.Notify(string.Format(GetString("StealerGetVote"), ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * Options.VotesPerKill.GetFloat()).ToString("0.0#####"))); if (killer.Is(CustomRoles.Pickpocket) && killer.PlayerId != target.PlayerId) killer.Notify(string.Format(GetString("PickpocketGetVote"), ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * Pickpocket.VotesPerKill.GetFloat()).ToString("0.0#####"))); if (killer.Is(CustomRoles.Deadlined)) Deadlined.SetDone(killer); - if (target.Is(CustomRoles.Avanger)) + if (target.Is(CustomRoles.Avenger)) { PlayerControl[] pcList = Main.AllAlivePlayerControls.Where(x => x.PlayerId != target.PlayerId).ToArray(); PlayerControl rp = pcList.RandomElement(); diff --git a/README.md b/README.md index 8db2fe3c4..f00c3e44f 100644 --- a/README.md +++ b/README.md @@ -398,7 +398,7 @@ Click this badge to view our translation project: | /tl
/sp
/jj
/trial | Trial a player as the Judge or Councillor | 🔸 **id** – The player's ID to trial or kill
| :purple_circle: Everyone | :yellow_square: In Meetings | :x: | | /sw
/swap
/st | Set a (vote-) swap target as the Swapper | 🔸 **id** – The player's ID whose vote will be swapped with the other player you set
| :purple_circle: Everyone | :yellow_square: In Meetings | :x: | | /compare
/cp
/cmp | Compare two players' teams as the Inspector | 🔸 **id1** – The first player's ID to compare
🔸 **id2** – The second player's ID to compare
| :purple_circle: Everyone | :yellow_square: In Meetings | :x: | -| /ms
/mediumship
/medium | Answer the Medium's question | 🔸 **answer** – yes/no
| :purple_circle: Everyone | :yellow_square: In Meetings | :x: | +| /ms
/medium
/medium | Answer the Medium's question | 🔸 **answer** – yes/no
| :purple_circle: Everyone | :yellow_square: In Meetings | :x: | | /rv | Take revenge on (kill) a player as the Nemesis | 🔸 **id** – The player's ID to take revenge on (kill)
| :purple_circle: Everyone | :red_square: After Death | :x: | | | | | | | | | 104 | | | | | | @@ -436,7 +436,7 @@ Click this badge to view our translation project: > > - Many role ideas -> - Provided roles: AntiAdminer, CursedWolf, Workaholic, Greedier, Stalker, Ignitor, Rabbit +> - Provided roles: AntiAdminer, CursedWolf, Workaholic, Greedy, Stalker, Ignitor, Rabbit > - Reference: Modify game announcement > - New settings UI for v2024.6.18 > - Reference: Role Basis Changing Mid-Game diff --git a/Resources/Config/EACList.txt b/Resources/Config/EACList.txt index 57d04f016..57c5d29d2 100644 --- a/Resources/Config/EACList.txt +++ b/Resources/Config/EACList.txt @@ -90,6 +90,7 @@ goldapex#3225,a89e4420e,BoomplayYT woveelixir#4088,42044d211,DMD 3CD //hacker and probably BoomplayYT's alt tenpalace#1924,6a259fcd9,Goaty cat#2761,f70d4ddb1,ULC +pinbrittle#1538,4955c179f,Moralmaser // Cheating and disrupting lobbies ## Griefers, toxic, harrasing, morons setmolar#4374,藏族顶针 diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 9d750d86f..327e08818 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -214,12 +214,12 @@ "Gangster": "Gangster", "Cleaner": "Cleaner", "Lightning": "Lightning", - "Greedier": "Greedy", + "Greedy": "Greedy", "CursedWolf": "Cursed Wolf", "SoulCatcher": "Soul Catcher", "QuickShooter": "Quick Shooter", "Camouflager": "Camouflager", - "Eraser": "Evil Eraser", + "EvilEraser": "Evil Eraser", "Butcher": "Butcher", "Hangman": "Hangman", "Swooper": "Swooper", @@ -275,7 +275,7 @@ "Judge": "Judge", "Mortician": "Mortician", "Medium": "Medium", - "DovesOfNeace": "Pacifist", + "Pacifist": "Pacifist", "Observer": "Observer", "Monarch": "Monarch", "Investigator": "Investigator", @@ -363,7 +363,7 @@ "Sunglasses": "Sunglasses", "Workhorse": "Workhorse", "Fool": "Fool", - "Avanger": "Avenger", + "Avenger": "Avenger", "Youtuber": "YouTuber", "Egoist": "Egoist", "Stealer": "Stealer", @@ -421,7 +421,7 @@ "Prefix.Bewilder": "Bewilder", "Prefix.Workhorse": "Workhorse", "Prefix.Fool": "Fool", - "Prefix.Avanger": "Avenger", + "Prefix.Avenger": "Avenger", "Prefix.Youtuber": "YouTuber", "Prefix.Egoist": "Egoist", "Prefix.Stealer": "Stealer", @@ -493,12 +493,12 @@ "GangsterInfo": "Convert players to your side", "CleanerInfo": "Report bodies to make them unreportable", "LightningInfo": "Convert players to Quantum Ghosts", - "GreedierInfo": "Your kill cooldown shifts", + "GreedyInfo": "Your kill cooldown shifts", "CursedWolfInfo": "You survive a few kill attempts", "SoulCatcherInfo": "You swap places with your shift target", "QuickShooterInfo": "Store ammo to offset kill cooldown", "CamouflagerInfo": "Camouflage everyone for easy kills", - "EraserInfo": "Erase the role of your vote target", + "EvilEraserInfo": "Erase the role of your vote target", "ButcherInfo": "Enjoy my beautiful work", "HangmanInfo": "Killing while shifted ignores shields", "SwooperInfo": "Turn invisible temporarily", @@ -557,7 +557,7 @@ "MorticianInfo": "Report a body to know who interacted with them last", "MediumInfo": "Talk with ghosts", "ObserverInfo": "You can see all shield-animations", - "DovesOfNeaceInfo": "Vent to reset kill cooldowns", + "PacifistInfo": "Vent to reset kill cooldowns", "MonarchInfo": "Give your crew extra voting power!", "InvestigatorInfo": "Reveal roles of other players", "CoronerInfo": "Find corpses and their killers", @@ -634,7 +634,7 @@ "BewilderInfo": "Your killer gets your vision", "WorkhorseInfo": "Be the first to complete all tasks and get more", "FoolInfo": "You can't fix sabotages", - "AvangerInfo": "You take someone with you upon death", + "AvengerInfo": "You take someone with you upon death", "YoutuberInfo": "Get killed first to win", "HasteInfo": "Your kill cooldown progresses while in vents", "EgoistInfo": "Win on your own", @@ -723,12 +723,12 @@ "GangsterInfoLong": "(Impostors):\\nThe Gangster can recruit a player to a Madmate by pressing the kill button. If successful, both will see the shield animation as a reminder. The host sets the maximum number of recruits. If recruitment fails, the target is killed normally. When out of recruits, the Gangster can only make normal kills.", "CleanerInfoLong": "(Impostors):\\nCleaner can press the Report button to clean up any dead body they come across.\\n\\nNote: You can only clean bodies if your kill cooldown is up.\\n\\nIf the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned up body cannot be reported (including Bait's).", "LightningInfoLong": "(Impostors):\\nThe Lightning role cannot make regular kills. When the Lightning uses its kill button, the target will vaporize into a quantum ghost. If a player who is not a quantum ghost touches the quantum ghost, the quantum ghost will die. If the quantum ghost survives until a meeting, they will die after the meeting ends. Interacting with the quantum ghost has no effect. Killing the Lightning may cause the killer to vaporize into a quantum ghost, depending on the host's settings.", - "GreedierInfoLong": "(Impostors):\\nAs the Greedy, your kill cooldown is different after every even-numbered kill and every odd-numbered kill of yours. You have a separate cooldown after meetings. Your first kill after every meeting will set your cooldown to the Even-Numbered Kill Cooldown, your second kill will set it to the Odd-Numbered Kill Cooldown, and the process repeats until a meeting is called again.", + "GreedyInfoLong": "(Impostors):\\nAs the Greedy, your kill cooldown is different after every even-numbered kill and every odd-numbered kill of yours. You have a separate cooldown after meetings. Your first kill after every meeting will set your cooldown to the Even-Numbered Kill Cooldown, your second kill will set it to the Odd-Numbered Kill Cooldown, and the process repeats until a meeting is called again.", "CursedWolfInfoLong": "(Impostors):\\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The host sets the max of times you can counterattack)", "SoulCatcherInfoLong": "(Impostors):\\nSoul Catcher can swap places with the shapeshift target after shapeshifting. (If the target is in an abnormal state such as dead, swallowed by pelican, venting, etc., then nothing will happen)", "QuickShooterInfoLong": "(Impostors):\\nWhen the kill cooldown is over, the Quick Shooter can reset the cooldown by either shapeshifting or petting. Additionally, they can store a bullet, and upon successful storage, a shield animation will appear on their body as a reminder. After a Quick Shooter completes a kill, they can offset the kill cooldown with bullets until they run out. At the beginning of each meeting, the Quick Shooter can only keep a certain number of bullets, which the host sets.", "CamouflagerInfoLong": "(Impostors):\\nDuring the use of the Shapeshift skill by Camouflager, all players will appear identical. This effect will last until Camouflager reverts to its original form. It's important to note that the skills of communication sabotage camouflage and the skills of Camouflager can be used together. However, in case a meeting takes place during the activation of Camouflager's skill, it will be considered invalid.", - "EraserInfoLong": "(Impostors):\\nDuring the meeting, Eraser can vote for any crew member as a target. The selected crew member's roles will be erased after the meeting concludes. It is important to note that players whose roles have been erased will always be considered as vanilla roles, including the game result page.", + "EvilEraserInfoLong": "(Impostors):\\nDuring the meeting, Evil Eraser can vote for any crew member as a target. The selected crew member's roles will be erased after the meeting concludes. It is important to note that players whose roles have been erased will always be considered as vanilla roles, including the game result page.", "ButcherInfoLong": "(Impostors):\\nAs the Butcher, when you kill someone, they will drop 30 bodies, making it difficult to see who died in the round at the beginning of the meeting.\\nIf you kill an Avenger, the game instantly ends with 'Everyone died'.", "HangmanInfoLong": "(Impostors):\\nThe Hangman kills by strangling during shapeshifting, ignoring all target abilities. The strangled player doesn't leave a body or trigger abilities, including Veteran, Lucky, and Seer. Additional roles are also affected.", "SwooperInfoLong": "(Impostors):\\nThe Swooper can Vent/Vanish to temporarily turn invisible. You can kill while being invisible, unlike vanilla Phantom.", @@ -788,7 +788,7 @@ "MediumInfoLong": "(Crewmates):\\nThe Medium can contact a dead player after they are reported. The dead player can answer once with a YES or NO to the Medium's question (using /ms yes or /ms no). The Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\\nThe Observer can see all shield animations caused by other players after the first meeting.", "MonarchInfoLong": "(Crewmates):\\nAs the Monarch, you can knight players to give them an extra vote.\\n\\nYou cannot knight someone who already has extra votes.\\nKnighted players appear with a golden name.", - "DovesOfNeaceInfoLong": "(Crewmates):\\nPacifist resets kill cooldown for all players with kill button on vent/pet. Madmate only works on Crewmates.", + "PacifistInfoLong": "(Crewmates):\\nPacifist resets kill cooldown for all players with kill button on vent/pet. Madmate only works on Crewmates.", "InvestigatorInfoLong": "(Crewmates):\\nAs an Investigator, use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the reveal target. Stay near the target for a defined time to reveal their role.", "CoronerInfoLong": "(Crewmates):\\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If a meeting is called, the arrows disappear. Depending on the setting, the body you found cannot be reported.", "ScoutInfoLong": "(Crewmates):\\nAs a Scout, you can vote for a player in the meeting, which will mark their position for you in the game with arrows. In addition, at the beginning of a meeting, you will be shown in which room the player was last if the option is activated.", @@ -870,7 +870,7 @@ "TruantInfoLong": "(Add-ons):\\nAfter each meeting, you freeze in place for a set amount of seconds.", "WorkhorseInfoLong": "(Add-ons):\\nComplete all tasks to become Workhorse and get extra tasks set by the host.", "FoolInfoLong": "(Add-ons):\\nImpostors and Mechanics won't be Fool. Fools can't repair any sabotage.", - "AvangerInfoLong": "(Add-ons):\\nHost can allow Impostor to become Avenger. If Avenger dies, they'll revenge a random player.", + "AvengerInfoLong": "(Add-ons):\\nHost can allow Impostor to become Avenger. If Avenger dies, they'll revenge a random player.", "YoutuberInfoLong": "(Add-ons):\\nIf the YouTuber is the first player killed, they win. If not, they follow the Crewmate to win. Note: Indirect killing methods don't trigger the YouTuber's skills.", "EgoistInfoLong": "(Add-ons):\\nOnly impostors can get Egoist. If the impostor team wins while there's at least one Impostor alive who isn't an Egoist, the Egoist loses.\\nIn order for the Egoist to win, they must eject all other impostors and stay alive.", "StealerInfoLong": "(Add-ons):\\nStealers gets additional votes every time they kill someone.", @@ -1563,7 +1563,6 @@ "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", "NemesisCanKillNum": "Max number of revenges", "JesterCanUseButton": "Can call emergency meetings", - "VectorVentButtonText": "Hop", "Vector.NumVentsToWinOn.Skeld": "Number of Vents to Win on Skeld", "Vector.NumVentsToWinOn.MiraHQ": "Number of Vents to Win on Mira", "Vector.NumVentsToWinOn.Polus": "Number of Vents to Win on Polus", @@ -1749,7 +1748,7 @@ "CamouflageCooldown": "Camouflage Cooldown", "CamouflageDuration": "Camouflage Duration", "EraseLimit": "Max Erases", - "EraserHideVote": "Hide Eraser's Votes", + "EvilEraserHideVote": "Hide Evil Eraser's Votes", "EKill": "Kill Button", "EVote": "Vote", "E2Kill": "Kill Target", @@ -1884,8 +1883,8 @@ "ObliviousBaitImmune": "Immune to Bait", "MediumContactLimit": "(Initial) Max number of contacts (ability uses)", "MediumOnlyReceiveMsgFromCrew": "Receive messages only from Crewmates (including Madmates and Charmed Players)", - "DovesOfNeaceCooldown": "Ability Cooldown", - "DovesOfNeaceMaxOfUseage": "Max Number of Ability Uses", + "PacifistCooldown": "Ability Cooldown", + "PacifistMaxOfUsage": "Max Number of Ability Uses", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerNotifyKiller": "Notify Killer about being Tracked", @@ -2222,12 +2221,12 @@ "CustomSabotage.GrabOxygenMask.Done": "<#00ff00>Oxygen Mask Grabbed! You are safe.", "MorticianGetNoInfo": "According to your inspection, {0} did not seem to have contact with anyone during their lifetime.", "MorticianGetInfo": "According to your inspection, the last person {0} came into contact with during their lifetime was {1}.", - "MediumshipHelp": "/ms yes to agree\\n/ms no to disagree", - "MediumshipYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", - "MediumshipNo": "You thought you heard a quiet voice from another world denying the answer to your question.", - "MediumshipDone": "You successfully responded to the Medium.", - "MediumshipNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\\nConfirm: /ms yes\\nDeny: /ms no", - "MediumshipNotifySelf": "You established contact with {0}, please ask questions to them and wait for them to respond.\\n\\nRemaining ability uses: {1}", + "MediumHelp": "/ms yes to agree\\n/ms no to disagree", + "MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", + "MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.", + "MediumDone": "You successfully responded to the Medium.", + "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\\nConfirm: /ms yes\\nDeny: /ms no", + "MediumNotifySelf": "You established contact with {0}, please ask questions to them and wait for them to respond.\\n\\nRemaining ability uses: {1}", "ByBard": "by Bard", "ByBardGetFailed": "oops, I seem to be out of inspiration.", "GangsterSuccessfullyRecruited": "You successfully recruited a player", @@ -2241,7 +2240,7 @@ "LighterSkillInUse": "Ability in use", "LighterSkillStop": "Ability expired", "MediumKnowPlayerDead": "Someone died somewhere", - "StealerGetTicket": "You've got +{0} votes", + "StealerGetVote": "You've got +{0} votes", "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "ExecutionerRoleChanged": "Your target died", "SpeedBoosterTaskDone": "Your speed is {0} now", @@ -2262,7 +2261,7 @@ "TeleportedByTransporter": "Swapping places with: {0}", "TeleportedByTwister": "Swapping places with: {0}", "ErrorTeleport": "Teleport failed", - "LostRoleByEraser": "You lost your role because of the Eraser", + "LostRoleByEvilEraser": "You lost your role because of the Evil Eraser", "LostRoleByNiceEraser": "You lost your role because of the Nice Eraser", "KilledByScavenger": "You were killed by the Scavenger and thus teleported off-map", "SnitchDoneTasks": "Call a meeting to find the impostors", @@ -2300,9 +2299,9 @@ "GuessTeamMate": "Sorry, you can't guess your teammates.", "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", "GuessPhantom": "You can't guess a Specter, that allows them to win!", - "DovesOfNeaceOnGuard": "Ability used, {0} uses remain", - "DovesOfNeaceMaxUsage": "Ability use limit reached", - "DovesOfNeaceSkillNotify": "Pacifist reset your kill cooldown", + "PacifistOnGuard": "Ability used, {0} uses remain", + "PacifistMaxUsage": "Ability use limit reached", + "PacifistSkillNotify": "Pacifist reset your kill cooldown", "BeRecruitedByJackal": "You have been recruited by the Jackal", "CoronerTrackRecorded": "Track recorded", "CoronerNoTrack": "Nothing to track", @@ -3064,7 +3063,7 @@ "EraserEraseMsgTitle": "★[ Eraser ]★", "TrialKillTitle": "[★ Court ★]", "MorticianCheckTitle": "[★ Corpse Examination ★]", - "MediumshipTitle": "[★ Voice of the Underworld ★]", + "MediumTitle": "[★ Voice of the Underworld ★]", "NemesisRevengeTitle": "★[ NEWS ]★", "TrackerTitle": "★[ Track Reading ]★", "Temp.Blank": "​", @@ -3302,7 +3301,7 @@ "RevolutionistVentButtonText": "Revolution", "FollowerKillButtonText": "Follow", "RomanticKillButtonText": "Romance", - "DovesOfNeaceVentButtonText": "Reset", + "PacifistVentButtonText": "Reset", "CultistKillButtonText": "Charm", "HangmanKillButtonTextDuringSS": "Strangle", "InfectiousKillButtonText": "Infect", @@ -3671,13 +3670,6 @@ "JailorInfo": "Lock up your target in Jail", "JailorInfoLong": "(Crewmates):\\nAs the Jailor, use your kill button to lock a player in jail. Jailed players cannot be guessed or judged and jailed players can only guess Jailor.", "JailorJailCooldown": "Jail cooldown", - "JailorMaxExecution": "Maximum executions", - "JailorNBCanBeExe": "Can execute Neutral Benign", - "JailorNCCanBeExe": "Can execute Neutral Chaos", - "JailorNECanBeExe": "Can execute Neutral Evil", - "JailorNKCanBeExe": "Can execute Neutral Killing", - "JailorCovenCanBeExe": "Can execute Coven", - "JailorCKCanBeExe": "Can execute Crew Killing", "JailorTargetAlreadySelected": "You have already selected a target", "SuccessfullyJailed": "Target successfully Jailed", "CantGuessJailed": "You can not guess the target", @@ -4666,12 +4658,12 @@ "Ignitor": "Ignitor", "IgnitorInfo": "Light Candles for High Vision", "IgnitorInfoLong": "(Crewmates):\\nAs the Ignitor, you can light a new candle by completing a task, which sets your vision to maximum. As time goes on and the candle burns down, your vision progressively gets smaller. Since you use candles, you're immune to the Lights Sabotage.", - "CandleLighterStartVision": "Starting Vision (Highest)", - "CandleLighterCountStartTime": "Time to Start Changing Vision", - "CandleLighterEndVisionTime": "Time to End Vision", - "CandleLighterEndVision": "End Vision (Smallest Vision)", - "CandleLighterTimeMoveMeeting": "Time Moves During Meetings", - "CandleLighterTasksFinishedVision": "Vision after completing all tasks", + "IgnitorStartVision": "Starting Vision (Highest)", + "IgnitorCountStartTime": "Time to Start Changing Vision", + "IgnitorEndVisionTime": "Time to End Vision", + "IgnitorEndVision": "End Vision (Smallest Vision)", + "IgnitorTimeMoveMeeting": "Time Moves During Meetings", + "IgnitorTasksFinishedVision": "Vision after completing all tasks", "AprilFoolsMode": "April Fools Mode", "SilenceMode": "Silencing Method", "Altruist": "Altruist", diff --git a/Resources/Sounds/MarioCoin.wav b/Resources/Sounds/Vector.wav similarity index 100% rename from Resources/Sounds/MarioCoin.wav rename to Resources/Sounds/Vector.wav diff --git a/Resources/Sounds/MarioJump.wav b/Resources/Sounds/VectorJump.wav similarity index 100% rename from Resources/Sounds/MarioJump.wav rename to Resources/Sounds/VectorJump.wav diff --git a/Roles/AddOns/Common/Avanger.cs b/Roles/AddOns/Common/Avenger.cs similarity index 64% rename from Roles/AddOns/Common/Avanger.cs rename to Roles/AddOns/Common/Avenger.cs index 8a620bb6d..4d1004c4b 100644 --- a/Roles/AddOns/Common/Avanger.cs +++ b/Roles/AddOns/Common/Avenger.cs @@ -1,11 +1,11 @@ namespace EHR.AddOns.Common; -internal class Avanger : IAddon +internal class Avenger : IAddon { public AddonTypes Type => AddonTypes.Harmful; public void SetupCustomOption() { - Options.SetupAdtRoleOptions(15100, CustomRoles.Avanger, canSetNum: true, teamSpawnOptions: true); + Options.SetupAdtRoleOptions(15100, CustomRoles.Avenger, canSetNum: true, teamSpawnOptions: true); } } \ No newline at end of file diff --git a/Roles/Crewmate/CopyCat.cs b/Roles/Crewmate/CopyCat.cs index d1546ae95..2732ec75b 100644 --- a/Roles/Crewmate/CopyCat.cs +++ b/Roles/Crewmate/CopyCat.cs @@ -120,7 +120,7 @@ public class CopyCat : RoleBase CustomRoles.Escapist or CustomRoles.Enderman => CustomRoles.Tunneler, CustomRoles.Twister => CustomRoles.TimeMaster, CustomRoles.Disperser => CustomRoles.Transporter, - CustomRoles.Eraser => CustomRoles.NiceEraser, + CustomRoles.EvilEraser => CustomRoles.NiceEraser, CustomRoles.Visionary => CustomRoles.Oracle, CustomRoles.Workaholic or CustomRoles.Pawn => CustomRoles.Snitch, CustomRoles.Sunnyboy or CustomRoles.Fabricator => new[] {CustomRoles.Doctor, CustomRoles.ScientistEHR}.RandomElement(), diff --git a/Roles/Crewmate/CandleLighter.cs b/Roles/Crewmate/Ignitor.cs similarity index 83% rename from Roles/Crewmate/CandleLighter.cs rename to Roles/Crewmate/Ignitor.cs index 92b5aa0df..8559c2c86 100644 --- a/Roles/Crewmate/CandleLighter.cs +++ b/Roles/Crewmate/Ignitor.cs @@ -1,120 +1,120 @@ -using System; -using System.Collections.Generic; -using AmongUs.GameOptions; -using UnityEngine; - -namespace EHR.Crewmate; - -using static Options; - -public class Ignitor : RoleBase // Candle Lighter from TOHY -{ - private const int Id = 5280; - private static List PlayerIdList = []; - - private static OptionItem OptionTaskStartVision; - private static OptionItem OptionCountStartTime; - private static OptionItem OptionTaskEndVisionTime; - private static OptionItem OptionTaskEndVision; - private static OptionItem OptionTaskTimeMoveMeeting; - private static OptionItem OptionTasksFinishedVision; - private bool Active = true; - private float ElapsedTime; - - private float UpdateTime; - - public override bool IsEnable => PlayerIdList.Count > 0; - - public override void SetupCustomOption() - { - SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Ignitor); - - OptionTaskStartVision = new FloatOptionItem(Id + 2, "CandleLighterStartVision", new(0.5f, 5f, 0.1f), 0.8f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) - .SetValueFormat(OptionFormat.Multiplier); - - OptionCountStartTime = new IntegerOptionItem(Id + 3, "CandleLighterCountStartTime", new(0, 50, 5), 0, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) - .SetValueFormat(OptionFormat.Seconds); - - OptionTaskEndVisionTime = new IntegerOptionItem(Id + 4, "CandleLighterEndVisionTime", new(20, 200, 10), 50, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) - .SetValueFormat(OptionFormat.Seconds); - - OptionTaskEndVision = new FloatOptionItem(Id + 5, "CandleLighterEndVision", new(0f, 0.5f, 0.05f), 0.1f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) - .SetValueFormat(OptionFormat.Multiplier); - - OptionTaskTimeMoveMeeting = new BooleanOptionItem(Id + 6, "CandleLighterTimeMoveMeeting", false, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]); - - OptionTasksFinishedVision = new FloatOptionItem(Id + 7, "CandleLighterTasksFinishedVision", new(0.5f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) - .SetValueFormat(OptionFormat.Multiplier); - - OverrideTasksData.Create(Id + 8, TabGroup.CrewmateRoles, CustomRoles.Ignitor); - } - - public override void Init() - { - PlayerIdList = []; - Active = true; - } - - public override void Add(byte playerId) - { - PlayerIdList.Add(playerId); - Active = true; - UpdateTime = 1.0f; - ElapsedTime = OptionTaskEndVisionTime.GetInt() + OptionCountStartTime.GetInt(); - } - - public override void Remove(byte playerId) - { - PlayerIdList.Remove(playerId); - } - - public override void ApplyGameOptions(IGameOptions opt, byte id) - { - float Vision; - - if (!Active) - Vision = OptionTasksFinishedVision.GetFloat(); - else if (ElapsedTime > OptionTaskEndVisionTime.GetInt()) - Vision = OptionTaskStartVision.GetFloat(); - else - Vision = OptionTaskStartVision.GetFloat() * (ElapsedTime / OptionTaskEndVisionTime.GetInt()); - - if (Vision <= OptionTaskEndVision.GetFloat()) Vision = OptionTaskEndVision.GetFloat(); - - opt.SetFloat(FloatOptionNames.CrewLightMod, Vision); - if (Utils.IsActive(SystemTypes.Electrical)) opt.SetFloat(FloatOptionNames.CrewLightMod, Vision * 5); - } - - public override void OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount) - { - if (completedTaskCount + 1 >= totalTaskCount) - Active = false; - else - ElapsedTime = OptionTaskEndVisionTime.GetInt(); - - pc.MarkDirtySettings(); - } - - public override void OnFixedUpdate(PlayerControl player) - { - if (!GameStates.IsInTask && !OptionTaskTimeMoveMeeting.GetBool()) return; - - if (!Active) return; - - UpdateTime -= Time.fixedDeltaTime; - if (UpdateTime < 0) UpdateTime = 1.0f; - - if (ElapsedTime > 0f) - { - ElapsedTime -= Time.fixedDeltaTime; - - if (Math.Abs(UpdateTime - 1.0f) < 0.01f) player.MarkDirtySettings(); - } - } +using System; +using System.Collections.Generic; +using AmongUs.GameOptions; +using UnityEngine; + +namespace EHR.Crewmate; + +using static Options; + +public class Ignitor : RoleBase // Candle Lighter from TOHY +{ + private const int Id = 5280; + private static List PlayerIdList = []; + + private static OptionItem OptionTaskStartVision; + private static OptionItem OptionCountStartTime; + private static OptionItem OptionTaskEndVisionTime; + private static OptionItem OptionTaskEndVision; + private static OptionItem OptionTaskTimeMoveMeeting; + private static OptionItem OptionTasksFinishedVision; + private bool Active = true; + private float ElapsedTime; + + private float UpdateTime; + + public override bool IsEnable => PlayerIdList.Count > 0; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Ignitor); + + OptionTaskStartVision = new FloatOptionItem(Id + 2, "IgnitorStartVision", new(0.5f, 5f, 0.1f), 0.8f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) + .SetValueFormat(OptionFormat.Multiplier); + + OptionCountStartTime = new IntegerOptionItem(Id + 3, "IgnitorCountStartTime", new(0, 50, 5), 0, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) + .SetValueFormat(OptionFormat.Seconds); + + OptionTaskEndVisionTime = new IntegerOptionItem(Id + 4, "IgnitorEndVisionTime", new(20, 200, 10), 50, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) + .SetValueFormat(OptionFormat.Seconds); + + OptionTaskEndVision = new FloatOptionItem(Id + 5, "IgnitorEndVision", new(0f, 0.5f, 0.05f), 0.1f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) + .SetValueFormat(OptionFormat.Multiplier); + + OptionTaskTimeMoveMeeting = new BooleanOptionItem(Id + 6, "IgnitorTimeMoveMeeting", false, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]); + + OptionTasksFinishedVision = new FloatOptionItem(Id + 7, "IgnitorTasksFinishedVision", new(0.5f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Ignitor]) + .SetValueFormat(OptionFormat.Multiplier); + + OverrideTasksData.Create(Id + 8, TabGroup.CrewmateRoles, CustomRoles.Ignitor); + } + + public override void Init() + { + PlayerIdList = []; + Active = true; + } + + public override void Add(byte playerId) + { + PlayerIdList.Add(playerId); + Active = true; + UpdateTime = 1.0f; + ElapsedTime = OptionTaskEndVisionTime.GetInt() + OptionCountStartTime.GetInt(); + } + + public override void Remove(byte playerId) + { + PlayerIdList.Remove(playerId); + } + + public override void ApplyGameOptions(IGameOptions opt, byte id) + { + float Vision; + + if (!Active) + Vision = OptionTasksFinishedVision.GetFloat(); + else if (ElapsedTime > OptionTaskEndVisionTime.GetInt()) + Vision = OptionTaskStartVision.GetFloat(); + else + Vision = OptionTaskStartVision.GetFloat() * (ElapsedTime / OptionTaskEndVisionTime.GetInt()); + + if (Vision <= OptionTaskEndVision.GetFloat()) Vision = OptionTaskEndVision.GetFloat(); + + opt.SetFloat(FloatOptionNames.CrewLightMod, Vision); + if (Utils.IsActive(SystemTypes.Electrical)) opt.SetFloat(FloatOptionNames.CrewLightMod, Vision * 5); + } + + public override void OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount) + { + if (completedTaskCount + 1 >= totalTaskCount) + Active = false; + else + ElapsedTime = OptionTaskEndVisionTime.GetInt(); + + pc.MarkDirtySettings(); + } + + public override void OnFixedUpdate(PlayerControl player) + { + if (!GameStates.IsInTask && !OptionTaskTimeMoveMeeting.GetBool()) return; + + if (!Active) return; + + UpdateTime -= Time.fixedDeltaTime; + if (UpdateTime < 0) UpdateTime = 1.0f; + + if (ElapsedTime > 0f) + { + ElapsedTime -= Time.fixedDeltaTime; + + if (Math.Abs(UpdateTime - 1.0f) < 0.01f) player.MarkDirtySettings(); + } + } } \ No newline at end of file diff --git a/Roles/Crewmate/Medium.cs b/Roles/Crewmate/Medium.cs index f5eac4726..373d221d2 100644 --- a/Roles/Crewmate/Medium.cs +++ b/Roles/Crewmate/Medium.cs @@ -83,7 +83,7 @@ public class Medium : RoleBase if (pc.IsAlive()) return false; msg = msg.ToLower().Trim(); - if (!CheckCommand(ref msg, "通灵|ms|mediumship|medium", false)) return false; + if (!CheckCommand(ref msg, "通灵|ms|medium", false)) return false; bool ans; @@ -93,12 +93,12 @@ public class Medium : RoleBase ans = true; else { - Utils.SendMessage(GetString("MediumshipHelp"), pc.PlayerId); + Utils.SendMessage(GetString("MediumHelp"), pc.PlayerId); return true; } - Utils.SendMessage(GetString("Mediumship" + (ans ? "Yes" : "No")), ContactPlayer[pc.PlayerId], Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumshipTitle"))); - Utils.SendMessage(GetString("MediumshipDone"), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumshipTitle"))); + Utils.SendMessage(GetString("Medium" + (ans ? "Yes" : "No")), ContactPlayer[pc.PlayerId], Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumTitle"))); + Utils.SendMessage(GetString("MediumDone"), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("MediumTitle"))); ContactPlayer.Remove(pc.PlayerId); diff --git a/Roles/Crewmate/DovesOfNeace.cs b/Roles/Crewmate/Pacifist.cs similarity index 63% rename from Roles/Crewmate/DovesOfNeace.cs rename to Roles/Crewmate/Pacifist.cs index fb7cb25b0..45bf484a9 100644 --- a/Roles/Crewmate/DovesOfNeace.cs +++ b/Roles/Crewmate/Pacifist.cs @@ -6,29 +6,29 @@ using static EHR.Options; namespace EHR.Crewmate; -internal class DovesOfNeace : RoleBase +internal class Pacifist : RoleBase { public static bool On; public override bool IsEnable => On; public override void SetupCustomOption() { - SetupRoleOptions(7700, TabGroup.CrewmateRoles, CustomRoles.DovesOfNeace); + SetupRoleOptions(7700, TabGroup.CrewmateRoles, CustomRoles.Pacifist); - DovesOfNeaceCooldown = new FloatOptionItem(7710, "DovesOfNeaceCooldown", new(0f, 180f, 1f), 7f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.DovesOfNeace]) + PacifistCooldown = new FloatOptionItem(7710, "PacifistCooldown", new(0f, 180f, 1f), 7f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Pacifist]) .SetValueFormat(OptionFormat.Seconds); - DovesOfNeaceMaxOfUseage = new IntegerOptionItem(7711, "DovesOfNeaceMaxOfUseage", new(0, 30, 1), 0, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.DovesOfNeace]) + PacifistMaxOfUsage = new IntegerOptionItem(7711, "PacifistMaxOfUseage", new(0, 30, 1), 0, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Pacifist]) .SetValueFormat(OptionFormat.Times); - DovesOfNeaceAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(7712, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.4f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.DovesOfNeace]) + PacifistAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(7712, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.4f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Pacifist]) .SetValueFormat(OptionFormat.Times); - DovesOfNeaceAbilityChargesWhenFinishedTasks = new FloatOptionItem(7713, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.DovesOfNeace]) + PacifistAbilityChargesWhenFinishedTasks = new FloatOptionItem(7713, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, TabGroup.CrewmateRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Pacifist]) .SetValueFormat(OptionFormat.Times); } @@ -36,7 +36,7 @@ internal class DovesOfNeace : RoleBase public override void Add(byte playerId) { On = true; - playerId.SetAbilityUseLimit(DovesOfNeaceMaxOfUseage.GetFloat()); + playerId.SetAbilityUseLimit(PacifistMaxOfUsage.GetFloat()); } public override void Init() @@ -48,16 +48,16 @@ internal class DovesOfNeace : RoleBase { if (UsePets.GetBool()) return; - AURoleOptions.EngineerCooldown = DovesOfNeaceCooldown.GetFloat(); + AURoleOptions.EngineerCooldown = PacifistCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override void SetButtonTexts(HudManager hud, byte id) { if (UsePets.GetBool()) - hud.PetButton.buttonLabelText.text = Translator.GetString("DovesOfNeaceVentButtonText"); + hud.PetButton.buttonLabelText.text = Translator.GetString("PacifistVentButtonText"); else - hud.AbilityButton.buttonLabelText.text = Translator.GetString("DovesOfNeaceVentButtonText"); + hud.AbilityButton.buttonLabelText.text = Translator.GetString("PacifistVentButtonText"); } public override void OnPet(PlayerControl pc) @@ -91,11 +91,11 @@ internal class DovesOfNeace : RoleBase x.SetKillCooldown(); if (Main.PlayerStates[x.PlayerId].Role is Mercenary m) m.OnReportDeadBody(); - x.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.DovesOfNeace), Translator.GetString("DovesOfNeaceSkillNotify"))); + x.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Pacifist), Translator.GetString("PacifistSkillNotify"))); }); pc.RPCPlayCustomSound("Dove"); - pc.Notify(string.Format(Translator.GetString("DovesOfNeaceOnGuard"), pc.GetAbilityUseLimit())); + pc.Notify(string.Format(Translator.GetString("PacifistOnGuard"), pc.GetAbilityUseLimit())); } public override bool CanUseVent(PlayerControl pc, int ventId) diff --git a/Roles/Impostor/Butcher.cs b/Roles/Impostor/Butcher.cs index e47619e39..945225f7d 100644 --- a/Roles/Impostor/Butcher.cs +++ b/Roles/Impostor/Butcher.cs @@ -55,7 +55,7 @@ internal class Butcher : RoleBase if (!ButcherDeadPlayerList.Contains(target.PlayerId)) ButcherDeadPlayerList.Add(target.PlayerId); - if (target.Is(CustomRoles.Avanger)) + if (target.Is(CustomRoles.Avenger)) { target.Suicide(PlayerState.DeathReason.Dismembered, killer); diff --git a/Roles/Impostor/Eraser.cs b/Roles/Impostor/EvilEraser.cs similarity index 89% rename from Roles/Impostor/Eraser.cs rename to Roles/Impostor/EvilEraser.cs index b6960679d..7ac41d833 100644 --- a/Roles/Impostor/Eraser.cs +++ b/Roles/Impostor/EvilEraser.cs @@ -1,165 +1,165 @@ -using System.Collections.Generic; -using EHR.Neutral; -using Hazel; -using static EHR.Translator; - -namespace EHR.Impostor; - -internal class Eraser : RoleBase -{ - private const int Id = 16800; - private static List PlayerIdList = []; - - private static readonly string[] EraseMode = - [ - "EKill", - "EVote" - ]; - - private static readonly string[] WhenTargetIsNeutralAction = - [ - "E2Block", - "E2Kill" - ]; - - private static OptionItem EraseLimitOpt; - public static OptionItem EraseMethod; - private static OptionItem WhenTargetIsNeutral; - public static OptionItem HideVote; - public static OptionItem CancelVote; - - private static List DidVote = []; - private static List PlayerToErase = []; - public static List ErasedPlayers = []; - - public override bool IsEnable => PlayerIdList.Count > 0; - - public override void SetupCustomOption() - { - Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Eraser); - - EraseMethod = new StringOptionItem(Id + 10, "EraseMethod", EraseMode, 0, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]); - - WhenTargetIsNeutral = new StringOptionItem(Id + 11, "WhenTargetIsNeutral", WhenTargetIsNeutralAction, 0, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]); - - EraseLimitOpt = new IntegerOptionItem(Id + 12, "EraseLimit", new(1, 15, 1), 1, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]) - .SetValueFormat(OptionFormat.Times); - - HideVote = new BooleanOptionItem(Id + 13, "EraserHideVote", false, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]); - - CancelVote = Options.CreateVoteCancellingUseSetting(Id + 14, CustomRoles.Eraser, TabGroup.ImpostorRoles); - } - - public override void Init() - { - PlayerIdList = []; - ErasedPlayers = []; - } - - public override void Add(byte playerId) - { - PlayerIdList.Add(playerId); - playerId.SetAbilityUseLimit(EraseLimitOpt.GetFloat()); - } - - public override void Remove(byte playerId) - { - PlayerIdList.Remove(playerId); - } - - public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) - { - if (killer.GetAbilityUseLimit() < 1) return true; - - if (target.PlayerId == killer.PlayerId) return true; - - if (target.GetCustomRole().IsNeutral() && EraseMethod.GetInt() == 0) - { - killer.Notify(GetString("EraserEraseNeutralNotice")); - if (WhenTargetIsNeutral.GetInt() == 1) return true; - - killer.SetKillCooldown(5f); - return false; - } - - if (EraseMethod.GetInt() == 0) - { - return killer.CheckDoubleTrigger(target, () => - { - killer.RpcRemoveAbilityUse(); - killer.SetKillCooldown(); - killer.Notify(GetString("TargetErasedInRound")); - if (!PlayerToErase.Contains(target.PlayerId)) PlayerToErase.Add(target.PlayerId); - }); - } - - return true; - } - - public override bool OnVote(PlayerControl player, PlayerControl target) - { - if (Starspawn.IsDayBreak) return false; - if (player == null || target == null || EraseMethod.GetInt() == 0) return false; - - if (DidVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false; - - DidVote.Add(player.PlayerId); - - if (player.GetAbilityUseLimit() < 1) return false; - - if (target.PlayerId == player.PlayerId) - { - Utils.SendMessage(GetString("EraserEraseSelf"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle")), sendOption: SendOption.None); - return false; - } - - if (target.GetCustomRole().IsNeutral()) - { - Utils.SendMessage(string.Format(GetString("EraserEraseNeutralNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle"))); - return false; - } - - player.RpcRemoveAbilityUse(); - - if (!PlayerToErase.Contains(target.PlayerId)) PlayerToErase.Add(target.PlayerId); - - Utils.SendMessage(string.Format(GetString("EraserEraseNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle"))); - - if (GameStates.IsInTask) Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target); - - Main.DontCancelVoteList.Add(player.PlayerId); - return true; - } - - public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target) - { - OnVote(shapeshifter, target); - } - - public override void OnReportDeadBody() - { - DidVote = []; - } - - public override void AfterMeetingTasks() - { - PlayerToErase.ForEach(id => - { - PlayerControl pc = Utils.GetPlayerById(id); - if (pc == null || !pc.IsAlive() || pc.Is(CustomRoles.Bloodlust)) return; - - CustomRoles erasedRole = pc.IsImpostor() ? CustomRoles.ImpostorEHR : pc.IsCrewmate() ? CustomRoles.CrewmateEHR : pc.Is(Team.Coven) ? CustomRoles.CovenMember : CustomRoles.Amnesiac; - pc.RpcSetCustomRole(erasedRole); - pc.RpcChangeRoleBasis(erasedRole); - pc.Notify(GetString("LostRoleByEraser")); - Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} lost their role", "Eraser"); - ErasedPlayers.Add(id); - }); - - PlayerToErase = []; - } +using System.Collections.Generic; +using EHR.Neutral; +using Hazel; +using static EHR.Translator; + +namespace EHR.Impostor; + +internal class EvilEraser : RoleBase +{ + private const int Id = 16800; + private static List PlayerIdList = []; + + private static readonly string[] EraseMode = + [ + "EKill", + "EVote" + ]; + + private static readonly string[] WhenTargetIsNeutralAction = + [ + "E2Block", + "E2Kill" + ]; + + private static OptionItem EraseLimitOpt; + public static OptionItem EraseMethod; + private static OptionItem WhenTargetIsNeutral; + public static OptionItem HideVote; + public static OptionItem CancelVote; + + private static List DidVote = []; + private static List PlayerToErase = []; + public static List ErasedPlayers = []; + + public override bool IsEnable => PlayerIdList.Count > 0; + + public override void SetupCustomOption() + { + Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.EvilEraser); + + EraseMethod = new StringOptionItem(Id + 10, "EraseMethod", EraseMode, 0, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilEraser]); + + WhenTargetIsNeutral = new StringOptionItem(Id + 11, "WhenTargetIsNeutral", WhenTargetIsNeutralAction, 0, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilEraser]); + + EraseLimitOpt = new IntegerOptionItem(Id + 12, "EraseLimit", new(1, 15, 1), 1, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilEraser]) + .SetValueFormat(OptionFormat.Times); + + HideVote = new BooleanOptionItem(Id + 13, "EraserHideVote", false, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilEraser]); + + CancelVote = Options.CreateVoteCancellingUseSetting(Id + 14, CustomRoles.EvilEraser, TabGroup.ImpostorRoles); + } + + public override void Init() + { + PlayerIdList = []; + ErasedPlayers = []; + } + + public override void Add(byte playerId) + { + PlayerIdList.Add(playerId); + playerId.SetAbilityUseLimit(EraseLimitOpt.GetFloat()); + } + + public override void Remove(byte playerId) + { + PlayerIdList.Remove(playerId); + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + if (killer.GetAbilityUseLimit() < 1) return true; + + if (target.PlayerId == killer.PlayerId) return true; + + if (target.GetCustomRole().IsNeutral() && EraseMethod.GetInt() == 0) + { + killer.Notify(GetString("EraserEraseNeutralNotice")); + if (WhenTargetIsNeutral.GetInt() == 1) return true; + + killer.SetKillCooldown(5f); + return false; + } + + if (EraseMethod.GetInt() == 0) + { + return killer.CheckDoubleTrigger(target, () => + { + killer.RpcRemoveAbilityUse(); + killer.SetKillCooldown(); + killer.Notify(GetString("TargetErasedInRound")); + if (!PlayerToErase.Contains(target.PlayerId)) PlayerToErase.Add(target.PlayerId); + }); + } + + return true; + } + + public override bool OnVote(PlayerControl player, PlayerControl target) + { + if (Starspawn.IsDayBreak) return false; + if (player == null || target == null || EraseMethod.GetInt() == 0) return false; + + if (DidVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false; + + DidVote.Add(player.PlayerId); + + if (player.GetAbilityUseLimit() < 1) return false; + + if (target.PlayerId == player.PlayerId) + { + Utils.SendMessage(GetString("EraserEraseSelf"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.EvilEraser), GetString("EraserEraseMsgTitle")), sendOption: SendOption.None); + return false; + } + + if (target.GetCustomRole().IsNeutral()) + { + Utils.SendMessage(string.Format(GetString("EraserEraseNeutralNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.EvilEraser), GetString("EraserEraseMsgTitle"))); + return false; + } + + player.RpcRemoveAbilityUse(); + + if (!PlayerToErase.Contains(target.PlayerId)) PlayerToErase.Add(target.PlayerId); + + Utils.SendMessage(string.Format(GetString("EraserEraseNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.EvilEraser), GetString("EraserEraseMsgTitle"))); + + if (GameStates.IsInTask) Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target); + + Main.DontCancelVoteList.Add(player.PlayerId); + return true; + } + + public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target) + { + OnVote(shapeshifter, target); + } + + public override void OnReportDeadBody() + { + DidVote = []; + } + + public override void AfterMeetingTasks() + { + PlayerToErase.ForEach(id => + { + PlayerControl pc = Utils.GetPlayerById(id); + if (pc == null || !pc.IsAlive() || pc.Is(CustomRoles.Bloodlust)) return; + + CustomRoles erasedRole = pc.IsImpostor() ? CustomRoles.ImpostorEHR : pc.IsCrewmate() ? CustomRoles.CrewmateEHR : pc.Is(Team.Coven) ? CustomRoles.CovenMember : CustomRoles.Amnesiac; + pc.RpcSetCustomRole(erasedRole); + pc.RpcChangeRoleBasis(erasedRole); + pc.Notify(GetString("LostRoleByEraser")); + Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} lost their role", "Eraser"); + ErasedPlayers.Add(id); + }); + + PlayerToErase = []; + } } \ No newline at end of file diff --git a/Roles/Impostor/Greedier.cs b/Roles/Impostor/Greedy.cs similarity index 92% rename from Roles/Impostor/Greedier.cs rename to Roles/Impostor/Greedy.cs index 522bc2d19..98897735d 100644 --- a/Roles/Impostor/Greedier.cs +++ b/Roles/Impostor/Greedy.cs @@ -1,140 +1,140 @@ -using System.Collections.Generic; -using System.Linq; -using AmongUs.GameOptions; -using EHR.Modules; -using EHR.Neutral; -using Hazel; - -namespace EHR.Impostor; - -// Reference: https://github.com/Yumenopai/TownOfHost_Y -public class Greedier : RoleBase // Also used for Pulse as the NK version of this -{ - private const int Id = 1300; - public static List PlayerIdList = []; - - private static OptionItem OddKillCooldown; - private static OptionItem EvenKillCooldown; - private static OptionItem AfterMeetingKillCooldown; - private float AfterMeetingKCD; - private float EvenKCD; - private bool HasImpVision; - - private bool IsPulse; - - public bool IsOdd = true; - - private float OddKCD; - - public override bool IsEnable => PlayerIdList.Count > 0; - - public override void SetupCustomOption() - { - Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Greedier); - - OddKillCooldown = new FloatOptionItem(Id + 10, "OddKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier]) - .SetValueFormat(OptionFormat.Seconds); - - EvenKillCooldown = new FloatOptionItem(Id + 11, "EvenKillCooldown", new(0f, 180f, 0.5f), 15f, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier]) - .SetValueFormat(OptionFormat.Seconds); - - AfterMeetingKillCooldown = new FloatOptionItem(Id + 12, "AfterMeetingKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedier]) - .SetValueFormat(OptionFormat.Seconds); - } - - public override void Init() - { - PlayerIdList = []; - } - - public override void Add(byte playerId) - { - PlayerIdList.Add(playerId); - IsOdd = true; - - IsPulse = Main.PlayerStates[playerId].MainRole == CustomRoles.Pulse; - - if (IsPulse) - { - OddKCD = Pulse.OddKillCooldown.GetFloat(); - EvenKCD = Pulse.EvenKillCooldown.GetFloat(); - AfterMeetingKCD = Pulse.AfterMeetingKillCooldown.GetFloat(); - HasImpVision = Pulse.HasImpostorVision.GetBool(); - } - else - { - OddKCD = OddKillCooldown.GetFloat(); - EvenKCD = EvenKillCooldown.GetFloat(); - AfterMeetingKCD = AfterMeetingKillCooldown.GetFloat(); - HasImpVision = true; - } - } - - public override void Remove(byte playerId) - { - PlayerIdList.Remove(playerId); - } - - public override void ApplyGameOptions(IGameOptions opt, byte playerId) - { - opt.SetVision(HasImpVision); - } - - public override bool CanUseImpostorVentButton(PlayerControl pc) - { - return !IsPulse || Pulse.CanVent.GetBool(); - } - - private void SendRPC(byte playerId) - { - if (!Utils.DoRPC) return; - - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetGreedierOe, SendOption.Reliable); - writer.Write(playerId); - writer.Write(IsOdd); - AmongUsClient.Instance.FinishRpcImmediately(writer); - } - - public void ReceiveRPC(bool isOdd) - { - IsOdd = isOdd; - } - - public override void SetKillCooldown(byte id) - { - Main.AllPlayerKillCooldown[id] = OddKCD; - } - - public override void OnReportDeadBody() - { - foreach (PlayerControl pc in Main.AllAlivePlayerControls.Where(x => PlayerIdList.Contains(x.PlayerId))) - { - IsOdd = true; - SendRPC(pc.PlayerId); - Main.AllPlayerKillCooldown[pc.PlayerId] = AfterMeetingKCD; - } - } - - public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) - { - switch (IsOdd) - { - case true: - Logger.Info($"{killer.Data?.PlayerName}: Odd-Kill", "Greedier"); - Main.AllPlayerKillCooldown[killer.PlayerId] = EvenKCD; - break; - case false: - Logger.Info($"{killer.Data?.PlayerName}: Even-Kill", "Greedier"); - Main.AllPlayerKillCooldown[killer.PlayerId] = OddKCD; - break; - } - - IsOdd = !IsOdd; - SendRPC(killer.PlayerId); - killer.SyncSettings(); - return base.OnCheckMurder(killer, target); - } +using System.Collections.Generic; +using System.Linq; +using AmongUs.GameOptions; +using EHR.Modules; +using EHR.Neutral; +using Hazel; + +namespace EHR.Impostor; + +// Reference: https://github.com/Yumenopai/TownOfHost_Y +public class Greedy : RoleBase // Also used for Pulse as the NK version of this +{ + private const int Id = 1300; + public static List PlayerIdList = []; + + private static OptionItem OddKillCooldown; + private static OptionItem EvenKillCooldown; + private static OptionItem AfterMeetingKillCooldown; + private float AfterMeetingKCD; + private float EvenKCD; + private bool HasImpVision; + + private bool IsPulse; + + public bool IsOdd = true; + + private float OddKCD; + + public override bool IsEnable => PlayerIdList.Count > 0; + + public override void SetupCustomOption() + { + Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Greedy); + + OddKillCooldown = new FloatOptionItem(Id + 10, "OddKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedy]) + .SetValueFormat(OptionFormat.Seconds); + + EvenKillCooldown = new FloatOptionItem(Id + 11, "EvenKillCooldown", new(0f, 180f, 0.5f), 15f, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedy]) + .SetValueFormat(OptionFormat.Seconds); + + AfterMeetingKillCooldown = new FloatOptionItem(Id + 12, "AfterMeetingKillCooldown", new(0f, 180f, 0.5f), 27.5f, TabGroup.ImpostorRoles) + .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedy]) + .SetValueFormat(OptionFormat.Seconds); + } + + public override void Init() + { + PlayerIdList = []; + } + + public override void Add(byte playerId) + { + PlayerIdList.Add(playerId); + IsOdd = true; + + IsPulse = Main.PlayerStates[playerId].MainRole == CustomRoles.Pulse; + + if (IsPulse) + { + OddKCD = Pulse.OddKillCooldown.GetFloat(); + EvenKCD = Pulse.EvenKillCooldown.GetFloat(); + AfterMeetingKCD = Pulse.AfterMeetingKillCooldown.GetFloat(); + HasImpVision = Pulse.HasImpostorVision.GetBool(); + } + else + { + OddKCD = OddKillCooldown.GetFloat(); + EvenKCD = EvenKillCooldown.GetFloat(); + AfterMeetingKCD = AfterMeetingKillCooldown.GetFloat(); + HasImpVision = true; + } + } + + public override void Remove(byte playerId) + { + PlayerIdList.Remove(playerId); + } + + public override void ApplyGameOptions(IGameOptions opt, byte playerId) + { + opt.SetVision(HasImpVision); + } + + public override bool CanUseImpostorVentButton(PlayerControl pc) + { + return !IsPulse || Pulse.CanVent.GetBool(); + } + + private void SendRPC(byte playerId) + { + if (!Utils.DoRPC) return; + + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetGreedyOe, SendOption.Reliable); + writer.Write(playerId); + writer.Write(IsOdd); + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public void ReceiveRPC(bool isOdd) + { + IsOdd = isOdd; + } + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = OddKCD; + } + + public override void OnReportDeadBody() + { + foreach (PlayerControl pc in Main.AllAlivePlayerControls.Where(x => PlayerIdList.Contains(x.PlayerId))) + { + IsOdd = true; + SendRPC(pc.PlayerId); + Main.AllPlayerKillCooldown[pc.PlayerId] = AfterMeetingKCD; + } + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + switch (IsOdd) + { + case true: + Logger.Info($"{killer.Data?.PlayerName}: Odd-Kill", "Greedy"); + Main.AllPlayerKillCooldown[killer.PlayerId] = EvenKCD; + break; + case false: + Logger.Info($"{killer.Data?.PlayerName}: Even-Kill", "Greedy"); + Main.AllPlayerKillCooldown[killer.PlayerId] = OddKCD; + break; + } + + IsOdd = !IsOdd; + SendRPC(killer.PlayerId); + killer.SyncSettings(); + return base.OnCheckMurder(killer, target); + } } \ No newline at end of file