diff --git a/CustomRoles.cs b/CustomRoles.cs index 110670971..8f9012382 100644 --- a/CustomRoles.cs +++ b/CustomRoles.cs @@ -308,11 +308,11 @@ public enum CustomRoles Evolver, Executioner, Explosivist, - Totocalcio, // Follower + Follower, Gaslighter, Glitch, God, - FFF, // Hater + Hater, HeadHunter, HexMaster, Hookshot, @@ -374,7 +374,7 @@ public enum CustomRoles Sprayer, DarkHide, // Stalker Starspawn, - Succubus, // Cultist + Cultist, Sunnyboy, Technician, Tank, @@ -399,7 +399,7 @@ public enum CustomRoles Augur, Banshee, CovenLeader, - RegularCoven, // Coven Member + CovenMember, Death, // Reaper changes to Death Dreamweaver, Enchanter, diff --git a/Main.cs b/Main.cs index 8fdb160b5..6f0140b39 100644 --- a/Main.cs +++ b/Main.cs @@ -523,7 +523,7 @@ public class Main : BasePlugin { CustomRoles.Innocent, "#8f815e" }, { CustomRoles.Pelican, "#34c84b" }, { CustomRoles.Revolutionist, "#ba4d06" }, - { CustomRoles.FFF, "#414b66" }, + { CustomRoles.Hater, "#414b66" }, { CustomRoles.Konan, "#4d4dff" }, { CustomRoles.Demon, "#68bc71" }, { CustomRoles.DarkHide, "#483d8b" }, @@ -533,11 +533,11 @@ public class Main : BasePlugin { CustomRoles.Provocateur, "#74ba43" }, { CustomRoles.Sunnyboy, "#ff9902" }, { CustomRoles.Poisoner, "#e70052" }, - { CustomRoles.Totocalcio, "#ff9409" }, + { CustomRoles.Follower, "#ff9409" }, { CustomRoles.Romantic, "#FF1493" }, { CustomRoles.VengefulRomantic, "#ba2749" }, { CustomRoles.RuthlessRomantic, "#D2691E" }, - { CustomRoles.Succubus, "#cf6acd" }, + { CustomRoles.Cultist, "#cf6acd" }, { CustomRoles.Necromancer, "#f7adcf" }, { CustomRoles.Deathknight, "#361d12" }, { CustomRoles.HexMaster, "#ff00ff" }, @@ -1025,7 +1025,7 @@ public enum CustomWinner BloodKnight = CustomRoles.BloodKnight, Poisoner = CustomRoles.Poisoner, HexMaster = CustomRoles.HexMaster, - Succubus = CustomRoles.Succubus, + Cultist = CustomRoles.Cultist, Necromancer = CustomRoles.Necromancer, Wraith = CustomRoles.Wraith, SerialKiller = CustomRoles.SerialKiller, @@ -1107,10 +1107,10 @@ public enum AdditionalWinners Executioner = CustomRoles.Executioner, Opportunist = CustomRoles.Opportunist, Lawyer = CustomRoles.Lawyer, - FFF = CustomRoles.FFF, + Hater = CustomRoles.Hater, Provocateur = CustomRoles.Provocateur, Sunnyboy = CustomRoles.Sunnyboy, - Totocalcio = CustomRoles.Totocalcio, + Follower = CustomRoles.Follower, Romantic = CustomRoles.Romantic, VengefulRomantic = CustomRoles.VengefulRomantic, Pursuer = CustomRoles.Pursuer, diff --git a/Modules/CustomRoleSelector.cs b/Modules/CustomRoleSelector.cs index 66e62b4ee..21a2980a5 100644 --- a/Modules/CustomRoleSelector.cs +++ b/Modules/CustomRoleSelector.cs @@ -115,7 +115,7 @@ internal static class CustomRoleSelector case CustomRoles.Deathknight: case CustomRoles.Convict: case CustomRoles.Refugee: - case CustomRoles.RegularCoven: + case CustomRoles.CovenMember: case CustomRoles.CovenLeader: case CustomRoles.Death: case CustomRoles.GM: diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index edc9a7d41..479109d5c 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -361,7 +361,7 @@ internal static class CustomRolesHelper CustomRoles.Silencer => Silencer.SilenceMode.GetValue() == 1 ? CustomRoles.Shapeshifter : CustomRoles.Impostor, CustomRoles.NoteKiller => CustomRoles.Crewmate, CustomRoles.RoomRusher => RoomRusher.CanVent ? CustomRoles.Engineer : CustomRoles.Crewmate, - CustomRoles.RegularCoven => CustomRoles.Crewmate, + CustomRoles.CovenMember => CustomRoles.Crewmate, CustomRoles.Augur => Augur.CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate, // Vanilla roles (just in case) @@ -479,7 +479,7 @@ internal static class CustomRolesHelper CustomRoles.Goose => RoleTypes.Impostor, CustomRoles.Pursuer => RoleTypes.Impostor, CustomRoles.Revolutionist => RoleTypes.Impostor, - CustomRoles.FFF => RoleTypes.Impostor, + CustomRoles.Hater => RoleTypes.Impostor, CustomRoles.Medic => UsePets && Medic.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor, CustomRoles.Demon => RoleTypes.Impostor, CustomRoles.HexMaster => RoleTypes.Impostor, @@ -545,11 +545,11 @@ internal static class CustomRolesHelper CustomRoles.Bandit => RoleTypes.Impostor, CustomRoles.Maverick => RoleTypes.Impostor, CustomRoles.Parasite => RoleTypes.Shapeshifter, - CustomRoles.Totocalcio => RoleTypes.Impostor, + CustomRoles.Follower => RoleTypes.Impostor, CustomRoles.Romantic => RoleTypes.Impostor, CustomRoles.VengefulRomantic => RoleTypes.Impostor, CustomRoles.RuthlessRomantic => RoleTypes.Impostor, - CustomRoles.Succubus => RoleTypes.Impostor, + CustomRoles.Cultist => RoleTypes.Impostor, CustomRoles.Necromancer => RoleTypes.Impostor, CustomRoles.Deathknight => RoleTypes.Impostor, CustomRoles.Virus => RoleTypes.Impostor, @@ -602,7 +602,7 @@ internal static class CustomRolesHelper CustomRoles.Sidekick or CustomRoles.HexMaster or CustomRoles.Doppelganger or - CustomRoles.Succubus or + CustomRoles.Cultist or CustomRoles.Demon or CustomRoles.Crewpostor or CustomRoles.Hypocrite or @@ -818,7 +818,7 @@ internal static class CustomRolesHelper { return role is CustomRoles.Jackal or - CustomRoles.Succubus or + CustomRoles.Cultist or CustomRoles.Necromancer or CustomRoles.Virus or CustomRoles.Spiritcaller; @@ -1227,7 +1227,7 @@ internal static class CustomRolesHelper public static bool IsCoven(this CustomRoles role) { return role is - CustomRoles.RegularCoven or + CustomRoles.CovenMember or CustomRoles.CovenLeader or CustomRoles.SpellCaster or CustomRoles.PotionMaster or @@ -1545,7 +1545,7 @@ internal static class CustomRolesHelper CustomRoles.SchrodingersCat => RoleOptionType.Neutral_Benign, CustomRoles.Predator => RoleOptionType.Neutral_Benign, CustomRoles.Pursuer => RoleOptionType.Neutral_Benign, - CustomRoles.FFF => RoleOptionType.Neutral_Benign, + CustomRoles.Hater => RoleOptionType.Neutral_Benign, CustomRoles.Revolutionist => RoleOptionType.Neutral_Benign, CustomRoles.Impartial => RoleOptionType.Neutral_Benign, CustomRoles.Investor => RoleOptionType.Neutral_Benign, @@ -1560,7 +1560,7 @@ internal static class CustomRolesHelper CustomRoles.SoulHunter => RoleOptionType.Neutral_Benign, CustomRoles.Technician => RoleOptionType.Neutral_Benign, CustomRoles.Tank => RoleOptionType.Neutral_Benign, - CustomRoles.Totocalcio => RoleOptionType.Neutral_Benign, + CustomRoles.Follower => RoleOptionType.Neutral_Benign, CustomRoles.Arsonist => RoleOptionType.Neutral_Evil, CustomRoles.Jester => RoleOptionType.Neutral_Evil, CustomRoles.Gaslighter => RoleOptionType.Neutral_Evil, @@ -1909,7 +1909,7 @@ public enum CountTypes Demon, BloodKnight, Poisoner, - Succubus, + Cultist, Necromancer, HexMaster, Wraith, diff --git a/Modules/GameState.cs b/Modules/GameState.cs index 3b9807948..874f4c83f 100644 --- a/Modules/GameState.cs +++ b/Modules/GameState.cs @@ -261,10 +261,10 @@ public class PlayerState(byte playerId) Utils.NotifyRoles(SpecifyTarget: Player); break; case CustomRoles.Charmed: - countTypes = Succubus.CharmedCountMode.GetInt() switch + countTypes = Cultist.CharmedCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, - 1 => CountTypes.Succubus, + 1 => CountTypes.Cultist, 2 => countTypes, _ => throw new NotImplementedException() }; diff --git a/Modules/GhostRolesManager.cs b/Modules/GhostRolesManager.cs index f27df603c..8fe48bf48 100644 --- a/Modules/GhostRolesManager.cs +++ b/Modules/GhostRolesManager.cs @@ -116,7 +116,7 @@ internal static class GhostRolesManager Main.PlayerStates[pc.PlayerId].Role switch { Romantic when Romantic.HasPickedPartner => true, - Totocalcio tc when tc.BetPlayer != byte.MaxValue => true, + Follower tc when tc.BetPlayer != byte.MaxValue => true, _ => false }; } diff --git a/Modules/NameColorManager.cs b/Modules/NameColorManager.cs index 1f6a2e79b..b05ee4de3 100644 --- a/Modules/NameColorManager.cs +++ b/Modules/NameColorManager.cs @@ -110,7 +110,7 @@ public static class NameColorManager if (target.Is(CustomRoles.Glow) && Utils.IsActive(SystemTypes.Electrical)) color = Main.RoleColors[CustomRoles.Glow]; if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) color = Main.RoleColors[CustomRoles.Mare]; if (seer.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Contagious) && Virus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Virus]; - if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && Succubus.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Charmed]; + if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && Cultist.TargetKnowOtherTarget.GetBool()) color = Main.RoleColors[CustomRoles.Charmed]; if (seer.Is(CustomRoles.Entranced) && target.Is(CustomRoles.Entranced) && Siren.EntrancedKnowEntranced.GetBool()) color = Main.RoleColors[CustomRoles.Siren]; if (seer.Is(CustomRoleTypes.Coven) && target.Is(CustomRoles.Entranced) && Siren.CovenKnowEntranced.GetValue() == 1) color = Main.RoleColors[CustomRoles.Entranced]; if (target.Is(CustomRoleTypes.Coven) && seer.Is(CustomRoles.Entranced) && Siren.EntrancedKnowCoven.GetValue() == 1) color = Main.RoleColors[CustomRoles.Entranced]; @@ -146,7 +146,7 @@ public static class NameColorManager CustomRoles.Gangster when target.Is(CustomRoles.Madmate) => Main.RoleColors[CustomRoles.Madmate], CustomRoles.Crewpostor when target.Is(CustomRoleTypes.Impostor) && Options.CrewpostorKnowsAllies.GetBool() => Main.ImpostorColor, CustomRoles.Hypocrite when target.Is(CustomRoleTypes.Impostor) && Hypocrite.KnowsAllies.GetBool() => Main.ImpostorColor, - CustomRoles.Succubus when target.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Charmed], + CustomRoles.Cultist when target.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Charmed], CustomRoles.Siren when target.Is(CustomRoles.Entranced) => Main.RoleColors[CustomRoles.Siren], CustomRoles.Necromancer or CustomRoles.Deathknight when target.Is(CustomRoles.Undead) => Main.RoleColors[CustomRoles.Undead], CustomRoles.Necromancer or CustomRoles.Deathknight when Necromancer.PartiallyRecruitedIds.Contains(target.PlayerId) => Main.RoleColors[CustomRoles.Deathknight], @@ -203,7 +203,7 @@ public static class NameColorManager CustomRoles.Speedrunner when !seer.Is(Team.Crewmate) && target.GetTaskState().CompletedTasksCount >= Speedrunner.SpeedrunnerNotifyAtXTasksLeft.GetInt() && Speedrunner.SpeedrunnerNotifyKillers.GetBool() => Main.RoleColors[CustomRoles.Speedrunner], CustomRoles.SoulHunter when SoulHunter.IsSoulHunterTarget(seer.PlayerId) => Main.RoleColors[CustomRoles.SoulHunter], CustomRoles.Necromancer or CustomRoles.Deathknight when seer.Is(CustomRoles.Undead) => Main.RoleColors[targetRole], - CustomRoles.Succubus when seer.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Succubus], + CustomRoles.Cultist when seer.Is(CustomRoles.Charmed) => Main.RoleColors[CustomRoles.Cultist], CustomRoles.Siren when seer.Is(CustomRoles.Entranced) => Main.RoleColors[CustomRoles.Siren], CustomRoles.Crewpostor when seer.Is(CustomRoleTypes.Impostor) && Options.AlliesKnowCrewpostor.GetBool() => Main.RoleColors[CustomRoles.Madmate], CustomRoles.Hypocrite when seer.Is(CustomRoleTypes.Impostor) && Hypocrite.AlliesKnowHypocrite.GetBool() => Main.RoleColors[CustomRoles.Madmate], diff --git a/Modules/RPC.cs b/Modules/RPC.cs index b37e1ac37..10f6a4d54 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -132,7 +132,7 @@ public enum CustomRPC SetSwooperTimer, SetBanditStealLimit, SetBkTimer, - SyncTotocalcioTargetAndTimes, + SyncFollowerTargetAndTimes, SyncRomanticTarget, SyncVengefulRomanticTarget, SetRevealedPlayer, @@ -1149,9 +1149,9 @@ internal static class RPCHandlerPatch Wildling.ReceiveRPC(reader); break; } - case CustomRPC.SyncTotocalcioTargetAndTimes: + case CustomRPC.SyncFollowerTargetAndTimes: { - Totocalcio.ReceiveRPC(reader); + Follower.ReceiveRPC(reader); break; } case CustomRPC.SyncRomanticTarget: diff --git a/Modules/Statistics.cs b/Modules/Statistics.cs index 179a9e227..367f491dd 100644 --- a/Modules/Statistics.cs +++ b/Modules/Statistics.cs @@ -305,7 +305,7 @@ public static class Statistics if ((targetState.MainRole == CustomRoles.Romantic && Romantic.PartnerId == killer.PlayerId) || (targetState.SubRoles.Contains(CustomRoles.Lovers) && killer.Is(CustomRoles.Lovers)) || (targetState.MainRole == CustomRoles.Lawyer && Lawyer.Target.TryGetValue(target.PlayerId, out byte ltg) && ltg == killer.PlayerId) || - (targetState.Role is Totocalcio tc && tc.BetPlayer == killer.PlayerId)) + (targetState.Role is Follower tc && tc.BetPlayer == killer.PlayerId)) Achievements.Type.WhatHaveIDone.CompleteAfterGameEnd(); if (targetState.MainRole == CustomRoles.Snitch && Snitch.IsExposed.TryGetValue(target.PlayerId, out bool exposed) && exposed) diff --git a/Modules/Utils.cs b/Modules/Utils.cs index e9edd6f6c..3978bde1b 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -587,7 +587,7 @@ public static class Utils roleText = GetRoleString("Recruit-") + roleText; } - if (targetSubRoles.Contains(CustomRoles.Charmed) && (self || pure || seeTargetBetrayalAddons || seerMainRole == CustomRoles.Succubus || (Succubus.TargetKnowOtherTarget.GetBool() && seerSubRoles.Contains(CustomRoles.Charmed)))) + if (targetSubRoles.Contains(CustomRoles.Charmed) && (self || pure || seeTargetBetrayalAddons || seerMainRole == CustomRoles.Cultist || (Cultist.TargetKnowOtherTarget.GetBool() && seerSubRoles.Contains(CustomRoles.Charmed)))) { roleColor = GetRoleColor(CustomRoles.Charmed); roleText = GetRoleString("Charmed-") + roleText; @@ -915,7 +915,7 @@ public static class Utils case CustomRoles.Pelican: case CustomRoles.Medusa: case CustomRoles.Revolutionist: - case CustomRoles.FFF: + case CustomRoles.Hater: case CustomRoles.Demon: case CustomRoles.HexMaster: case CustomRoles.Wraith: @@ -927,11 +927,11 @@ public static class Utils case CustomRoles.Provocateur: case CustomRoles.BloodKnight: case CustomRoles.Camouflager: - case CustomRoles.Totocalcio: + case CustomRoles.Follower: case CustomRoles.Romantic: case CustomRoles.VengefulRomantic: case CustomRoles.RuthlessRomantic: - case CustomRoles.Succubus: + case CustomRoles.Cultist: case CustomRoles.Necromancer: case CustomRoles.Deathknight: case CustomRoles.Amnesiac: @@ -2902,7 +2902,7 @@ public static class Utils TargetMark.Append(Demon.TargetMark(seer, target)); TargetMark.Append(Medic.GetMark(seer, target)); TargetMark.Append(Gaslighter.GetMark(seer, target, forMeeting)); - TargetMark.Append(Totocalcio.TargetMark(seer, target)); + TargetMark.Append(Follower.TargetMark(seer, target)); TargetMark.Append(Romantic.TargetMark(seer, target)); TargetMark.Append(Lawyer.LawyerMark(seer, target)); TargetMark.Append(Deathpact.GetDeathpactMark(seer, target)); diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index bcec6a246..7e5d30c40 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -3464,7 +3464,7 @@ internal static class ChatCommands "竊票者" or "偷票" or "偷票者" or "窃票师" or "窃票" => GetString("TicketsStealer"), "教父" => GetString("Gangster"), "革命家" or "革命" or "revo" => GetString("Revolutionist"), - "fff團" or "fff" or "fff团" => GetString("FFF"), + "fff團" or "fff" or "fff团" => GetString("Hater"), "清理工" or "清潔工" or "清洁工" or "清理" or "清洁" or "janitor" => GetString("Cleaner"), "醫生" => GetString("Medicaler"), "占卜師" or "占卜" or "ft" => GetString("Divinator"), @@ -3494,7 +3494,7 @@ internal static class ChatCommands "隱匿者" or "隐匿" or "隐身" or "隐身人" or "印尼" => GetString("Swooper"), "船鬼" or "cp" => GetString("Crewpostor"), "嗜血騎士" or "血骑" or "骑士" or "bk" => GetString("BloodKnight"), - "賭徒" => GetString("Totocalcio"), + "賭徒" => GetString("Follower"), "分散机" => GetString("Disperser"), "和平之鸽" or "和平之鴿" or "和平的鸽子" or "和平" or "dop" or "dove of peace" => GetString("DovesOfNeace"), "持槍" or "持械" or "手长" => GetString("Reach"), diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index c555de4a2..326939bd1 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -147,9 +147,9 @@ internal static class GameEndChecker .Select(pc => pc.PlayerId)); break; - case CustomWinner.Succubus: + case CustomWinner.Cultist: WinnerIds.UnionWith(Main.AllPlayerControls - .Where(pc => pc.Is(CustomRoles.Succubus) || pc.Is(CustomRoles.Charmed)) + .Where(pc => pc.Is(CustomRoles.Cultist) || pc.Is(CustomRoles.Charmed)) .Select(pc => pc.PlayerId)); break; @@ -218,8 +218,8 @@ internal static class GameEndChecker case CustomRoles.Sunnyboy when !pc.IsAlive(): case CustomRoles.Maverick when pc.IsAlive() && roleBase is Maverick mr && mr.NumOfKills >= Maverick.MinKillsToWin.GetInt(): case CustomRoles.Provocateur when Provocateur.Provoked.TryGetValue(pc.PlayerId, out byte tar) && !WinnerIds.Contains(tar): - case CustomRoles.FFF when (roleBase as FFF).IsWon: - case CustomRoles.Totocalcio when roleBase is Totocalcio tc && tc.BetPlayer != byte.MaxValue && (WinnerIds.Contains(tc.BetPlayer) || (Main.PlayerStates.TryGetValue(tc.BetPlayer, out PlayerState ps) && (WinnerRoles.Contains(ps.MainRole) || (WinnerTeam == CustomWinner.Bloodlust && ps.SubRoles.Contains(CustomRoles.Bloodlust))))): + case CustomRoles.Hater when (roleBase as Hater).IsWon: + case CustomRoles.Follower when roleBase is Follower tc && tc.BetPlayer != byte.MaxValue && (WinnerIds.Contains(tc.BetPlayer) || (Main.PlayerStates.TryGetValue(tc.BetPlayer, out PlayerState ps) && (WinnerRoles.Contains(ps.MainRole) || (WinnerTeam == CustomWinner.Bloodlust && ps.SubRoles.Contains(CustomRoles.Bloodlust))))): case CustomRoles.Romantic when WinnerIds.Contains(Romantic.PartnerId) || (Main.PlayerStates.TryGetValue(Romantic.PartnerId, out PlayerState ps1) && (WinnerRoles.Contains(ps1.MainRole) || (WinnerTeam == CustomWinner.Bloodlust && ps1.SubRoles.Contains(CustomRoles.Bloodlust)))): case CustomRoles.Lawyer when Lawyer.Target.TryGetValue(pc.PlayerId, out byte lawyertarget) && (WinnerIds.Contains(lawyertarget) || (Main.PlayerStates.TryGetValue(lawyertarget, out PlayerState ps2) && (WinnerRoles.Contains(ps2.MainRole) || (WinnerTeam == CustomWinner.Bloodlust && ps2.SubRoles.Contains(CustomRoles.Bloodlust))))): case CustomRoles.Postman when (roleBase as Postman).IsFinished: @@ -447,7 +447,7 @@ internal static class GameEndChecker case CustomRoles.Sunnyboy when state.IsDead: case CustomRoles.Maverick when !state.IsDead && state.Role is Maverick mr && mr.NumOfKills >= Maverick.MinKillsToWin.GetInt(): case CustomRoles.Provocateur when Provocateur.Provoked.TryGetValue(state.Player.PlayerId, out byte tar) && !WinnerIds.Contains(tar): - case CustomRoles.FFF when ((FFF)state.Role).IsWon: + case CustomRoles.Hater when ((Hater)state.Role).IsWon: case CustomRoles.Postman when ((Postman)state.Role).IsFinished: case CustomRoles.Dealer when ((Dealer)state.Role).IsWon: case CustomRoles.Impartial when ((Impartial)state.Role).IsWon: @@ -625,7 +625,7 @@ internal static class GameEndChecker else if (x.Is(Team.Crewmate)) crew++; else if (x.Is(Team.Coven)) coven++; - if (x.Is(CustomRoles.Charmed)) roleCounts[(null, CustomWinner.Succubus)]++; + if (x.Is(CustomRoles.Charmed)) roleCounts[(null, CustomWinner.Cultist)]++; if (x.Is(CustomRoles.Undead)) roleCounts[(null, CustomWinner.Necromancer)]++; if (x.Is(CustomRoles.Sidekick)) roleCounts[(null, CustomWinner.Jackal)]++; if (x.Is(CustomRoles.Recruit)) roleCounts[(null, CustomWinner.Jackal)]++; diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs index 1787ff6ce..ba6005a9c 100644 --- a/Patches/HudPatch.cs +++ b/Patches/HudPatch.cs @@ -590,7 +590,7 @@ internal static class SetHudActivePatch case CustomRoles.Deputy: case CustomRoles.Monarch: case CustomRoles.Pelican: - case CustomRoles.FFF: + case CustomRoles.Hater: case CustomRoles.Medic: case CustomRoles.Demon: case CustomRoles.DarkHide: diff --git a/Patches/HudSpritePatch.cs b/Patches/HudSpritePatch.cs index a056af3d1..3f76dc65e 100644 --- a/Patches/HudSpritePatch.cs +++ b/Patches/HudSpritePatch.cs @@ -341,7 +341,7 @@ public static class HudSpritePatch newKillButton = CustomButton.Get("Sidekick"); break; } - case CustomRoles.Succubus: + case CustomRoles.Cultist: { newKillButton = CustomButton.Get("Subbus"); break; diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index da444fca6..7abb11bc4 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -676,7 +676,7 @@ internal static class BeginCrewmatePatch CustomRoles.Sheriff => FastDestroyableSingleton.Instance.HnSOtherYeehawSfx, - CustomRoles.FFF or + CustomRoles.Hater or CustomRoles.Opportunist or CustomRoles.Revolutionist => GetIntroSound(RoleTypes.Crewmate), diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index 0f415278b..2d7534a03 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -1097,7 +1097,7 @@ internal static class MeetingHudStartPatch if (seer.Data.IsDead && Medic.InProtect(target.PlayerId) && !seer.Is(CustomRoles.Medic)) sb.Append(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medic), " ●")); - sb.Append(Totocalcio.TargetMark(seer, target)); + sb.Append(Follower.TargetMark(seer, target)); sb.Append(Romantic.TargetMark(seer, target)); sb.Append(Lawyer.LawyerMark(seer, target)); sb.Append(PlagueDoctor.GetMarkOthers(seer, target)); diff --git a/Patches/OnGameStartedPatch.cs b/Patches/OnGameStartedPatch.cs index 4eb425fb4..aae3358ef 100644 --- a/Patches/OnGameStartedPatch.cs +++ b/Patches/OnGameStartedPatch.cs @@ -900,7 +900,7 @@ internal static class StartGameHostPatch } } - if (!overrideLovers && CustomRoles.Lovers.IsEnable() && (CustomRoles.FFF.IsEnable() ? -1 : IRandom.Instance.Next(1, 100)) <= Lovers.LoverSpawnChances.GetInt()) AssignLoversRolesFromList(); + if (!overrideLovers && CustomRoles.Lovers.IsEnable() && (CustomRoles.Hater.IsEnable() ? -1 : IRandom.Instance.Next(1, 100)) <= Lovers.LoverSpawnChances.GetInt()) AssignLoversRolesFromList(); // Add-on assignment PlayerControl[] aapc = Main.AllAlivePlayerControls.Shuffle(); @@ -1292,7 +1292,7 @@ internal static class StartGameHostPatch return; } - List allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.FFF) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.Is(CustomRoleTypes.Coven) || Lovers.CovenCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList(); + List allPlayers = Main.AllPlayerControls.Where(pc => (!Main.NeverSpawnTogetherCombos.TryGetValue(OptionItem.CurrentPreset, out Dictionary> bannedCombos) || bannedCombos.All(x => !pc.Is(x.Key) || !x.Value.Contains(CustomRoles.Lovers))) && !pc.Is(CustomRoles.GM) && (!pc.HasSubRole() || pc.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !pc.Is(CustomRoles.Dictator) && !pc.Is(CustomRoles.God) && !pc.Is(CustomRoles.Hater) && !pc.Is(CustomRoles.Bomber) && !pc.Is(CustomRoles.Nuker) && !pc.Is(CustomRoles.Curser) && !pc.Is(CustomRoles.Provocateur) && !pc.Is(CustomRoles.Altruist) && (!pc.IsCrewmate() || Lovers.CrewCanBeInLove.GetBool()) && (!pc.GetCustomRole().IsNeutral() || Lovers.NeutralCanBeInLove.GetBool()) && (!pc.Is(CustomRoleTypes.Coven) || Lovers.CovenCanBeInLove.GetBool()) && (!pc.IsImpostor() || Lovers.ImpCanBeInLove.GetBool())).ToList(); const CustomRoles role = CustomRoles.Lovers; int count = Math.Clamp(rawCount, 0, allPlayers.Count); if (rawCount == -1) count = Math.Clamp(role.GetCount(), 0, allPlayers.Count); diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 4f3a2f55d..5a2d94f03 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -1929,7 +1929,7 @@ internal static class FixedUpdatePatch break; } - Mark.Append(Totocalcio.TargetMark(seer, target)); + Mark.Append(Follower.TargetMark(seer, target)); Mark.Append(Romantic.TargetMark(seer, target)); Mark.Append(Lawyer.LawyerMark(seer, target)); Mark.Append(Marshall.GetWarningMark(seer, target)); diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 1cc807174..9b2032a7c 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -298,7 +298,7 @@ "Innocent": "Innocent", "Pelican": "Pelican", "Revolutionist": "Revolutionist", - "FFF": "Hater", + "Hater": "Hater", "Demon": "Demon", "DarkHide": "Stalker", "Workaholic": "Workaholic", @@ -309,8 +309,8 @@ "Pestilence": "Pestilence", "Poisoner": "Poisoner", "Sidekick": "Sidekick", - "Totocalcio": "Follower", - "Succubus": "Cultist", + "Follower": "Follower", + "Cultist": "Cultist", "HexMaster": "Hex Master", "Wraith": "Wraith", "SerialKiller": "Serial Killer", @@ -578,7 +578,7 @@ "InnocentInfo": "Get someone ejected by making them kill you", "PelicanInfo": "Eat all players", "RevolutionistInfo": "Recruit players to win with you", - "FFFInfo": "Kill Lovers and Converted players", + "HaterInfo": "Kill Lovers and Converted players", "DemonInfo": "Consume blood volumes", "DarkHideInfo": "Your kills cause power outages", "WorkaholicInfo": "Finish all tasks to solo win!", @@ -589,8 +589,8 @@ "PestilenceInfo": "You're unstoppable", "PoisonerInfo": "Your kills are delayed", "SidekickInfo": "Help the Jackal win", - "TotocalcioInfo": "Follow a player and help them", - "SuccubusInfo": "Charm everyone", + "FollowerInfo": "Follow a player and help them", + "CultistInfo": "Charm everyone", "HexMasterInfo": "Hex players to kill them in meetings", "WraithInfo": "Vent to go invisible temporarily", "SerialKillerInfo": "Kill everyone to win!", @@ -808,7 +808,7 @@ "InnocentInfoLong": "(Neutrals):\\nInnocent players can use the kill button to plant another player, causing them to die immediately. If the planted player is voted out in a meeting, the Innocent wins. Note that the Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\\nAs the Pelican, you can use the kill button and swallow a player alive. Swallowed players are teleported out of the map and cannot interact with the game. In case of an emergency meeting or reporting a dead body, all swallowed players die instantly. This is not a standard way to kill, and role skills such as the Bodyguard and Veteran are ineffective. If you die or disconnect, all previously swallowed players are returned to your location.", "RevolutionistInfoLong": "(Neutrals):\\nThe Revolutionist can recruit players by clicking the kill button on them and following them for a few seconds. If recruiting is successful, a shield animation is shown as a reminder. Players recruited are likely to be immediately killed, a probability set by the host. The Revolutionist and all recruited players win if the specified number of players vent within the set time, otherwise, the recruited player dies. The Revolutionist dies if killed during a countdown or at a meeting. Players who died after recruitment can still win with the Revolutionist.", - "FFFInfoLong": "(Neutrals):\\nAs the Hater, you can kill as often as you want with no cooldown and have impostor vision. You can only kill Lovers, recruited players, and recruiting roles, or you will die. Winning is possible if you kill at least one player during the game.", + "HaterInfoLong": "(Neutrals):\\nAs the Hater, you can kill as often as you want with no cooldown and have impostor vision. You can only kill Lovers, recruited players, and recruiting roles, or you will die. Winning is possible if you kill at least one player during the game.", "DemonInfoLong": "(Neutrals):\\nDemon has a unique health-based killing system, and killing takes effect when one's health is exhausted. If a Demon's health is consumed but they are not killed, the murderer will see a shield animation as a reminder.", "DarkHideInfoLong": "(Neutrals):\\nThe Stalker can kill anyone and cause electricity sabotage. They cannot vent. If the Stalker is alive and the Impostor or Crewmate wins, the Stalker wins alone.", "WorkaholicInfoLong": "(Neutrals):\\nWorkaholics win by completing more tasks, maybe even after their death.", @@ -819,8 +819,8 @@ "BloodKnightInfoLong": "(Neutrals):\\nBlood Knights win if they're the last killing role alive and crewmates are equal or less than them. They gain temporary shields after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Neutrals):\\nPlague everyone using your kill button to turn into Pestilence. Once you turn into Pestilence, you will become immortal (for the most part) and gain the ability to kill.\\nIn addition to this, After turning into Pestilence, you will kill anyone who tries to kill you directly.\\n\\nYou can only win if you turn into Pestilence.", "PestilenceInfoLong": "(Neutrals):\\nAs Pestilence, you're an unstoppable machine. Any attack towards you will be reflected towards them. Indirect kills don't even kill you.\\n\\nOnly way to kill Pestilence is by vote, or by it misguessing.", - "TotocalcioInfoLong": "(Neutrals):\\nThe Follower can start following someone by using their Kill button and switch targets by using it again. If the Follower's target wins, the Follower will win, too. They can even win after they die.", - "SuccubusInfoLong": "(Neutrals):\\nIf there are more Cultists than Crewmates and only these two teams remain, the Cultist team wins. The Cultist can charm a non-neutral player by pressing the kill button, making them a part of the Cultist team with new victory conditions.", + "FollowerInfoLong": "(Neutrals):\\nThe Follower can start following someone by using their Kill button and switch targets by using it again. If the Follower's target wins, the Follower will win, too. They can even win after they die.", + "CultistInfoLong": "(Neutrals):\\nIf there are more Cultists than Crewmates and only these two teams remain, the Cultist team wins. The Cultist can charm a non-neutral player by pressing the kill button, making them a part of the Cultist team with new victory conditions.", "HexMasterInfoLong": "(Neutrals):\\nAs the Hex Master, you can hex players or kill them. Hexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutrals):\\nAs the Wraith, you can Vent/Vanish to go invisible temporarily. You can kill while being invisible.\\n\\nKill; everyone to win.", "SerialKillerInfoLong": "(Neutrals):\\nAs the Serial Killer, your job is to murder everyone to win simply.", @@ -1771,21 +1771,21 @@ "RoleBlockDuration": "Role Block Duration", "RoleBlockCooldown": "Role Block Cooldown", "BKProtectDuration": "Protection Duration", - "TotocalcioMaxBetTimes": "Maximum Number of Follows", - "TotocalcioBetCooldown": "Follow Cooldown", - "TotocalcioMaxBetCooldown": "Maximum Follow Cooldown", - "TotocalcioBetCooldownIncrese": "Increase Cooldown per 1 follow by", - "TotocalcioKnowTargetRole": "Follower knows their target's role", - "TotocalcioBetTargetKnowTotocalcio": "Follower target knows who the Follower is", + "FollowerMaxBetTimes": "Maximum Number of Follows", + "FollowerBetCooldown": "Follow Cooldown", + "FollowerMaxBetCooldown": "Maximum Follow Cooldown", + "FollowerBetCooldownIncrese": "Increase Cooldown per 1 follow by", + "FollowerKnowTargetRole": "Follower knows their target's role", + "FollowerBetTargetKnowFollower": "Follower target knows who the Follower is", "DivinatorHideVote": "Hide Fortune Teller's Votes", "ShowSpecificRole": "Know specific roles on Task Completion", - "SuccubusCharmCooldown": "Charm Cooldown", - "SuccubusCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", - "SuccubusCharmMax": "Maximum Number Of Charm", - "SuccubusKnowTargetRole": "Know Charmed Player's Role", - "SuccubusTargetKnowOtherTarget": "Charmed players know each other", - "SuccubusCanCharmNeutral": "Neutral Roles can be Charmed", - "CharmedDiesOnSuccubusDeath": "Charmed Players Die When <#cf6acd>Cultist Dies", + "CultistCharmCooldown": "Charm Cooldown", + "CultistCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", + "CultistCharmMax": "Maximum Number Of Charm", + "CultistKnowTargetRole": "Know Charmed Player's Role", + "CultistTargetKnowOtherTarget": "Charmed players know each other", + "CultistCanCharmNeutral": "Neutral Roles can be Charmed", + "CharmedDiesOnCultistDeath": "Charmed Players Die When <#cf6acd>Cultist Dies", "InfectiousBiteCooldown": "Infect Cooldown", "KnowTargetRole": "Knows role of target", "TargetKnowsLawyer": "Target knows their Lawyer", @@ -1804,7 +1804,7 @@ "ContagiousPlayersCanKillEachOther": "Contagious players can kill each other", "CharmedCountMode": "Charmed players count as", "CharmedCountMode.None": "Nothing", - "CharmedCountMode.Succubus": "Cultist", + "CharmedCountMode.Cultist": "Cultist", "CharmedCountMode.Original": "Original Team", "ResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", "ResetKillCooldownOn": "Kill Cooldown On Reset", @@ -2255,11 +2255,11 @@ "BKOffsetKill": "Someone tried killing you", "MedicKillerTryBrokenShieldTargetForMedic": "Someone tried killing the player you shielded!", "MedicKillerTryBrokenShieldTargetForTarget": "Someone tried killing you!", - "TotocalcioBetPlayer": "You're now following your target", - "TotocalcioBetOnYou": "The Follower is now following you", - "SuccubusCharmedPlayer": "You successfully charmed a player", - "CharmedBySuccubus": "You have been charmed by the Cultist", - "SuccubusInvalidTarget": "Target cannot be charmed", + "FollowerBetPlayer": "You're now following your target", + "FollowerBetOnYou": "The Follower is now following you", + "CultistCharmedPlayer": "You successfully charmed a player", + "CharmedByCultist": "You have been charmed by the Cultist", + "CultistInvalidTarget": "Target cannot be charmed", "KillBaitNotify": "You'll self-report in {0}s", "InfectiousInvalidTarget": "Target cannot be infected", "BittenByInfectious": "You were infected by the Infectious!", @@ -3164,7 +3164,7 @@ "PursuerButtonText": "Trick", "GangsterButtonText": "Recruit", "RevolutionistDrawButtonText": "Win over", - "FFFButtonText": "Hatred", + "HaterButtonText": "Hatred", "MedicalerButtonText": "Protect", "DemonButtonText": "Attack", "ImperiusCurseButtonText": "Teleport", @@ -3194,10 +3194,10 @@ "SheriffKillButtonText": "Shoot", "ArsonistVentButtonText": "Ignite", "RevolutionistVentButtonText": "Revolution", - "TotocalcioKillButtonText": "Follow", + "FollowerKillButtonText": "Follow", "RomanticKillButtonText": "Romance", "DovesOfNeaceVentButtonText": "Reset", - "SuccubusKillButtonText": "Charm", + "CultistKillButtonText": "Charm", "HangmanKillButtonTextDuringSS": "Strangle", "InfectiousKillButtonText": "Infect", "MonarchKillButtonText": "Knight", @@ -3645,15 +3645,15 @@ "DruidTriggerPlaceDelayOpt": "Trigger Place Delay (when not using pets)", "DruidTimeLeft": "Placing trigger in {0}s", "DruidTriggerTriggered": "Trigger {0} was triggered by someone! {1}", - "FFFMisFireKillTarget": "Misfire Kills Target", - "FFFChooseConverted": "Can Kill Converted Players", - "FFFCanKillMadmate": "Can Kill Madmates", - "FFFCanKillCharmed": "Can Kill Charmed Players", - "FFFCanKillLovers": "Can Kill Lovers", - "FFFCanKillSidekick": "Can Kill Sidekicks", - "FFFCanKillEgoist": "Can Kill Egoist", - "FFFCanKillContagious": "Can Kill Contagious Players", - "FFFCanKillUndead": "Can Kill Undead Players", + "HaterMisFireKillTarget": "Misfire Kills Target", + "HaterChooseConverted": "Can Kill Converted Players", + "HaterCanKillMadmate": "Can Kill Madmates", + "HaterCanKillCharmed": "Can Kill Charmed Players", + "HaterCanKillLovers": "Can Kill Lovers", + "HaterCanKillSidekick": "Can Kill Sidekicks", + "HaterCanKillEgoist": "Can Kill Egoist", + "HaterCanKillContagious": "Can Kill Contagious Players", + "HaterCanKillUndead": "Can Kill Undead Players", "Mafioso": "Mafioso", "MafiosoInfo": "With Each Tier, you're more Powerful", "MafiosoInfoLong": "(Impostors):\\nAs the Mafioso, you gain XP by killing, sabotaging, entering a vent you haven't entered that round yet, or by seeing a player not on your team get ejected. When you have 100 XP, your tier levels up. With each tier, you get progressively more powerful:\\n\\nTier 0: Regular impostor, higher kill cooldown, short kill range\\nTier 1: Long kill range, normal kill cooldown\\nTier 2: Lower kill cooldown\\nTier 3: Dual pistols: you have 2 separate higher kill cooldowns, if at least one of them is up, you can kill!\\nTier 4: Normal kill cooldown on both pistols\\nTier 5: Delayed kills", @@ -9692,9 +9692,9 @@ "CanVentAfterNecronomicon": "Can Vent <#00ffff>After Receiving The <#7b3fbb>Necronomicon", "YouReceivedTheNecronomicon": "You have received the <{0}>Necronomicon! This grants you the ability to kill normally, and other abilities based on your role.", "PlayerReceivedTheNecronomicon": "{0} has received the <{1}>Necronomicon!\\nNow, {2} Coven members have the Necronomicon: {3}", - "RegularCoven": "Coven Member", - "RegularCovenInfo": "Win with the Coven", - "RegularCovenInfoLong": "(Coven):\\nYour previous Coven role was lost. You are now a regular Coven member. You still win with the Coven, but you don't have any abilities, cannot kill, and cannot get the Necronomicon.\\nIf the Coven Leader dies, you become the new Coven Leader.", + "CovenMember": "Coven Member", + "CovenMemberInfo": "Win with the Coven", + "CovenMemberInfoLong": "(Coven):\\nYour previous Coven role was lost. You are now a regular Coven member. You still win with the Coven, but you don't have any abilities, cannot kill, and cannot get the Necronomicon.\\nIf the Coven Leader dies, you become the new Coven Leader.", "CovenLeader": "Coven Leader", "CovenLeaderInfo": "Lead the Coven & Kill", "CovenLeaderInfoLong": "(Coven):\\nYou will always spawn if the Coven is enabled. You are the only Coven member who can directly kill. You gain the Necronomicon first. When your powers are enhanced by the Necronomicon, your kill cooldown is halved, and you gain a long kill distance.", diff --git a/Roles/Coven/RegularCoven.cs b/Roles/Coven/CovenMember.cs similarity index 96% rename from Roles/Coven/RegularCoven.cs rename to Roles/Coven/CovenMember.cs index 089b92406..790c8ef63 100644 --- a/Roles/Coven/RegularCoven.cs +++ b/Roles/Coven/CovenMember.cs @@ -1,6 +1,6 @@ namespace EHR.Coven; -public class RegularCoven : Coven +public class CovenMember : Coven { public static bool On; diff --git a/Roles/Crewmate/Bane.cs b/Roles/Crewmate/Bane.cs index 650e5b355..d6e87bc45 100644 --- a/Roles/Crewmate/Bane.cs +++ b/Roles/Crewmate/Bane.cs @@ -24,7 +24,7 @@ public class Bane : RoleBase { if (killer == null || killer.Is(CustomRoles.Bloodlust)) return; - CustomRoles erasedRole = killer.IsImpostor() ? CustomRoles.ImpostorEHR : killer.IsCrewmate() ? CustomRoles.CrewmateEHR : killer.Is(Team.Coven) ? CustomRoles.RegularCoven : CustomRoles.Amnesiac; + CustomRoles erasedRole = killer.IsImpostor() ? CustomRoles.ImpostorEHR : killer.IsCrewmate() ? CustomRoles.CrewmateEHR : killer.Is(Team.Coven) ? CustomRoles.CovenMember : CustomRoles.Amnesiac; killer.RpcSetCustomRole(erasedRole); killer.RpcChangeRoleBasis(erasedRole); } diff --git a/Roles/Crewmate/NiceEraser.cs b/Roles/Crewmate/NiceEraser.cs index 10453de6c..9f2d3defc 100644 --- a/Roles/Crewmate/NiceEraser.cs +++ b/Roles/Crewmate/NiceEraser.cs @@ -114,7 +114,7 @@ internal class NiceEraser : RoleBase PlayerControl player = Utils.GetPlayerById(pc); if (player == null) return; - CustomRoles erasedRole = player.IsImpostor() ? CustomRoles.ImpostorEHR : player.IsCrewmate() ? CustomRoles.CrewmateEHR : player.Is(Team.Coven) ? CustomRoles.RegularCoven : CustomRoles.Amnesiac; + CustomRoles erasedRole = player.IsImpostor() ? CustomRoles.ImpostorEHR : player.IsCrewmate() ? CustomRoles.CrewmateEHR : player.Is(Team.Coven) ? CustomRoles.CovenMember : CustomRoles.Amnesiac; player.RpcSetCustomRole(erasedRole); player.RpcChangeRoleBasis(erasedRole); player.Notify(GetString("LostRoleByNiceEraser")); diff --git a/Roles/Crewmate/ParityCop.cs b/Roles/Crewmate/ParityCop.cs index 2d002ed89..22476790a 100644 --- a/Roles/Crewmate/ParityCop.cs +++ b/Roles/Crewmate/ParityCop.cs @@ -320,7 +320,7 @@ public class ParityCop : RoleBase switch (firstRoleClass) { case Lawyer when Lawyer.Target[first.PlayerId] == second.PlayerId: - case Totocalcio tc when tc.BetPlayer == second.PlayerId: + case Follower tc when tc.BetPlayer == second.PlayerId: case Romantic when Romantic.HasPickedPartner && Romantic.PartnerId == second.PlayerId: case Necromancer when secondRoleClass is Deathknight: return true; @@ -329,7 +329,7 @@ public class ParityCop : RoleBase switch (secondRoleClass) { case Lawyer when Lawyer.Target[second.PlayerId] == first.PlayerId: - case Totocalcio tc when tc.BetPlayer == first.PlayerId: + case Follower tc when tc.BetPlayer == first.PlayerId: case Romantic when Romantic.HasPickedPartner && Romantic.PartnerId == first.PlayerId: case Necromancer when firstRoleClass is Deathknight: return true; diff --git a/Roles/Impostor/Eraser.cs b/Roles/Impostor/Eraser.cs index c53b80d54..b6960679d 100644 --- a/Roles/Impostor/Eraser.cs +++ b/Roles/Impostor/Eraser.cs @@ -152,7 +152,7 @@ internal class Eraser : RoleBase 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.RegularCoven : CustomRoles.Amnesiac; + 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")); diff --git a/Roles/Neutral/Amnesiac.cs b/Roles/Neutral/Amnesiac.cs index fa351d3fb..cd9dc88fc 100644 --- a/Roles/Neutral/Amnesiac.cs +++ b/Roles/Neutral/Amnesiac.cs @@ -27,7 +27,7 @@ public class Amnesiac : RoleBase [ CustomRoles.Amnesiac, CustomRoles.Pursuer, - CustomRoles.Totocalcio, + CustomRoles.Follower, CustomRoles.Maverick ]; @@ -232,7 +232,7 @@ public class Amnesiac : RoleBase switch (role) { case CustomRoles.Virus: - case CustomRoles.Succubus: + case CustomRoles.Cultist: Achievements.Type.UnderNewManagement.Complete(); break; case CustomRoles.Deathknight: diff --git a/Roles/Neutral/Succubus.cs b/Roles/Neutral/Cultist.cs similarity index 66% rename from Roles/Neutral/Succubus.cs rename to Roles/Neutral/Cultist.cs index 6349dd65d..e6fa60fdc 100644 --- a/Roles/Neutral/Succubus.cs +++ b/Roles/Neutral/Cultist.cs @@ -1,168 +1,168 @@ -using System.Collections.Generic; -using System.Linq; -using AmongUs.GameOptions; -using EHR.Modules; -using Hazel; -using static EHR.Options; -using static EHR.Translator; - -namespace EHR.Neutral; - -public class Succubus : RoleBase -{ - private const int Id = 11200; - private static List PlayerIdList = []; - - private static OptionItem CharmCooldown; - private static OptionItem CharmCooldownIncrese; - private static OptionItem CharmMax; - private static OptionItem KnowTargetRole; - public static OptionItem TargetKnowOtherTarget; - private static OptionItem CanCharmNeutral; - public static OptionItem CharmedCountMode; - private static OptionItem CharmedDiesOnSuccubusDeath; - - private static readonly string[] CharmedCountModeStrings = - [ - "CharmedCountMode.None", - "CharmedCountMode.Succubus", - "CharmedCountMode.Original" - ]; - - public override bool IsEnable => PlayerIdList.Count > 0; - - public override void SetupCustomOption() - { - SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Succubus); - - CharmCooldown = new FloatOptionItem(Id + 10, "SuccubusCharmCooldown", new(0f, 60f, 0.5f), 30f, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]) - .SetValueFormat(OptionFormat.Seconds); - - CharmCooldownIncrese = new FloatOptionItem(Id + 11, "SuccubusCharmCooldownIncrese", new(0f, 180f, 0.5f), 10f, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]) - .SetValueFormat(OptionFormat.Seconds); - - CharmMax = new IntegerOptionItem(Id + 12, "SuccubusCharmMax", new(1, 15, 1), 15, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]) - .SetValueFormat(OptionFormat.Times); - - KnowTargetRole = new BooleanOptionItem(Id + 13, "SuccubusKnowTargetRole", true, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]); - - TargetKnowOtherTarget = new BooleanOptionItem(Id + 14, "SuccubusTargetKnowOtherTarget", true, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]); - - CharmedCountMode = new StringOptionItem(Id + 15, "CharmedCountMode", CharmedCountModeStrings, 0, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]); - - CanCharmNeutral = new BooleanOptionItem(Id + 16, "SuccubusCanCharmNeutral", false, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]); - - CharmedDiesOnSuccubusDeath = new BooleanOptionItem(Id + 17, "CharmedDiesOnSuccubusDeath", false, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Succubus]); - } - - public override void Init() - { - PlayerIdList = []; - } - - public override void Add(byte playerId) - { - PlayerIdList.Add(playerId); - playerId.SetAbilityUseLimit(CharmMax.GetFloat()); - } - - public override void Remove(byte playerId) - { - PlayerIdList.Remove(playerId); - } - - public override void SetKillCooldown(byte id) - { - Main.AllPlayerKillCooldown[id] = id.GetAbilityUseLimit() >= 1 ? CharmCooldown.GetFloat() + ((CharmMax.GetInt() - id.GetAbilityUseLimit()) * CharmCooldownIncrese.GetFloat()) : 300f; - } - - public override bool CanUseKillButton(PlayerControl player) - { - return player.IsAlive() && player.GetAbilityUseLimit() >= 1; - } - - public override bool CanUseImpostorVentButton(PlayerControl pc) - { - return false; - } - - public override void ApplyGameOptions(IGameOptions opt, byte playerId) - { - opt.SetVision(false); - } - - public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) - { - if (killer.GetAbilityUseLimit() < 1) return false; - - if (CanBeCharmed(target)) - { - killer.RpcRemoveAbilityUse(); - - target.RpcSetCustomRole(CustomRoles.Charmed); - - var sender = CustomRpcSender.Create("Succubus.OnCheckMurder", SendOption.Reliable); - var hasValue = false; - - hasValue |= sender.Notify(killer, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Succubus), GetString("SuccubusCharmedPlayer"))); - hasValue |= sender.SetKillCooldown(killer); - hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared); - if (cleared) hasValue = false; - - hasValue |= sender.Notify(target, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Succubus), GetString("CharmedBySuccubus"))); - hasValue |= sender.RpcGuardAndKill(target, killer); - hasValue |= sender.RpcGuardAndKill(target, target); - hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared); - if (cleared) hasValue = false; - - sender.SendMessage(!hasValue); - - Logger.Info("SetRole:" + target?.Data?.PlayerName + " = " + target.GetCustomRole() + " + " + CustomRoles.Charmed, "Assign " + CustomRoles.Charmed); - - if (killer.IsLocalPlayer()) - Achievements.Type.YoureMyFriendNow.Complete(); - - return false; - } - - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Succubus), GetString("SuccubusInvalidTarget"))); - - return false; - } - - public override bool KnowRole(PlayerControl player, PlayerControl target) - { - if (base.KnowRole(player, target)) return true; - if (player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Succubus)) return true; - if (KnowTargetRole.GetBool() && player.Is(CustomRoles.Succubus) && target.Is(CustomRoles.Charmed)) return true; - return TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed); - } - - public static bool CanBeCharmed(PlayerControl pc) - { - return pc != null && (pc.IsCrewmate() || pc.IsImpostor() || - (CanCharmNeutral.GetBool() && (pc.GetCustomRole().IsNeutral() || pc.IsNeutralKiller()))) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Curser) && !pc.Is(Team.Coven); - } - - public override void OnFixedUpdate(PlayerControl pc) - { - if (!CharmedDiesOnSuccubusDeath.GetBool() || !GameStates.IsInTask || !IsEnable) return; - - if (pc == null || pc.IsAlive()) return; - - foreach (PlayerControl charmed in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Charmed))) charmed.Suicide(realKiller: pc); - } - - public override void SetButtonTexts(HudManager hud, byte id) - { - hud.KillButton?.OverrideText(GetString("SuccubusKillButtonText")); - } +using System.Collections.Generic; +using System.Linq; +using AmongUs.GameOptions; +using EHR.Modules; +using Hazel; +using static EHR.Options; +using static EHR.Translator; + +namespace EHR.Neutral; + +public class Cultist : RoleBase +{ + private const int Id = 11200; + private static List PlayerIdList = []; + + private static OptionItem CharmCooldown; + private static OptionItem CharmCooldownIncrese; + private static OptionItem CharmMax; + private static OptionItem KnowTargetRole; + public static OptionItem TargetKnowOtherTarget; + private static OptionItem CanCharmNeutral; + public static OptionItem CharmedCountMode; + private static OptionItem CharmedDiesOnCultistDeath; + + private static readonly string[] CharmedCountModeStrings = + [ + "CharmedCountMode.None", + "CharmedCountMode.Cultist", + "CharmedCountMode.Original" + ]; + + public override bool IsEnable => PlayerIdList.Count > 0; + + public override void SetupCustomOption() + { + SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Cultist); + + CharmCooldown = new FloatOptionItem(Id + 10, "CultistCharmCooldown", new(0f, 60f, 0.5f), 30f, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]) + .SetValueFormat(OptionFormat.Seconds); + + CharmCooldownIncrese = new FloatOptionItem(Id + 11, "CultistCharmCooldownIncrese", new(0f, 180f, 0.5f), 10f, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]) + .SetValueFormat(OptionFormat.Seconds); + + CharmMax = new IntegerOptionItem(Id + 12, "CultistCharmMax", new(1, 15, 1), 15, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]) + .SetValueFormat(OptionFormat.Times); + + KnowTargetRole = new BooleanOptionItem(Id + 13, "CultistKnowTargetRole", true, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]); + + TargetKnowOtherTarget = new BooleanOptionItem(Id + 14, "CultistTargetKnowOtherTarget", true, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]); + + CharmedCountMode = new StringOptionItem(Id + 15, "CharmedCountMode", CharmedCountModeStrings, 0, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]); + + CanCharmNeutral = new BooleanOptionItem(Id + 16, "CultistCanCharmNeutral", false, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]); + + CharmedDiesOnCultistDeath = new BooleanOptionItem(Id + 17, "CharmedDiesOnCultistDeath", false, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Cultist]); + } + + public override void Init() + { + PlayerIdList = []; + } + + public override void Add(byte playerId) + { + PlayerIdList.Add(playerId); + playerId.SetAbilityUseLimit(CharmMax.GetFloat()); + } + + public override void Remove(byte playerId) + { + PlayerIdList.Remove(playerId); + } + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = id.GetAbilityUseLimit() >= 1 ? CharmCooldown.GetFloat() + ((CharmMax.GetInt() - id.GetAbilityUseLimit()) * CharmCooldownIncrese.GetFloat()) : 300f; + } + + public override bool CanUseKillButton(PlayerControl player) + { + return player.IsAlive() && player.GetAbilityUseLimit() >= 1; + } + + public override bool CanUseImpostorVentButton(PlayerControl pc) + { + return false; + } + + public override void ApplyGameOptions(IGameOptions opt, byte playerId) + { + opt.SetVision(false); + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + if (killer.GetAbilityUseLimit() < 1) return false; + + if (CanBeCharmed(target)) + { + killer.RpcRemoveAbilityUse(); + + target.RpcSetCustomRole(CustomRoles.Charmed); + + var sender = CustomRpcSender.Create("Cultist.OnCheckMurder", SendOption.Reliable); + var hasValue = false; + + hasValue |= sender.Notify(killer, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cultist), GetString("CultistCharmedPlayer"))); + hasValue |= sender.SetKillCooldown(killer); + hasValue |= sender.NotifyRolesSpecific(killer, target, out sender, out bool cleared); + if (cleared) hasValue = false; + + hasValue |= sender.Notify(target, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cultist), GetString("CharmedByCultist"))); + hasValue |= sender.RpcGuardAndKill(target, killer); + hasValue |= sender.RpcGuardAndKill(target, target); + hasValue |= sender.NotifyRolesSpecific(target, killer, out sender, out cleared); + if (cleared) hasValue = false; + + sender.SendMessage(!hasValue); + + Logger.Info("SetRole:" + target?.Data?.PlayerName + " = " + target.GetCustomRole() + " + " + CustomRoles.Charmed, "Assign " + CustomRoles.Charmed); + + if (killer.IsLocalPlayer()) + Achievements.Type.YoureMyFriendNow.Complete(); + + return false; + } + + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cultist), GetString("CultistInvalidTarget"))); + + return false; + } + + public override bool KnowRole(PlayerControl player, PlayerControl target) + { + if (base.KnowRole(player, target)) return true; + if (player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Cultist)) return true; + if (KnowTargetRole.GetBool() && player.Is(CustomRoles.Cultist) && target.Is(CustomRoles.Charmed)) return true; + return TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed); + } + + public static bool CanBeCharmed(PlayerControl pc) + { + return pc != null && (pc.IsCrewmate() || pc.IsImpostor() || + (CanCharmNeutral.GetBool() && (pc.GetCustomRole().IsNeutral() || pc.IsNeutralKiller()))) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Curser) && !pc.Is(Team.Coven); + } + + public override void OnFixedUpdate(PlayerControl pc) + { + if (!CharmedDiesOnCultistDeath.GetBool() || !GameStates.IsInTask || !IsEnable) return; + + if (pc == null || pc.IsAlive()) return; + + foreach (PlayerControl charmed in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Charmed))) charmed.Suicide(realKiller: pc); + } + + public override void SetButtonTexts(HudManager hud, byte id) + { + hud.KillButton?.OverrideText(GetString("CultistKillButtonText")); + } } \ No newline at end of file diff --git a/Roles/Neutral/Totocalcio.cs b/Roles/Neutral/Follower.cs similarity index 61% rename from Roles/Neutral/Totocalcio.cs rename to Roles/Neutral/Follower.cs index cdaad9cba..7c3039de9 100644 --- a/Roles/Neutral/Totocalcio.cs +++ b/Roles/Neutral/Follower.cs @@ -1,189 +1,189 @@ -using System.Collections.Generic; -using EHR.Modules; -using Hazel; -using UnityEngine; -using static EHR.Options; -using static EHR.Translator; -using Math = System.Math; - -namespace EHR.Neutral; - -public class Totocalcio : RoleBase -{ - private const int Id = 9800; - public static List PlayerIdList = []; - - private static OptionItem MaxBetTimes; - private static OptionItem BetCooldown; - private static OptionItem BetCooldownIncrese; - private static OptionItem MaxBetCooldown; - private static OptionItem KnowTargetRole; - private static OptionItem BetTargetKnowTotocalcio; - - public byte BetPlayer; - private int BetTimes; - - public override bool IsEnable => PlayerIdList.Count > 0; - - public override void SetupCustomOption() - { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Totocalcio); - - MaxBetTimes = new IntegerOptionItem(Id + 10, "TotocalcioMaxBetTimes", new(1, 5, 1), 3, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]) - .SetValueFormat(OptionFormat.Times); - - BetCooldown = new FloatOptionItem(Id + 12, "TotocalcioBetCooldown", new(0f, 60f, 0.5f), 10f, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]) - .SetValueFormat(OptionFormat.Seconds); - - BetCooldownIncrese = new FloatOptionItem(Id + 14, "TotocalcioBetCooldownIncrese", new(0f, 60f, 1f), 10f, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]) - .SetValueFormat(OptionFormat.Seconds); - - MaxBetCooldown = new FloatOptionItem(Id + 16, "TotocalcioMaxBetCooldown", new(0f, 180f, 0.5f), 70f, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]) - .SetValueFormat(OptionFormat.Seconds); - - KnowTargetRole = new BooleanOptionItem(Id + 18, "TotocalcioKnowTargetRole", true, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]); - - BetTargetKnowTotocalcio = new BooleanOptionItem(Id + 20, "TotocalcioBetTargetKnowTotocalcio", true, TabGroup.NeutralRoles) - .SetParent(CustomRoleSpawnChances[CustomRoles.Totocalcio]); - } - - public override void Init() - { - PlayerIdList = []; - BetTimes = MaxBetTimes.GetInt(); - BetPlayer = byte.MaxValue; - } - - public override void Add(byte playerId) - { - PlayerIdList.Add(playerId); - BetTimes = MaxBetTimes.GetInt(); - BetPlayer = byte.MaxValue; - } - - public override void Remove(byte playerId) - { - PlayerIdList.Remove(playerId); - } - - private void SendRPC(byte playerId) - { - if (!IsEnable || !Utils.DoRPC) return; - - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncTotocalcioTargetAndTimes, SendOption.Reliable); - writer.Write(playerId); - writer.Write(BetTimes); - writer.Write(BetPlayer); - AmongUsClient.Instance.FinishRpcImmediately(writer); - } - - public static void ReceiveRPC(MessageReader reader) - { - byte playerId = reader.ReadByte(); - if (Main.PlayerStates[playerId].Role is not Totocalcio tc) return; - - int times = reader.ReadInt32(); - byte target = reader.ReadByte(); - tc.BetTimes = times; - if (target != byte.MaxValue) tc.BetPlayer = target; - } - - public override bool CanUseKillButton(PlayerControl player) - { - return player.IsAlive() && BetTimes >= 1; - } - - public override bool CanUseImpostorVentButton(PlayerControl pc) - { - return false; - } - - public override void SetKillCooldown(byte id) - { - if (BetTimes < 1) - { - Main.AllPlayerKillCooldown[id] = 300f; - return; - } - - float cd = BetCooldown.GetFloat(); - cd += (MaxBetTimes.GetInt() - BetTimes) * BetCooldownIncrese.GetFloat(); - cd = Math.Min(cd, MaxBetCooldown.GetFloat()); - Main.AllPlayerKillCooldown[id] = cd; - } - - public override bool KnowRole(PlayerControl player, PlayerControl target) - { - if (base.KnowRole(player, target)) return true; - - if (!KnowTargetRole.GetBool()) return false; - - return player.Is(CustomRoles.Totocalcio) && BetPlayer == target.PlayerId; - } - - public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) - { - if (killer.PlayerId == target.PlayerId) return true; - - if (BetPlayer == target.PlayerId) return false; - if (BetTimes < 1) return false; - - BetTimes--; - PlayerControl betPlayer = Utils.GetPlayerById(BetPlayer); - - if (betPlayer != null) - { - Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: betPlayer, ForceLoop: true); - Utils.NotifyRoles(SpecifySeer: betPlayer, SpecifyTarget: killer, ForceLoop: true); - } - - BetPlayer = target.PlayerId; - SendRPC(killer.PlayerId); - - killer.ResetKillCooldown(); - killer.SetKillCooldown(); - killer.RPCPlayCustomSound("Bet"); - - killer.Notify(GetString("TotocalcioBetPlayer")); - if (BetTargetKnowTotocalcio.GetBool()) target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Totocalcio), GetString("TotocalcioBetOnYou"))); - - Logger.Info($"Target selected: {killer.GetNameWithRole().RemoveHtmlTags()} => {target.GetNameWithRole().RemoveHtmlTags()}", "Totocalcio"); - return false; - } - - public static string TargetMark(PlayerControl seer, PlayerControl target) - { - if (!seer.Is(CustomRoles.Totocalcio)) - { - if (!BetTargetKnowTotocalcio.GetBool()) return string.Empty; - - if (Main.PlayerStates[target.PlayerId].Role is not Totocalcio tc) return string.Empty; - - return seer.PlayerId == tc.BetPlayer ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Totocalcio), "♦") : string.Empty; - } - else - { - if (Main.PlayerStates[seer.PlayerId].Role is not Totocalcio tc) return string.Empty; - - return tc.BetPlayer == target.PlayerId ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Totocalcio), "♦") : string.Empty; - } - } - - public override string GetProgressText(byte playerId, bool comms) - { - PlayerControl player = Utils.GetPlayerById(playerId); - if (Main.PlayerStates[playerId].Role is not Totocalcio tc) return string.Empty; - - return player == null ? string.Empty : Utils.ColorString(tc.CanUseKillButton(player) ? Utils.GetRoleColor(CustomRoles.Totocalcio) : Color.gray, $"({tc.BetTimes})"); - } - - public override void SetButtonTexts(HudManager hud, byte id) - { - hud.KillButton?.OverrideText(GetString("TotocalcioKillButtonText")); - } +using System.Collections.Generic; +using EHR.Modules; +using Hazel; +using UnityEngine; +using static EHR.Options; +using static EHR.Translator; +using Math = System.Math; + +namespace EHR.Neutral; + +public class Follower : RoleBase +{ + private const int Id = 9800; + public static List PlayerIdList = []; + + private static OptionItem MaxBetTimes; + private static OptionItem BetCooldown; + private static OptionItem BetCooldownIncrese; + private static OptionItem MaxBetCooldown; + private static OptionItem KnowTargetRole; + private static OptionItem BetTargetKnowFollower; + + public byte BetPlayer; + private int BetTimes; + + public override bool IsEnable => PlayerIdList.Count > 0; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Follower); + + MaxBetTimes = new IntegerOptionItem(Id + 10, "FollowerMaxBetTimes", new(1, 5, 1), 3, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]) + .SetValueFormat(OptionFormat.Times); + + BetCooldown = new FloatOptionItem(Id + 12, "FollowerBetCooldown", new(0f, 60f, 0.5f), 10f, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]) + .SetValueFormat(OptionFormat.Seconds); + + BetCooldownIncrese = new FloatOptionItem(Id + 14, "FollowerBetCooldownIncrese", new(0f, 60f, 1f), 10f, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]) + .SetValueFormat(OptionFormat.Seconds); + + MaxBetCooldown = new FloatOptionItem(Id + 16, "FollowerMaxBetCooldown", new(0f, 180f, 0.5f), 70f, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]) + .SetValueFormat(OptionFormat.Seconds); + + KnowTargetRole = new BooleanOptionItem(Id + 18, "FollowerKnowTargetRole", true, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]); + + BetTargetKnowFollower = new BooleanOptionItem(Id + 20, "FollowerBetTargetKnowFollower", true, TabGroup.NeutralRoles) + .SetParent(CustomRoleSpawnChances[CustomRoles.Follower]); + } + + public override void Init() + { + PlayerIdList = []; + BetTimes = MaxBetTimes.GetInt(); + BetPlayer = byte.MaxValue; + } + + public override void Add(byte playerId) + { + PlayerIdList.Add(playerId); + BetTimes = MaxBetTimes.GetInt(); + BetPlayer = byte.MaxValue; + } + + public override void Remove(byte playerId) + { + PlayerIdList.Remove(playerId); + } + + private void SendRPC(byte playerId) + { + if (!IsEnable || !Utils.DoRPC) return; + + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncFollowerTargetAndTimes, SendOption.Reliable); + writer.Write(playerId); + writer.Write(BetTimes); + writer.Write(BetPlayer); + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public static void ReceiveRPC(MessageReader reader) + { + byte playerId = reader.ReadByte(); + if (Main.PlayerStates[playerId].Role is not Follower tc) return; + + int times = reader.ReadInt32(); + byte target = reader.ReadByte(); + tc.BetTimes = times; + if (target != byte.MaxValue) tc.BetPlayer = target; + } + + public override bool CanUseKillButton(PlayerControl player) + { + return player.IsAlive() && BetTimes >= 1; + } + + public override bool CanUseImpostorVentButton(PlayerControl pc) + { + return false; + } + + public override void SetKillCooldown(byte id) + { + if (BetTimes < 1) + { + Main.AllPlayerKillCooldown[id] = 300f; + return; + } + + float cd = BetCooldown.GetFloat(); + cd += (MaxBetTimes.GetInt() - BetTimes) * BetCooldownIncrese.GetFloat(); + cd = Math.Min(cd, MaxBetCooldown.GetFloat()); + Main.AllPlayerKillCooldown[id] = cd; + } + + public override bool KnowRole(PlayerControl player, PlayerControl target) + { + if (base.KnowRole(player, target)) return true; + + if (!KnowTargetRole.GetBool()) return false; + + return player.Is(CustomRoles.Follower) && BetPlayer == target.PlayerId; + } + + public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + if (killer.PlayerId == target.PlayerId) return true; + + if (BetPlayer == target.PlayerId) return false; + if (BetTimes < 1) return false; + + BetTimes--; + PlayerControl betPlayer = Utils.GetPlayerById(BetPlayer); + + if (betPlayer != null) + { + Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: betPlayer, ForceLoop: true); + Utils.NotifyRoles(SpecifySeer: betPlayer, SpecifyTarget: killer, ForceLoop: true); + } + + BetPlayer = target.PlayerId; + SendRPC(killer.PlayerId); + + killer.ResetKillCooldown(); + killer.SetKillCooldown(); + killer.RPCPlayCustomSound("Bet"); + + killer.Notify(GetString("FollowerBetPlayer")); + if (BetTargetKnowFollower.GetBool()) target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Follower), GetString("FollowerBetOnYou"))); + + Logger.Info($"Target selected: {killer.GetNameWithRole().RemoveHtmlTags()} => {target.GetNameWithRole().RemoveHtmlTags()}", "Follower"); + return false; + } + + public static string TargetMark(PlayerControl seer, PlayerControl target) + { + if (!seer.Is(CustomRoles.Follower)) + { + if (!BetTargetKnowFollower.GetBool()) return string.Empty; + + if (Main.PlayerStates[target.PlayerId].Role is not Follower tc) return string.Empty; + + return seer.PlayerId == tc.BetPlayer ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Follower), "♦") : string.Empty; + } + else + { + if (Main.PlayerStates[seer.PlayerId].Role is not Follower tc) return string.Empty; + + return tc.BetPlayer == target.PlayerId ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Follower), "♦") : string.Empty; + } + } + + 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})"); + } + + public override void SetButtonTexts(HudManager hud, byte id) + { + hud.KillButton?.OverrideText(GetString("FollowerKillButtonText")); + } } \ No newline at end of file diff --git a/Roles/Neutral/FFF.cs b/Roles/Neutral/Hater.cs similarity index 76% rename from Roles/Neutral/FFF.cs rename to Roles/Neutral/Hater.cs index 09ffdfe03..7c897b3e0 100644 --- a/Roles/Neutral/FFF.cs +++ b/Roles/Neutral/Hater.cs @@ -4,7 +4,7 @@ using static EHR.Options; namespace EHR.Neutral; -public class FFF : RoleBase +public class Hater : RoleBase { private const int Id = 11300; private static bool On; @@ -28,7 +28,7 @@ public class FFF : RoleBase CustomRoles.Amnesiac, CustomRoles.Pursuer, CustomRoles.Maverick, - CustomRoles.Totocalcio, + CustomRoles.Follower, CustomRoles.Opportunist, CustomRoles.Crewmate, CustomRoles.Jester, @@ -41,17 +41,17 @@ public class FFF : RoleBase public override void SetupCustomOption() { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.FFF, zeroOne: false); - MisFireKillTarget = new BooleanOptionItem(Id + 11, "FFFMisFireKillTarget", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.FFF]); - ChooseConverted = new BooleanOptionItem(Id + 12, "FFFChooseConverted", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.FFF]); - CanKillMadmate = new BooleanOptionItem(Id + 13, "FFFCanKillMadmate", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillCharmed = new BooleanOptionItem(Id + 14, "FFFCanKillCharmed", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillLovers = new BooleanOptionItem(Id + 15, "FFFCanKillLovers", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillSidekicks = new BooleanOptionItem(Id + 16, "FFFCanKillSidekick", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillEgoists = new BooleanOptionItem(Id + 17, "FFFCanKillEgoist", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillContagious = new BooleanOptionItem(Id + 19, "FFFCanKillContagious", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - CanKillUndead = new BooleanOptionItem(Id + 21, "FFFCanKillUndead", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); - ChangeRoleWhenCantWin = new BooleanOptionItem(Id + 18, "VultureChangeRoleWhenCantWin", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.FFF]); + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Hater, zeroOne: false); + MisFireKillTarget = new BooleanOptionItem(Id + 11, "HaterMisFireKillTarget", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hater]); + ChooseConverted = new BooleanOptionItem(Id + 12, "HaterChooseConverted", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hater]); + CanKillMadmate = new BooleanOptionItem(Id + 13, "HaterCanKillMadmate", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillCharmed = new BooleanOptionItem(Id + 14, "HaterCanKillCharmed", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillLovers = new BooleanOptionItem(Id + 15, "HaterCanKillLovers", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillSidekicks = new BooleanOptionItem(Id + 16, "HaterCanKillSidekick", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillEgoists = new BooleanOptionItem(Id + 17, "HaterCanKillEgoist", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillContagious = new BooleanOptionItem(Id + 19, "HaterCanKillContagious", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + CanKillUndead = new BooleanOptionItem(Id + 21, "HaterCanKillUndead", true, TabGroup.NeutralRoles).SetParent(ChooseConverted); + ChangeRoleWhenCantWin = new BooleanOptionItem(Id + 18, "VultureChangeRoleWhenCantWin", true, TabGroup.NeutralRoles).SetParent(CustomRoleSpawnChances[CustomRoles.Hater]); ChangeRole = new StringOptionItem(Id + 20, "VultureChangeRole", ChangeRoles.Select(x => x.ToColoredString()).ToArray(), 0, TabGroup.NeutralRoles, noTranslation: true).SetParent(ChangeRoleWhenCantWin); } @@ -95,13 +95,13 @@ public class FFF : RoleBase { if (killer.RpcCheckAndMurder(target)) IsWon = true; - Logger.Info($"{killer.GetRealName()} killed right target case 1", "FFF"); + Logger.Info($"{killer.GetRealName()} killed right target case 1", "Hater"); return false; } if ( ((target.Is(CustomRoles.Madmate) || target.Is(CustomRoles.Gangster)) && CanKillMadmate.GetBool()) - || ((target.Is(CustomRoles.Charmed) || target.Is(CustomRoles.Succubus)) && CanKillCharmed.GetBool()) + || ((target.Is(CustomRoles.Charmed) || target.Is(CustomRoles.Cultist)) && CanKillCharmed.GetBool()) || ((target.Is(CustomRoles.Undead) || target.Is(CustomRoles.Necromancer) || target.Is(CustomRoles.Deathknight)) && CanKillUndead.GetBool()) || (Main.LoversPlayers.Exists(x => x.PlayerId == target.PlayerId) && CanKillLovers.GetBool()) || ((target.Is(CustomRoles.Romantic) || target.Is(CustomRoles.RuthlessRomantic) || target.Is(CustomRoles.VengefulRomantic) @@ -113,7 +113,7 @@ public class FFF : RoleBase { if (killer.RpcCheckAndMurder(target)) IsWon = true; - Logger.Info($"{killer.GetRealName()} killed right target case 2", "FFF"); + Logger.Info($"{killer.GetRealName()} killed right target case 2", "Hater"); return false; } } @@ -127,7 +127,7 @@ public class FFF : RoleBase } killer.Suicide(PlayerState.DeathReason.Sacrifice); - Logger.Info($"{killer.GetRealName()} killed incorrect target => misfire", "FFF"); + Logger.Info($"{killer.GetRealName()} killed incorrect target => misfire", "Hater"); return false; } @@ -135,7 +135,7 @@ public class FFF : RoleBase { return role is CustomRoles.Gangster or - CustomRoles.Succubus or + CustomRoles.Cultist or CustomRoles.Deathknight or CustomRoles.Necromancer or CustomRoles.Refugee or @@ -160,6 +160,6 @@ public class FFF : RoleBase public override void SetButtonTexts(HudManager hud, byte id) { - hud.KillButton?.OverrideText(Translator.GetString("FFFButtonText")); + hud.KillButton?.OverrideText(Translator.GetString("HaterButtonText")); } } \ No newline at end of file diff --git a/Roles/Neutral/Romantic.cs b/Roles/Neutral/Romantic.cs index 454527eb0..2d1777e6a 100644 --- a/Roles/Neutral/Romantic.cs +++ b/Roles/Neutral/Romantic.cs @@ -35,7 +35,7 @@ public class Romantic : RoleBase private static readonly Dictionary ConvertingRolesAndAddons = new() { - [CustomRoles.Succubus] = CustomRoles.Charmed, + [CustomRoles.Cultist] = CustomRoles.Charmed, [CustomRoles.Jackal] = CustomRoles.Sidekick, [CustomRoles.Virus] = CustomRoles.Contagious, [CustomRoles.Deathknight] = CustomRoles.Undead, diff --git a/Roles/Neutral/Vulture.cs b/Roles/Neutral/Vulture.cs index d54ea10e0..5b190652f 100644 --- a/Roles/Neutral/Vulture.cs +++ b/Roles/Neutral/Vulture.cs @@ -31,7 +31,7 @@ public class Vulture : RoleBase CustomRoles.Amnesiac, CustomRoles.Pursuer, CustomRoles.Maverick, - CustomRoles.Totocalcio, + CustomRoles.Follower, CustomRoles.Opportunist, CustomRoles.Crewmate, CustomRoles.Jester