mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 01:46:25 +00:00
nothing trust me
This commit is contained in:
1 parent
cb2727cbc4
commit
f348076316
22 files changed
+394
-394
No files matched your search
+2
-2
@@ -32,7 +32,7 @@ public enum CustomRoles
|
||||
BountyHunter,
|
||||
Butcher,
|
||||
Camouflager,
|
||||
Capitalism,
|
||||
Capitalist,
|
||||
Cantankerous,
|
||||
Catalyst,
|
||||
Centralizer,
|
||||
@@ -234,7 +234,6 @@ public enum CustomRoles
|
||||
Mortician,
|
||||
NiceEraser,
|
||||
NiceGuesser,
|
||||
NiceSwapper,
|
||||
Nightmare,
|
||||
Negotiator,
|
||||
Observer,
|
||||
@@ -266,6 +265,7 @@ public enum CustomRoles
|
||||
SpeedBooster,
|
||||
Spy,
|
||||
SuperStar,
|
||||
Swapper,
|
||||
TaskManager,
|
||||
Telekinetic,
|
||||
Tether,
|
||||
|
||||
@@ -503,7 +503,7 @@ public class Main : BasePlugin
|
||||
{ CustomRoles.Deputy, "#df9026" },
|
||||
{ CustomRoles.Retributionist, "#cfc999" },
|
||||
{ CustomRoles.Cleanser, "#98FF98" },
|
||||
{ CustomRoles.NiceSwapper, "#922348" },
|
||||
{ CustomRoles.Swapper, "#922348" },
|
||||
{ CustomRoles.Ignitor, "#ffffa5" },
|
||||
{ CustomRoles.Guardian, "#2E8B57" },
|
||||
{ CustomRoles.Addict, "#008000" },
|
||||
|
||||
@@ -131,7 +131,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Terrorist => Terrorist.CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate,
|
||||
CustomRoles.Executioner => CustomRoles.Crewmate,
|
||||
CustomRoles.Lawyer => CustomRoles.Crewmate,
|
||||
CustomRoles.NiceSwapper => CustomRoles.Crewmate,
|
||||
CustomRoles.Swapper => CustomRoles.Crewmate,
|
||||
CustomRoles.Ignitor => CustomRoles.Crewmate,
|
||||
CustomRoles.Jailor => UsePets && Jailor.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
|
||||
CustomRoles.Vampire => CustomRoles.Impostor,
|
||||
@@ -310,7 +310,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Scavenger => CustomRoles.Impostor,
|
||||
CustomRoles.Transporter => CustomRoles.Crewmate,
|
||||
CustomRoles.Veteran => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
|
||||
CustomRoles.Capitalism => CustomRoles.Impostor,
|
||||
CustomRoles.Capitalist => CustomRoles.Impostor,
|
||||
CustomRoles.Bodyguard => CustomRoles.Crewmate,
|
||||
CustomRoles.Grenadier => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
|
||||
CustomRoles.Lighter => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
|
||||
@@ -792,7 +792,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Nuker or
|
||||
CustomRoles.Scavenger or
|
||||
CustomRoles.Trapster or
|
||||
CustomRoles.Capitalism or
|
||||
CustomRoles.Capitalist or
|
||||
CustomRoles.Gangster or
|
||||
CustomRoles.Cleaner or
|
||||
CustomRoles.Lightning or
|
||||
@@ -1141,7 +1141,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Lazy when pc.Is(CustomRoles.LazyGuy) || pc.Is(CustomRoles.Snitch) || pc.Is(CustomRoles.Marshall) || pc.Is(CustomRoles.Transporter) || pc.Is(CustomRoles.Guardian) => false,
|
||||
CustomRoles.Tiebreaker when pc.Is(CustomRoles.Dictator) => false,
|
||||
CustomRoles.Stressed when !pc.IsCrewmate() || pc.GetCustomRole().IsTasklessCrewmate() => false,
|
||||
CustomRoles.Stealer or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.Nuker) || pc.Is(CustomRoles.Trapster) || pc.Is(CustomRoles.Capitalism) => false,
|
||||
CustomRoles.Stealer or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.Nuker) || pc.Is(CustomRoles.Trapster) || pc.Is(CustomRoles.Capitalist) => false,
|
||||
CustomRoles.Torch when !pc.IsCrewmate() || pc.Is(CustomRoles.Bewilder) || pc.Is(CustomRoles.Sunglasses) || pc.Is(CustomRoles.GuardianAngelEHR) => false,
|
||||
CustomRoles.Bewilder when pc.Is(CustomRoles.Torch) || pc.Is(CustomRoles.GuardianAngelEHR) || pc.Is(CustomRoles.Sunglasses) => false,
|
||||
CustomRoles.Dynamo when pc.Is(CustomRoles.Spurt) || pc.GetCustomRole() is CustomRoles.Tank or CustomRoles.Ankylosaurus => false,
|
||||
@@ -1424,7 +1424,7 @@ internal static class CustomRolesHelper
|
||||
|
||||
public static bool IsDevFavoriteRole(this CustomRoles role)
|
||||
{
|
||||
return role is CustomRoles.Adventurer or CustomRoles.Chef or CustomRoles.Detour or CustomRoles.Hacker or CustomRoles.NiceSwapper or CustomRoles.Sentinel or CustomRoles.Sentry or CustomRoles.Tornado or CustomRoles.Tunneler or CustomRoles.Whisperer or CustomRoles.Wizard or
|
||||
return role is CustomRoles.Adventurer or CustomRoles.Chef or CustomRoles.Detour or CustomRoles.Hacker or CustomRoles.Swapper or CustomRoles.Sentinel or CustomRoles.Sentry or CustomRoles.Tornado or CustomRoles.Tunneler or CustomRoles.Whisperer or CustomRoles.Wizard or
|
||||
CustomRoles.Abyssbringer or CustomRoles.Assumer or CustomRoles.Chronomancer or CustomRoles.Echo or CustomRoles.Escapist or CustomRoles.Hypnotist or CustomRoles.Librarian or CustomRoles.Mafioso or CustomRoles.Mastermind or CustomRoles.Mercenary or CustomRoles.Penguin or CustomRoles.RiftMaker or CustomRoles.Sapper or CustomRoles.Wiper or
|
||||
CustomRoles.Bargainer or CustomRoles.Bubble or CustomRoles.Doomsayer or CustomRoles.Enderman or CustomRoles.Evolver or CustomRoles.HeadHunter or CustomRoles.Impartial or CustomRoles.Patroller or CustomRoles.Pawn or CustomRoles.Infection or CustomRoles.Postman or CustomRoles.Pyromaniac or CustomRoles.Revolutionist or CustomRoles.Rogue or CustomRoles.Romantic or CustomRoles.RoomRusher or CustomRoles.RouleteGrandeur or CustomRoles.Simon or CustomRoles.SoulHunter or CustomRoles.Sprayer or CustomRoles.Technician or CustomRoles.Tank or CustomRoles.Tiger or CustomRoles.Tremor or CustomRoles.Vengeance or CustomRoles.Vortex or CustomRoles.Werewolf or CustomRoles.WeaponMaster or
|
||||
CustomRoles.Reaper or CustomRoles.VoodooMaster or CustomRoles.Dreamweaver or CustomRoles.Banshee or
|
||||
@@ -1660,7 +1660,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Bard => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Blackmailer => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Camouflager => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Capitalism => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Capitalist => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Catalyst => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Centralizer => RoleOptionType.Impostor_Support,
|
||||
CustomRoles.Cleaner => RoleOptionType.Impostor_Support,
|
||||
@@ -1879,7 +1879,7 @@ internal static class CustomRolesHelper
|
||||
CustomRoles.Marshall => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.Mayor => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.NiceEraser => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.NiceSwapper => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.Swapper => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.Oxyman => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.President => RoleOptionType.Crewmate_Power,
|
||||
CustomRoles.Speedrunner => RoleOptionType.Crewmate_Power,
|
||||
|
||||
@@ -66,7 +66,7 @@ internal static class ExtendedPlayerControl
|
||||
public static bool UsesMeetingShapeshift(this PlayerControl player)
|
||||
{
|
||||
CustomRoles role = player.GetCustomRole();
|
||||
if (player.IsModdedClient() && role is CustomRoles.Judge or CustomRoles.NiceSwapper or CustomRoles.Nemesis) return false;
|
||||
if (player.IsModdedClient() && role is CustomRoles.Judge or CustomRoles.Swapper or CustomRoles.Nemesis) return false;
|
||||
return role.UsesMeetingShapeshift();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public static class GuessManager
|
||||
if (!AmongUsClient.Instance.AmHost) return false;
|
||||
if (!GameStates.IsMeeting || MeetingHud.Instance.state is MeetingHud.VoteStates.Results or MeetingHud.VoteStates.Proceeding || pc == null) return false;
|
||||
|
||||
bool hasGuessingRole = pc.GetCustomRole() is CustomRoles.NiceGuesser or CustomRoles.EvilGuesser or CustomRoles.Doomsayer or CustomRoles.Judge or CustomRoles.NiceSwapper or CustomRoles.Councillor or CustomRoles.NecroGuesser or CustomRoles.Augur;
|
||||
bool hasGuessingRole = pc.GetCustomRole() is CustomRoles.NiceGuesser or CustomRoles.EvilGuesser or CustomRoles.Doomsayer or CustomRoles.Judge or CustomRoles.Swapper or CustomRoles.Councillor or CustomRoles.NecroGuesser or CustomRoles.Augur;
|
||||
if (!hasGuessingRole && !pc.Is(CustomRoles.Guesser) && !Options.GuesserMode.GetBool()) return false;
|
||||
|
||||
int operate; // 1: ID, 2: Guess
|
||||
|
||||
@@ -390,8 +390,8 @@ public static class Options
|
||||
public static OptionItem GodfatherCancelVote;
|
||||
|
||||
public static OptionItem GuardSpellTimes;
|
||||
public static OptionItem CapitalismSkillCooldown;
|
||||
public static OptionItem CapitalismKillCooldown;
|
||||
public static OptionItem CapitalistSkillCooldown;
|
||||
public static OptionItem CapitalistKillCooldown;
|
||||
public static OptionItem GrenadierSkillCooldown;
|
||||
public static OptionItem GrenadierSkillDuration;
|
||||
public static OptionItem GrenadierCauseVision;
|
||||
|
||||
+4
-4
@@ -123,7 +123,7 @@ public enum CustomRPC
|
||||
SetDoppelgangerStealLimit,
|
||||
SetJailorExeLimit,
|
||||
SetWwTimer,
|
||||
SetNiceSwapperVotes,
|
||||
SetSwapperVotes,
|
||||
Judge,
|
||||
Guess,
|
||||
MeetingKill,
|
||||
@@ -247,7 +247,7 @@ internal static class RPCHandlerPatch
|
||||
private static bool TrustedRpc(byte id)
|
||||
{
|
||||
if (SubmergedCompatibility.IsSubmerged() && id is >= 120 and <= 124) return true;
|
||||
return (CustomRPC)id is CustomRPC.VersionCheck or CustomRPC.RequestRetryVersionCheck or CustomRPC.AntiBlackout or CustomRPC.SyncNameNotify or CustomRPC.RequestSendMessage or CustomRPC.RequestCommandProcessing or CustomRPC.Judge or CustomRPC.SetNiceSwapperVotes or CustomRPC.MeetingKill or CustomRPC.Guess or CustomRPC.NemesisRevenge or CustomRPC.BAU or CustomRPC.FFAKill or CustomRPC.TMGSync or CustomRPC.InspectorCommand or CustomRPC.ImitatorClick;
|
||||
return (CustomRPC)id is CustomRPC.VersionCheck or CustomRPC.RequestRetryVersionCheck or CustomRPC.AntiBlackout or CustomRPC.SyncNameNotify or CustomRPC.RequestSendMessage or CustomRPC.RequestCommandProcessing or CustomRPC.Judge or CustomRPC.SetSwapperVotes or CustomRPC.MeetingKill or CustomRPC.Guess or CustomRPC.NemesisRevenge or CustomRPC.BAU or CustomRPC.FFAKill or CustomRPC.TMGSync or CustomRPC.InspectorCommand or CustomRPC.ImitatorClick;
|
||||
}
|
||||
|
||||
private static bool CheckRateLimit(PlayerControl __instance, RpcCalls rpcType)
|
||||
@@ -1217,9 +1217,9 @@ internal static class RPCHandlerPatch
|
||||
}
|
||||
|
||||
break;
|
||||
case CustomRPC.SetNiceSwapperVotes:
|
||||
case CustomRPC.SetSwapperVotes:
|
||||
{
|
||||
NiceSwapper.ReceiveRPC(reader, __instance);
|
||||
Swapper.ReceiveRPC(reader, __instance);
|
||||
break;
|
||||
}
|
||||
case CustomRPC.SetTrackerTarget:
|
||||
|
||||
+3
-3
@@ -1032,7 +1032,7 @@ public static class Utils
|
||||
(pc.Is(CustomRoles.Marshall) && !Options.MarshallCanBeMadmate.GetBool()) ||
|
||||
(pc.Is(CustomRoles.Investigator) && !Options.InvestigatorCanBeMadmate.GetBool()) ||
|
||||
(pc.Is(CustomRoles.President) && !Options.PresidentCanBeMadmate.GetBool()) ||
|
||||
pc.Is(CustomRoles.NiceSwapper) ||
|
||||
pc.Is(CustomRoles.Swapper) ||
|
||||
pc.Is(CustomRoles.Speedrunner) ||
|
||||
pc.Is(CustomRoles.LazyGuy) ||
|
||||
pc.Is(CustomRoles.Loyal) ||
|
||||
@@ -3642,8 +3642,8 @@ public static class Utils
|
||||
}
|
||||
|
||||
break;
|
||||
case CustomRoles.NiceSwapper when disconnect:
|
||||
NiceSwapper.SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
case CustomRoles.Swapper when disconnect:
|
||||
Swapper.SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
break;
|
||||
case CustomRoles.Silencer when disconnect:
|
||||
if (onMeeting) Main.Instance.StartCoroutine(CoRoutine());
|
||||
|
||||
@@ -391,7 +391,7 @@ internal static class ChatCommands
|
||||
{
|
||||
if (GuessManager.GuesserMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (Judge.TrialMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (NiceSwapper.SwapMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (Swapper.SwapMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (Inspector.InspectorCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (Councillor.MurderMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
if (Medium.MsMsg(PlayerControl.LocalPlayer, text)) goto Canceled;
|
||||
@@ -3595,7 +3595,7 @@ internal static class ChatCommands
|
||||
{
|
||||
if (GuessManager.GuesserMsg(player, text) ||
|
||||
Judge.TrialMsg(player, text) ||
|
||||
NiceSwapper.SwapMsg(player, text) ||
|
||||
Swapper.SwapMsg(player, text) ||
|
||||
Inspector.InspectorCheckMsg(player, text) ||
|
||||
Councillor.MurderMsg(player, text))
|
||||
{
|
||||
|
||||
@@ -78,7 +78,7 @@ internal static class ExileControllerWrapUpPatch
|
||||
|
||||
Witch.RemoveSpelledPlayer();
|
||||
|
||||
NiceSwapper.OnExileFinish();
|
||||
Swapper.OnExileFinish();
|
||||
|
||||
foreach (PlayerControl pc in Main.AllPlayerControls)
|
||||
{
|
||||
|
||||
+1
-1
@@ -352,7 +352,7 @@ internal static class HudManagerPatch
|
||||
ActionButton button;
|
||||
Type type = state.Role.GetType();
|
||||
|
||||
if (type.GetMethod("OnVote").DeclaringType == type || role is CustomRoles.Adrenaline or CustomRoles.Battery or CustomRoles.Dad or CustomRoles.Grappler or CustomRoles.Inquirer or CustomRoles.Judge or CustomRoles.Mechanic or CustomRoles.Medium or CustomRoles.NiceSwapper or CustomRoles.Inspector or CustomRoles.Spy or CustomRoles.Councillor or CustomRoles.CursedWolf or CustomRoles.Forger or CustomRoles.Generator or CustomRoles.Ventriloquist or CustomRoles.Bargainer or CustomRoles.Technician or CustomRoles.Virus)
|
||||
if (type.GetMethod("OnVote").DeclaringType == type || role is CustomRoles.Adrenaline or CustomRoles.Battery or CustomRoles.Dad or CustomRoles.Grappler or CustomRoles.Inquirer or CustomRoles.Judge or CustomRoles.Mechanic or CustomRoles.Medium or CustomRoles.Swapper or CustomRoles.Inspector or CustomRoles.Spy or CustomRoles.Councillor or CustomRoles.CursedWolf or CustomRoles.Forger or CustomRoles.Generator or CustomRoles.Ventriloquist or CustomRoles.Bargainer or CustomRoles.Technician or CustomRoles.Virus)
|
||||
button = null;
|
||||
else if (role is CustomRoles.Coroner or CustomRoles.Occultist or CustomRoles.Vulture)
|
||||
button = __instance.ReportButton;
|
||||
|
||||
@@ -631,7 +631,7 @@ internal static class BeginCrewmatePatch
|
||||
|
||||
CustomRoles.Dictator or
|
||||
CustomRoles.Mayor or
|
||||
CustomRoles.NiceSwapper
|
||||
CustomRoles.Swapper
|
||||
=> HudManager.Instance.Chat.messageSound,
|
||||
|
||||
CustomRoles.AntiAdminer or
|
||||
|
||||
@@ -235,7 +235,7 @@ internal static class CheckForEndVotingPatch
|
||||
Dictionary<byte, int> votingData = __instance.CustomCalculateVotes();
|
||||
|
||||
Blackmailer.ManipulateVotingResult(votingData, states);
|
||||
NiceSwapper.ManipulateVotingResult(votingData, states);
|
||||
Swapper.ManipulateVotingResult(votingData, states);
|
||||
Assumer.OnVotingEnd(votingData);
|
||||
|
||||
var exileId = byte.MaxValue;
|
||||
@@ -1123,7 +1123,7 @@ internal static class MeetingHudStartPatch
|
||||
GuessManager.StartMeetingPatch.Postfix(__instance);
|
||||
Inspector.StartMeetingPatch.Postfix(__instance);
|
||||
Judge.StartMeetingPatch.Postfix(__instance);
|
||||
NiceSwapper.StartMeetingPatch.Postfix(__instance);
|
||||
Swapper.StartMeetingPatch.Postfix(__instance);
|
||||
Councillor.StartMeetingPatch.Postfix(__instance);
|
||||
Nemesis.StartMeetingPatch.Postfix(__instance);
|
||||
Imitator.StartMeetingPatch.Postfix(__instance);
|
||||
@@ -1211,7 +1211,7 @@ internal static class MeetingHudUpdatePatch
|
||||
|
||||
switch (myRole)
|
||||
{
|
||||
case CustomRoles.NiceGuesser or CustomRoles.EvilGuesser or CustomRoles.Judge or CustomRoles.NiceSwapper or CustomRoles.Councillor or CustomRoles.Guesser when !PlayerControl.LocalPlayer.IsAlive():
|
||||
case CustomRoles.NiceGuesser or CustomRoles.EvilGuesser or CustomRoles.Judge or CustomRoles.Swapper or CustomRoles.Councillor or CustomRoles.Guesser when !PlayerControl.LocalPlayer.IsAlive():
|
||||
ClearShootButton(__instance, true);
|
||||
break;
|
||||
case CustomRoles.Nemesis when !PlayerControl.LocalPlayer.IsAlive() && GameObject.Find("ShootButton") == null:
|
||||
|
||||
@@ -1034,9 +1034,9 @@ internal static class ReportDeadBodyPatch
|
||||
return false;
|
||||
}
|
||||
|
||||
if (__instance.Is(CustomRoles.NiceSwapper) && !NiceSwapper.CanStartMeeting.GetBool())
|
||||
if (__instance.Is(CustomRoles.Swapper) && !Swapper.CanStartMeeting.GetBool())
|
||||
{
|
||||
Notify("NiceSwapperCannotCallEmergencyMeeting");
|
||||
Notify("SwapperCannotCallEmergencyMeeting");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2234,7 +2234,7 @@ internal static class PlayerControlCompleteTaskPatch
|
||||
public static bool Prefix(PlayerControl __instance)
|
||||
{
|
||||
if (MeetingHud.Instance && MeetingHud.Instance.state != MeetingHud.VoteStates.Animating) return false;
|
||||
return !Workhorse.OnCompleteTask(__instance) && Capitalism.AddTaskForPlayer(__instance); // Cancel task win
|
||||
return !Workhorse.OnCompleteTask(__instance) && Capitalist.AddTaskForPlayer(__instance); // Cancel task win
|
||||
}
|
||||
|
||||
public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] uint idx)
|
||||
|
||||
@@ -187,11 +187,11 @@ internal static class RpcSetTasksPatch
|
||||
// Workhorse task assignment
|
||||
if (pc.Is(CustomRoles.Workhorse)) (hasCommonTasks, numLongTasks, numShortTasks) = Workhorse.TaskData;
|
||||
|
||||
// Capitalism is going to harm people~
|
||||
if (Capitalism.CapitalismAssignTask.TryGetValue(pc.PlayerId, out int extraTasksNum))
|
||||
// Capitalist is going to harm people~
|
||||
if (Capitalist.CapitalistAssignTask.TryGetValue(pc.PlayerId, out int extraTasksNum))
|
||||
{
|
||||
numShortTasks += extraTasksNum;
|
||||
Capitalism.CapitalismAssignTask.Remove(pc.PlayerId);
|
||||
Capitalist.CapitalistAssignTask.Remove(pc.PlayerId);
|
||||
}
|
||||
|
||||
if (taskTypeIds.Length == 0) hasCommonTasks = false; // Set common to 0 when redistributing tasks
|
||||
|
||||
+11
-11
@@ -210,7 +210,7 @@
|
||||
"Bomber": "Bomber",
|
||||
"Scavenger": "Scavenger",
|
||||
"Trapster": "Trapster",
|
||||
"Capitalism": "Capitalist",
|
||||
"Capitalist": "Capitalist",
|
||||
"Gangster": "Gangster",
|
||||
"Cleaner": "Cleaner",
|
||||
"Lightning": "Lightning",
|
||||
@@ -489,7 +489,7 @@
|
||||
"TrapsterInfo": "Start a killing chain",
|
||||
"ScavengerInfo": "Your kills are unreportable",
|
||||
"EvilGuesserInfo": "Guess roles in meetings to kill",
|
||||
"CapitalismInfo": "Give more tasks to crewmates",
|
||||
"CapitalistInfo": "Give more tasks to crewmates",
|
||||
"GangsterInfo": "Convert players to your side",
|
||||
"CleanerInfo": "Report bodies to make them unreportable",
|
||||
"LightningInfo": "Convert players to Quantum Ghosts",
|
||||
@@ -719,7 +719,7 @@
|
||||
"BomberInfoLong": "(Impostors):\\nThe Bomber can use the vanish/pet button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.",
|
||||
"ScavengerInfoLong": "(Impostors):\\nScavenger kills do not leave dead bodies behind. To kill someone, you must click your kill button on them, then stay near that person for a few seconds, similar to an Arsonist douse.",
|
||||
"TrapsterInfoLong": "(Impostors):\\nAs the Trapster, you can vanish/pet to create a fake dead body. Anyone who reports this body will die, and depending on settings the body will be reported.\\n\\n(Legacy Version):\\nIn the game, the Trapster kills a player and then puts a trap on their body. If another player reports the dead body and it has the Trapster's trap on it, the player who reports will die instantly without the body getting reported. The player killed by the Trapster's trap will also become a Trapster. This chain reaction continues until no more players are left to become Trapsters. However, the Trapster will die immediately after making a kill. It's worth noting that the Trapster's own dead body cannot trigger their trap.",
|
||||
"CapitalismInfoLong": "(Impostors):\\nCapitalists can add a short task to a player by pressing the kill button. Note: using this ability on players who have no tasks or have completed tasks will not take effect.",
|
||||
"CapitalistInfoLong": "(Impostors):\\nCapitalists can add a short task to a player by pressing the kill button. Note: using this ability on players who have no tasks or have completed tasks will not take effect.",
|
||||
"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.",
|
||||
@@ -1609,7 +1609,7 @@
|
||||
"SnitchCanBeWorkhorse": "<color=#b8fb4f>Snitch</color> can become <color=#00ffff>Workhorse</color>",
|
||||
"WorkhorseSpawnChance": "<color=#00ffff>Workhorse</color> Spawn Chance",
|
||||
"InnocentCanWinByImp": "If their target was an <color=#ff1919>Impostor</color> then they win with them",
|
||||
"CapitalismSkillCooldown": "Ability Cooldown",
|
||||
"CapitalistSkillCooldown": "Ability Cooldown",
|
||||
"DualVotes": "Duplicate votes",
|
||||
"HideDualVotes": "Hide duplicated votes",
|
||||
"VeteranSkillCooldown": "Alert Cooldown",
|
||||
@@ -1845,7 +1845,7 @@
|
||||
"CheckReportFail": "<#ff0000>This meeting call was canceled due to the following reason:\\n</color>",
|
||||
"CannotCallEmergencyMeetingWhileSabotage": "Emergency meetings cannot be called during crisis",
|
||||
"JesterCannotCallEmergencyMeeting": "As the <#ec62a5>Jester</color>, according to the host's settings, you cannot call emergency meetings",
|
||||
"NiceSwapperCannotCallEmergencyMeeting": "As the <#922348>Nice Swapper</color>, according to the host's settings, you cannot call emergency meetings",
|
||||
"SwapperCannotCallEmergencyMeeting": "As the <#922348>Nice Swapper</color>, according to the host's settings, you cannot call emergency meetings",
|
||||
"AdrenalineCannotCallEmergencyMeeting": "As the <#ffff00>Adrenaline</color>, you cannot call emergency meetings currently",
|
||||
"PlayerWasRevived": "The player whose body you tried to report was revived",
|
||||
"HypnosisNoMeeting": "Everyone is in hypnosis, no meeting calls are allowed currently",
|
||||
@@ -3259,7 +3259,7 @@
|
||||
"BountyHunterChangeButtonText": "Swap",
|
||||
"EvilTrackerChangeButtonText": "Track",
|
||||
"InnocentButtonText": "Frame",
|
||||
"CapitalismButtonText": "Add Task",
|
||||
"CapitalistButtonText": "Add Task",
|
||||
"PelicanButtonText": "Eat",
|
||||
"CounterfeiterButtonText": "Cheat",
|
||||
"PursuerButtonText": "Trick",
|
||||
@@ -4791,11 +4791,11 @@
|
||||
"ExpressInfoLong": "(Crewmates):\\nAs the Express, you gain a small temporary speed boost after each task you complete.",
|
||||
"ExpressSpeed": "Increased Speed",
|
||||
"ExpressSpeedDur": "Increased Speed Duration",
|
||||
"NiceSwapper": "Swapper",
|
||||
"NiceSwapperInfo": "Swap players' votes",
|
||||
"NiceSwapperInfoLong": "(Crewmates):\\nAs the Swapper, you can use the command <b>/sw <color=#0000ff>[ID]</color></b> twice to choose 2 players. Those votes received by those 2 players will be swapped.\\nYou can see everyone's <color=#0000ff>ID</color>s next to their name.\\n\\nFor example, if 3 players voted red, and 5 players voted yellow, and you swap red and yellows' IDs, then red will receive 5 votes, and yellow will receive 3 votes.\\n\\nDue to technical difficulties, the Host's original vote will seem unchanged, but it's only visual, their vote will still get swapped.",
|
||||
"NiceSwapperMax": "Initial Number of Swaps",
|
||||
"NiceSwapperTrialMax": "Ability use limit reached",
|
||||
"Swapper": "Swapper",
|
||||
"SwapperInfo": "Swap players' votes",
|
||||
"SwapperInfoLong": "(Crewmates):\\nAs the Swapper, you can use the command <b>/sw <color=#0000ff>[ID]</color></b> twice to choose 2 players. Those votes received by those 2 players will be swapped.\\nYou can see everyone's <color=#0000ff>ID</color>s next to their name.\\n\\nFor example, if 3 players voted red, and 5 players voted yellow, and you swap red and yellows' IDs, then red will receive 5 votes, and yellow will receive 3 votes.\\n\\nDue to technical difficulties, the Host's original vote will seem unchanged, but it's only visual, their vote will still get swapped.",
|
||||
"SwapperMax": "Initial Number of Swaps",
|
||||
"SwapperTrialMax": "Ability use limit reached",
|
||||
"CanSwapSelfVotes": "<color=#922348>Swapper</color> Can Swap Themselves",
|
||||
"SwapperHideMsg": "<color=#00ff00>Hide <color=#922348>Swapper</color>'s commands</color>",
|
||||
"CantSwapSelf": "You can't swap yourself",
|
||||
|
||||
@@ -141,7 +141,7 @@ public class CopyCat : RoleBase
|
||||
CustomRoles.Demon => CustomRoles.Spy,
|
||||
CustomRoles.Undertaker or CustomRoles.Vortex => CustomRoles.Vacuum,
|
||||
CustomRoles.Kidnapper => CustomRoles.Autocrat,
|
||||
CustomRoles.Capitalism => CustomRoles.Helper,
|
||||
CustomRoles.Capitalist => CustomRoles.Helper,
|
||||
CustomRoles.Technician or CustomRoles.Saboteur => CustomRoles.Mechanic,
|
||||
CustomRoles.Inhibitor => new[] {CustomRoles.Doorjammer, CustomRoles.SecurityGuard}.RandomElement(),
|
||||
CustomRoles.Magician or CustomRoles.Curser => CustomRoles.Wizard,
|
||||
|
||||
@@ -50,7 +50,7 @@ public class MeetingManager : RoleBase
|
||||
public static void OnSwap(PlayerControl tg1, PlayerControl tg2)
|
||||
{
|
||||
foreach (byte id in PlayerIdList)
|
||||
LateTask.New(() => Utils.SendMessage(string.Format(GetString("MeetingManagerMessageAboutSwap"), CustomRoles.NiceSwapper.ToColoredString(), tg1.GetRealName().Replace("\n", " + "), tg2.GetRealName().Replace("\n", " + ")), id, Utils.ColorString(Utils.GetRoleColor(CustomRoles.MeetingManager), GetString("MeetingManagerMessageTitle"))), 1f, "Meeting Manager Messages");
|
||||
LateTask.New(() => Utils.SendMessage(string.Format(GetString("MeetingManagerMessageAboutSwap"), CustomRoles.Swapper.ToColoredString(), tg1.GetRealName().Replace("\n", " + "), tg2.GetRealName().Replace("\n", " + ")), id, Utils.ColorString(Utils.GetRoleColor(CustomRoles.MeetingManager), GetString("MeetingManagerMessageTitle"))), 1f, "Meeting Manager Messages");
|
||||
}
|
||||
|
||||
public static void OnCompare(PlayerControl tg1, PlayerControl tg2)
|
||||
|
||||
@@ -1,329 +1,329 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Modules;
|
||||
using EHR.Neutral;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
using static EHR.Translator;
|
||||
|
||||
|
||||
namespace EHR.Crewmate;
|
||||
|
||||
public class NiceSwapper : RoleBase
|
||||
{
|
||||
private const int Id = 642680;
|
||||
|
||||
public static OptionItem SwapMax;
|
||||
public static OptionItem HideMsg;
|
||||
public static OptionItem CanSwapSelf;
|
||||
public static OptionItem CanStartMeeting;
|
||||
public static OptionItem NiceSwapperAbilityUseGainWithEachTaskCompleted;
|
||||
public static OptionItem AbilityChargesWhenFinishedTasks;
|
||||
|
||||
public static (byte, byte) SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
private static byte NiceSwapperId = byte.MaxValue;
|
||||
|
||||
public override bool IsEnable => NiceSwapperId != byte.MaxValue;
|
||||
public static bool On => NiceSwapperId != byte.MaxValue;
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
Options.SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.NiceSwapper);
|
||||
|
||||
SwapMax = new IntegerOptionItem(Id + 3, "NiceSwapperMax", new(0, 20, 1), 1, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
CanSwapSelf = new BooleanOptionItem(Id + 2, "CanSwapSelfVotes", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper]);
|
||||
CanStartMeeting = new BooleanOptionItem(Id + 4, "JesterCanUseButton", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper]);
|
||||
|
||||
NiceSwapperAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 6, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.3f, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
AbilityChargesWhenFinishedTasks = new FloatOptionItem(Id + 7, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
HideMsg = new BooleanOptionItem(Id + 5, "SwapperHideMsg", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceSwapper]);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
NiceSwapperId = byte.MaxValue;
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
NiceSwapperId = playerId;
|
||||
playerId.SetAbilityUseLimit(SwapMax.GetFloat());
|
||||
}
|
||||
|
||||
public static bool SwapMsg(PlayerControl pc, string msg, bool isUI = false)
|
||||
{
|
||||
string originMsg = msg;
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInGame || pc == null || pc.GetCustomRole() != CustomRoles.NiceSwapper) return false;
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole()} : {msg} (UI: {isUI})", "Swapper");
|
||||
|
||||
int operate;
|
||||
msg = msg.ToLower().TrimStart().TrimEnd();
|
||||
|
||||
if (CheckCommand(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id"))
|
||||
operate = 1;
|
||||
else if (CheckCommand(ref msg, "sw|换票|换|swap|st", false))
|
||||
operate = 2;
|
||||
else
|
||||
return false;
|
||||
|
||||
switch (operate)
|
||||
{
|
||||
case 1:
|
||||
Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
if (!pc.IsAlive())
|
||||
{
|
||||
if (!isUI) Utils.SendMessage(GetString("SwapDead"), pc.PlayerId, sendOption: SendOption.None);
|
||||
pc.ShowPopUp(GetString("SwapDead"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pc.GetAbilityUseLimit() < 1)
|
||||
{
|
||||
if (!isUI) Utils.SendMessage(GetString("NiceSwapperTrialMax"), pc.PlayerId);
|
||||
|
||||
pc.ShowPopUp(GetString("NiceSwapperTrialMax"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HideMsg.GetBool() && !isUI)
|
||||
ChatManager.SendPreviousMessagesToAll();
|
||||
else if (pc.AmOwner && !isUI) Utils.SendMessage(originMsg, 255, pc.GetRealName());
|
||||
|
||||
if (!byte.TryParse(msg.Replace(" ", string.Empty), out byte targetId))
|
||||
{
|
||||
Utils.SendMessage(GetString("SwapHelp"), pc.PlayerId);
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerControl target = Utils.GetPlayerById(targetId);
|
||||
if (target == null) break;
|
||||
|
||||
bool targetIsntSelected = SwapTargets.Item1 != target.PlayerId && SwapTargets.Item2 != target.PlayerId; // Whether the picked target isn't already being swapped
|
||||
|
||||
bool vote1Empty = SwapTargets.Item1 == byte.MaxValue && targetIsntSelected; // Whether the first swapping slot is suitable to swap this target
|
||||
bool vote2Available = SwapTargets.Item1 != byte.MaxValue && SwapTargets.Item2 == byte.MaxValue && targetIsntSelected; // Whether the second swapping slot is suitable to swap this target
|
||||
bool selfCheck = CanSwapSelf.GetBool() || target.PlayerId != pc.PlayerId;
|
||||
|
||||
if (vote1Empty && selfCheck) // Take the first slot
|
||||
{
|
||||
SwapTargets.Item1 = target.PlayerId;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("Swap1"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} chose to swap {target.GetNameWithRole()} (first target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (vote2Available && selfCheck) // Take the second slot
|
||||
{
|
||||
SwapTargets.Item2 = target.PlayerId;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("Swap2"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} chose to swap {target.GetNameWithRole()} (second target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (target.PlayerId == SwapTargets.Item1) // If this player is already chosen to be swapped in the first slot, cancel it
|
||||
{
|
||||
SwapTargets.Item1 = byte.MaxValue;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("CancelSwap1"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} canceled swapping on {target.GetNameWithRole()} (first target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (target.PlayerId == SwapTargets.Item2) // If this player is already chosen to be swapped in the second slot, cancel it
|
||||
{
|
||||
SwapTargets.Item2 = byte.MaxValue;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("CancelSwap2"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} canceled swapping on {target.GetNameWithRole()} (second target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (!selfCheck) // When the Swapper tries to swap themselves, but they aren't allowed to
|
||||
{
|
||||
if (!isUI)
|
||||
Utils.SendMessage(GetString("CantSwapSelf"), pc.PlayerId);
|
||||
else
|
||||
pc.ShowPopUp(GetString("CantSwapSelf"));
|
||||
}
|
||||
|
||||
|
||||
if (CustomRoles.MeetingManager.RoleExist())
|
||||
{
|
||||
PlayerControl pc1 = SwapTargets.Item1.GetPlayer();
|
||||
PlayerControl pc2 = SwapTargets.Item2.GetPlayer();
|
||||
|
||||
if (pc1 != null && pc2 != null)
|
||||
MeetingManager.OnSwap(pc1, pc2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void OnExileFinish()
|
||||
{
|
||||
if (SwapTargets != (byte.MaxValue, byte.MaxValue))
|
||||
{
|
||||
Utils.GetPlayerById(NiceSwapperId).RpcRemoveAbilityUse();
|
||||
SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ManipulateVotingResult(Dictionary<byte, int> votingData, MeetingHud.VoterState[] states)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (NiceSwapperId == byte.MaxValue || SwapTargets.Item1 == byte.MaxValue || SwapTargets.Item2 == byte.MaxValue) return;
|
||||
|
||||
// Swap the number of votes received internally
|
||||
int count1 = votingData.GetValueOrDefault(SwapTargets.Item1, 0);
|
||||
int count2 = votingData.GetValueOrDefault(SwapTargets.Item2, 0);
|
||||
votingData[SwapTargets.Item1] = count2;
|
||||
votingData[SwapTargets.Item2] = count1;
|
||||
|
||||
// Swap the votes visually
|
||||
List<byte> votedFor1 = states.Where(x => x.VotedForId == SwapTargets.Item1).Select(x => x.VoterId).ToList();
|
||||
List<byte> votedFor2 = states.Where(x => x.VotedForId == SwapTargets.Item2).Select(x => x.VoterId).ToList();
|
||||
|
||||
for (var index = 0; index < states.Length; index++)
|
||||
{
|
||||
ref MeetingHud.VoterState state = ref states[index];
|
||||
|
||||
if (votedFor1.Contains(state.VoterId))
|
||||
state.VotedForId = SwapTargets.Item2;
|
||||
else if (votedFor2.Contains(state.VoterId))
|
||||
state.VotedForId = SwapTargets.Item1;
|
||||
}
|
||||
|
||||
Utils.SendMessage(string.Format(GetString("SwapVote"), SwapTargets.Item1.ColoredPlayerName(), SwapTargets.Item2.ColoredPlayerName()), title: Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceSwapper), GetString("SwapTitle")));
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
}
|
||||
|
||||
private static bool CheckCommand(ref string msg, string command, bool exact = true)
|
||||
{
|
||||
string[] comList = command.Split('|');
|
||||
|
||||
foreach (string str in comList)
|
||||
{
|
||||
if (exact)
|
||||
{
|
||||
if (msg == "/" + str) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg.StartsWith("/" + str))
|
||||
{
|
||||
msg = msg.Replace("/" + str, string.Empty);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
|
||||
{
|
||||
if (Starspawn.IsDayBreak) return;
|
||||
SwapMsg(shapeshifter, $"/sw {target.PlayerId}");
|
||||
}
|
||||
|
||||
private static void SendRPC(byte playerId)
|
||||
{
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetNiceSwapperVotes, SendOption.Reliable, AmongUsClient.Instance.HostId);
|
||||
writer.Write(playerId);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
public static void ReceiveRPC(MessageReader reader, PlayerControl pc)
|
||||
{
|
||||
byte playerId = reader.ReadByte();
|
||||
SwapMsg(pc, $"/sw {playerId}", true);
|
||||
}
|
||||
|
||||
private static void SwapperOnClick(byte playerId, MeetingHud __instance)
|
||||
{
|
||||
Logger.Msg($"Click: ID {playerId}", "NiceSwapper UI");
|
||||
|
||||
PlayerControl pc = Utils.GetPlayerById(playerId);
|
||||
if (pc == null || !pc.IsAlive() || !GameStates.IsVoting) return;
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
SwapMsg(PlayerControl.LocalPlayer, $"/sw {playerId}", true);
|
||||
else
|
||||
SendRPC(playerId);
|
||||
|
||||
if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.NiceSwapper && PlayerControl.LocalPlayer.IsAlive())
|
||||
{
|
||||
__instance.playerStates.ToList().ForEach(x =>
|
||||
{
|
||||
Transform swapButton = x.transform.FindChild("ShootButton");
|
||||
if (swapButton != null) Object.Destroy(swapButton.gameObject);
|
||||
});
|
||||
|
||||
CreateSwapperButton(__instance);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateSwapperButton(MeetingHud __instance)
|
||||
{
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
targetBox.name = "ShootButton";
|
||||
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
|
||||
var renderer = targetBox.GetComponent<SpriteRenderer>();
|
||||
|
||||
if (pc.PlayerId == pva.TargetPlayerId && (SwapTargets.Item1 == pc.PlayerId || SwapTargets.Item2 == pc.PlayerId))
|
||||
renderer.sprite = CustomButton.Get("SwapYes");
|
||||
else
|
||||
renderer.sprite = CustomButton.Get("SwapNo");
|
||||
|
||||
var button = targetBox.GetComponent<PassiveButton>();
|
||||
button.OnClick.RemoveAllListeners();
|
||||
button.OnClick.AddListener((Action)(() => SwapperOnClick(pva.TargetPlayerId, __instance)));
|
||||
}
|
||||
}
|
||||
|
||||
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
|
||||
public static class StartMeetingPatch
|
||||
{
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
public static void Postfix(MeetingHud __instance)
|
||||
{
|
||||
if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.NiceSwapper && PlayerControl.LocalPlayer.IsAlive())
|
||||
CreateSwapperButton(__instance);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ManipulateGameEndCheckCrew(out bool keepGameGoing, out int countsAs)
|
||||
{
|
||||
keepGameGoing = true;
|
||||
countsAs = 1;
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using EHR.Modules;
|
||||
using EHR.Neutral;
|
||||
using Hazel;
|
||||
using UnityEngine;
|
||||
using static EHR.Translator;
|
||||
|
||||
|
||||
namespace EHR.Crewmate;
|
||||
|
||||
public class Swapper : RoleBase
|
||||
{
|
||||
private const int Id = 642680;
|
||||
|
||||
public static OptionItem SwapMax;
|
||||
public static OptionItem HideMsg;
|
||||
public static OptionItem CanSwapSelf;
|
||||
public static OptionItem CanStartMeeting;
|
||||
public static OptionItem SwapperAbilityUseGainWithEachTaskCompleted;
|
||||
public static OptionItem AbilityChargesWhenFinishedTasks;
|
||||
|
||||
public static (byte, byte) SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
private static byte SwapperId = byte.MaxValue;
|
||||
|
||||
public override bool IsEnable => SwapperId != byte.MaxValue;
|
||||
public static bool On => SwapperId != byte.MaxValue;
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
Options.SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Swapper);
|
||||
|
||||
SwapMax = new IntegerOptionItem(Id + 3, "SwapperMax", new(0, 20, 1), 1, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
CanSwapSelf = new BooleanOptionItem(Id + 2, "CanSwapSelfVotes", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
CanStartMeeting = new BooleanOptionItem(Id + 4, "JesterCanUseButton", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
|
||||
SwapperAbilityUseGainWithEachTaskCompleted = new FloatOptionItem(Id + 6, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.05f), 0.3f, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
AbilityChargesWhenFinishedTasks = new FloatOptionItem(Id + 7, "AbilityChargesWhenFinishedTasks", new(0f, 5f, 0.05f), 0.2f, TabGroup.CrewmateRoles)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper])
|
||||
.SetValueFormat(OptionFormat.Times);
|
||||
|
||||
HideMsg = new BooleanOptionItem(Id + 5, "SwapperHideMsg", true, TabGroup.CrewmateRoles).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]);
|
||||
}
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
SwapperId = byte.MaxValue;
|
||||
}
|
||||
|
||||
public override void Add(byte playerId)
|
||||
{
|
||||
SwapperId = playerId;
|
||||
playerId.SetAbilityUseLimit(SwapMax.GetFloat());
|
||||
}
|
||||
|
||||
public static bool SwapMsg(PlayerControl pc, string msg, bool isUI = false)
|
||||
{
|
||||
string originMsg = msg;
|
||||
|
||||
if (!AmongUsClient.Instance.AmHost || !GameStates.IsInGame || pc == null || pc.GetCustomRole() != CustomRoles.Swapper) return false;
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole()} : {msg} (UI: {isUI})", "Swapper");
|
||||
|
||||
int operate;
|
||||
msg = msg.ToLower().TrimStart().TrimEnd();
|
||||
|
||||
if (CheckCommand(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id"))
|
||||
operate = 1;
|
||||
else if (CheckCommand(ref msg, "sw|换票|换|swap|st", false))
|
||||
operate = 2;
|
||||
else
|
||||
return false;
|
||||
|
||||
switch (operate)
|
||||
{
|
||||
case 1:
|
||||
Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
if (!pc.IsAlive())
|
||||
{
|
||||
if (!isUI) Utils.SendMessage(GetString("SwapDead"), pc.PlayerId, sendOption: SendOption.None);
|
||||
pc.ShowPopUp(GetString("SwapDead"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pc.GetAbilityUseLimit() < 1)
|
||||
{
|
||||
if (!isUI) Utils.SendMessage(GetString("SwapperTrialMax"), pc.PlayerId);
|
||||
|
||||
pc.ShowPopUp(GetString("SwapperTrialMax"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (HideMsg.GetBool() && !isUI)
|
||||
ChatManager.SendPreviousMessagesToAll();
|
||||
else if (pc.AmOwner && !isUI) Utils.SendMessage(originMsg, 255, pc.GetRealName());
|
||||
|
||||
if (!byte.TryParse(msg.Replace(" ", string.Empty), out byte targetId))
|
||||
{
|
||||
Utils.SendMessage(GetString("SwapHelp"), pc.PlayerId);
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerControl target = Utils.GetPlayerById(targetId);
|
||||
if (target == null) break;
|
||||
|
||||
bool targetIsntSelected = SwapTargets.Item1 != target.PlayerId && SwapTargets.Item2 != target.PlayerId; // Whether the picked target isn't already being swapped
|
||||
|
||||
bool vote1Empty = SwapTargets.Item1 == byte.MaxValue && targetIsntSelected; // Whether the first swapping slot is suitable to swap this target
|
||||
bool vote2Available = SwapTargets.Item1 != byte.MaxValue && SwapTargets.Item2 == byte.MaxValue && targetIsntSelected; // Whether the second swapping slot is suitable to swap this target
|
||||
bool selfCheck = CanSwapSelf.GetBool() || target.PlayerId != pc.PlayerId;
|
||||
|
||||
if (vote1Empty && selfCheck) // Take the first slot
|
||||
{
|
||||
SwapTargets.Item1 = target.PlayerId;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("Swap1"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} chose to swap {target.GetNameWithRole()} (first target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (vote2Available && selfCheck) // Take the second slot
|
||||
{
|
||||
SwapTargets.Item2 = target.PlayerId;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("Swap2"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} chose to swap {target.GetNameWithRole()} (second target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (target.PlayerId == SwapTargets.Item1) // If this player is already chosen to be swapped in the first slot, cancel it
|
||||
{
|
||||
SwapTargets.Item1 = byte.MaxValue;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("CancelSwap1"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} canceled swapping on {target.GetNameWithRole()} (first target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (target.PlayerId == SwapTargets.Item2) // If this player is already chosen to be swapped in the second slot, cancel it
|
||||
{
|
||||
SwapTargets.Item2 = byte.MaxValue;
|
||||
|
||||
if (!isUI) Utils.SendMessage(GetString("CancelSwap2"), pc.PlayerId);
|
||||
|
||||
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} canceled swapping on {target.GetNameWithRole()} (second target)", "Swapper");
|
||||
}
|
||||
|
||||
else if (!selfCheck) // When the Swapper tries to swap themselves, but they aren't allowed to
|
||||
{
|
||||
if (!isUI)
|
||||
Utils.SendMessage(GetString("CantSwapSelf"), pc.PlayerId);
|
||||
else
|
||||
pc.ShowPopUp(GetString("CantSwapSelf"));
|
||||
}
|
||||
|
||||
|
||||
if (CustomRoles.MeetingManager.RoleExist())
|
||||
{
|
||||
PlayerControl pc1 = SwapTargets.Item1.GetPlayer();
|
||||
PlayerControl pc2 = SwapTargets.Item2.GetPlayer();
|
||||
|
||||
if (pc1 != null && pc2 != null)
|
||||
MeetingManager.OnSwap(pc1, pc2);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void OnExileFinish()
|
||||
{
|
||||
if (SwapTargets != (byte.MaxValue, byte.MaxValue))
|
||||
{
|
||||
Utils.GetPlayerById(SwapperId).RpcRemoveAbilityUse();
|
||||
SwapTargets = (byte.MaxValue, byte.MaxValue);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ManipulateVotingResult(Dictionary<byte, int> votingData, MeetingHud.VoterState[] states)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (SwapperId == byte.MaxValue || SwapTargets.Item1 == byte.MaxValue || SwapTargets.Item2 == byte.MaxValue) return;
|
||||
|
||||
// Swap the number of votes received internally
|
||||
int count1 = votingData.GetValueOrDefault(SwapTargets.Item1, 0);
|
||||
int count2 = votingData.GetValueOrDefault(SwapTargets.Item2, 0);
|
||||
votingData[SwapTargets.Item1] = count2;
|
||||
votingData[SwapTargets.Item2] = count1;
|
||||
|
||||
// Swap the votes visually
|
||||
List<byte> votedFor1 = states.Where(x => x.VotedForId == SwapTargets.Item1).Select(x => x.VoterId).ToList();
|
||||
List<byte> votedFor2 = states.Where(x => x.VotedForId == SwapTargets.Item2).Select(x => x.VoterId).ToList();
|
||||
|
||||
for (var index = 0; index < states.Length; index++)
|
||||
{
|
||||
ref MeetingHud.VoterState state = ref states[index];
|
||||
|
||||
if (votedFor1.Contains(state.VoterId))
|
||||
state.VotedForId = SwapTargets.Item2;
|
||||
else if (votedFor2.Contains(state.VoterId))
|
||||
state.VotedForId = SwapTargets.Item1;
|
||||
}
|
||||
|
||||
Utils.SendMessage(string.Format(GetString("SwapVote"), SwapTargets.Item1.ColoredPlayerName(), SwapTargets.Item2.ColoredPlayerName()), title: Utils.ColorString(Utils.GetRoleColor(CustomRoles.Swapper), GetString("SwapTitle")));
|
||||
}
|
||||
catch (Exception e) { Utils.ThrowException(e); }
|
||||
}
|
||||
|
||||
private static bool CheckCommand(ref string msg, string command, bool exact = true)
|
||||
{
|
||||
string[] comList = command.Split('|');
|
||||
|
||||
foreach (string str in comList)
|
||||
{
|
||||
if (exact)
|
||||
{
|
||||
if (msg == "/" + str) return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg.StartsWith("/" + str))
|
||||
{
|
||||
msg = msg.Replace("/" + str, string.Empty);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnMeetingShapeshift(PlayerControl shapeshifter, PlayerControl target)
|
||||
{
|
||||
if (Starspawn.IsDayBreak) return;
|
||||
SwapMsg(shapeshifter, $"/sw {target.PlayerId}");
|
||||
}
|
||||
|
||||
private static void SendRPC(byte playerId)
|
||||
{
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetSwapperVotes, SendOption.Reliable, AmongUsClient.Instance.HostId);
|
||||
writer.Write(playerId);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
public static void ReceiveRPC(MessageReader reader, PlayerControl pc)
|
||||
{
|
||||
byte playerId = reader.ReadByte();
|
||||
SwapMsg(pc, $"/sw {playerId}", true);
|
||||
}
|
||||
|
||||
private static void SwapperOnClick(byte playerId, MeetingHud __instance)
|
||||
{
|
||||
Logger.Msg($"Click: ID {playerId}", "Swapper UI");
|
||||
|
||||
PlayerControl pc = Utils.GetPlayerById(playerId);
|
||||
if (pc == null || !pc.IsAlive() || !GameStates.IsVoting) return;
|
||||
|
||||
if (AmongUsClient.Instance.AmHost)
|
||||
SwapMsg(PlayerControl.LocalPlayer, $"/sw {playerId}", true);
|
||||
else
|
||||
SendRPC(playerId);
|
||||
|
||||
if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.Swapper && PlayerControl.LocalPlayer.IsAlive())
|
||||
{
|
||||
__instance.playerStates.ToList().ForEach(x =>
|
||||
{
|
||||
Transform swapButton = x.transform.FindChild("ShootButton");
|
||||
if (swapButton != null) Object.Destroy(swapButton.gameObject);
|
||||
});
|
||||
|
||||
CreateSwapperButton(__instance);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateSwapperButton(MeetingHud __instance)
|
||||
{
|
||||
foreach (PlayerVoteArea pva in __instance.playerStates)
|
||||
{
|
||||
PlayerControl pc = Utils.GetPlayerById(pva.TargetPlayerId);
|
||||
if (pc == null || !pc.IsAlive()) continue;
|
||||
|
||||
GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject;
|
||||
GameObject targetBox = Object.Instantiate(template, pva.transform);
|
||||
targetBox.name = "ShootButton";
|
||||
targetBox.transform.localPosition = new(-0.35f, 0.03f, -1.31f);
|
||||
var renderer = targetBox.GetComponent<SpriteRenderer>();
|
||||
|
||||
if (pc.PlayerId == pva.TargetPlayerId && (SwapTargets.Item1 == pc.PlayerId || SwapTargets.Item2 == pc.PlayerId))
|
||||
renderer.sprite = CustomButton.Get("SwapYes");
|
||||
else
|
||||
renderer.sprite = CustomButton.Get("SwapNo");
|
||||
|
||||
var button = targetBox.GetComponent<PassiveButton>();
|
||||
button.OnClick.RemoveAllListeners();
|
||||
button.OnClick.AddListener((Action)(() => SwapperOnClick(pva.TargetPlayerId, __instance)));
|
||||
}
|
||||
}
|
||||
|
||||
//[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))]
|
||||
public static class StartMeetingPatch
|
||||
{
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
public static void Postfix(MeetingHud __instance)
|
||||
{
|
||||
if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.Swapper && PlayerControl.LocalPlayer.IsAlive())
|
||||
CreateSwapperButton(__instance);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ManipulateGameEndCheckCrew(out bool keepGameGoing, out int countsAs)
|
||||
{
|
||||
keepGameGoing = true;
|
||||
countsAs = 1;
|
||||
}
|
||||
}
|
||||
@@ -3,19 +3,19 @@ using static EHR.Options;
|
||||
|
||||
namespace EHR.Impostor;
|
||||
|
||||
internal class Capitalism : RoleBase
|
||||
internal class Capitalist : RoleBase
|
||||
{
|
||||
private static readonly Dictionary<byte, int> CapitalismAddTask = [];
|
||||
public static readonly Dictionary<byte, int> CapitalismAssignTask = [];
|
||||
private static readonly Dictionary<byte, int> CapitalistAddTask = [];
|
||||
public static readonly Dictionary<byte, int> CapitalistAssignTask = [];
|
||||
public static bool On;
|
||||
public override bool IsEnable => On;
|
||||
|
||||
public override void SetupCustomOption()
|
||||
{
|
||||
SetupRoleOptions(16600, TabGroup.ImpostorRoles, CustomRoles.Capitalism);
|
||||
SetupRoleOptions(16600, TabGroup.ImpostorRoles, CustomRoles.Capitalist);
|
||||
|
||||
CapitalismKillCooldown = new FloatOptionItem(16611, "KillCooldown", new(2.5f, 60f, 0.5f), 25f, TabGroup.ImpostorRoles)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Capitalism])
|
||||
CapitalistKillCooldown = new FloatOptionItem(16611, "KillCooldown", new(2.5f, 60f, 0.5f), 25f, TabGroup.ImpostorRoles)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Capitalist])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
}
|
||||
|
||||
@@ -31,33 +31,33 @@ internal class Capitalism : RoleBase
|
||||
|
||||
public override void SetButtonTexts(HudManager hud, byte id)
|
||||
{
|
||||
hud.KillButton?.OverrideText(Translator.GetString("CapitalismButtonText"));
|
||||
hud.KillButton?.OverrideText(Translator.GetString("CapitalistButtonText"));
|
||||
}
|
||||
|
||||
public override void SetKillCooldown(byte id)
|
||||
{
|
||||
Main.AllPlayerKillCooldown[id] = CapitalismKillCooldown.GetFloat();
|
||||
Main.AllPlayerKillCooldown[id] = CapitalistKillCooldown.GetFloat();
|
||||
}
|
||||
|
||||
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
return killer.CheckDoubleTrigger(target, () =>
|
||||
{
|
||||
CapitalismAddTask.TryAdd(target.PlayerId, 0);
|
||||
CapitalismAddTask[target.PlayerId]++;
|
||||
CapitalismAssignTask.TryAdd(target.PlayerId, 0);
|
||||
CapitalismAssignTask[target.PlayerId]++;
|
||||
Logger.Info($"{killer.GetRealName()} added a task for: {target.GetRealName()}", "Capitalism Add Task");
|
||||
CapitalistAddTask.TryAdd(target.PlayerId, 0);
|
||||
CapitalistAddTask[target.PlayerId]++;
|
||||
CapitalistAssignTask.TryAdd(target.PlayerId, 0);
|
||||
CapitalistAssignTask[target.PlayerId]++;
|
||||
Logger.Info($"{killer.GetRealName()} added a task for: {target.GetRealName()}", "Capitalist Add Task");
|
||||
});
|
||||
}
|
||||
|
||||
public static bool AddTaskForPlayer(PlayerControl player)
|
||||
{
|
||||
if (CapitalismAddTask.TryGetValue(player.PlayerId, out int amount))
|
||||
if (CapitalistAddTask.TryGetValue(player.PlayerId, out int amount))
|
||||
{
|
||||
TaskState taskState = player.GetTaskState();
|
||||
taskState.AllTasksCount += amount;
|
||||
CapitalismAddTask.Remove(player.PlayerId);
|
||||
CapitalistAddTask.Remove(player.PlayerId);
|
||||
taskState.CompletedTasksCount++;
|
||||
player.RpcResetTasks(false);
|
||||
player.SyncSettings();
|
||||
@@ -125,7 +125,7 @@ public class Gangster : RoleBase
|
||||
(pc.Is(CustomRoles.Marshall) && !MarshallCanBeMadmate.GetBool()) ||
|
||||
(pc.Is(CustomRoles.Investigator) && !InvestigatorCanBeMadmate.GetBool()) ||
|
||||
(pc.Is(CustomRoles.President) && !PresidentCanBeMadmate.GetBool()) ||
|
||||
pc.Is(CustomRoles.NiceSwapper) ||
|
||||
pc.Is(CustomRoles.Swapper) ||
|
||||
pc.Is(CustomRoles.Speedrunner) ||
|
||||
pc.Is(CustomRoles.Snitch) ||
|
||||
pc.Is(CustomRoles.LazyGuy) ||
|
||||
|
||||
@@ -68,8 +68,8 @@ public class Executioner : RoleBase
|
||||
{
|
||||
List<PlayerControl> targetList = [];
|
||||
targetList.AddRange(from target in Main.AllPlayerControls where playerId != target.PlayerId where CanTargetImpostor.GetBool() || !target.Is(CustomRoleTypes.Impostor) where CanTargetNeutralKiller.GetBool() || !target.IsNeutralKiller() where CanTargetNeutralBenign.GetBool() || !target.IsNeutralBenign() where CanTargetNeutralEvil.GetBool() || (!target.IsNeutralEvil() && !target.IsNeutralPariah()) where CanTargetCoven.GetBool() || !target.Is(CustomRoleTypes.Coven) where target.GetCustomRole() is not (CustomRoles.GM or CustomRoles.SuperStar) where Main.LoversPlayers.TrueForAll(x => x.PlayerId != playerId) select target);
|
||||
targetList.AddRange(Main.AllPlayerControls.Where(x => x.IsCrewmate() && x.GetCustomRole() is not (CustomRoles.NiceSwapper or CustomRoles.Mayor or CustomRoles.NiceGuesser or CustomRoles.Dictator)));
|
||||
targetList.RemoveAll(x => x.GetCustomRole() is CustomRoles.NiceSwapper or CustomRoles.Mayor or CustomRoles.NiceGuesser or CustomRoles.Dictator or CustomRoles.Executioner or CustomRoles.Terrorist or CustomRoles.GM);
|
||||
targetList.AddRange(Main.AllPlayerControls.Where(x => x.IsCrewmate() && x.GetCustomRole() is not (CustomRoles.Swapper or CustomRoles.Mayor or CustomRoles.NiceGuesser or CustomRoles.Dictator)));
|
||||
targetList.RemoveAll(x => x.GetCustomRole() is CustomRoles.Swapper or CustomRoles.Mayor or CustomRoles.NiceGuesser or CustomRoles.Dictator or CustomRoles.Executioner or CustomRoles.Terrorist or CustomRoles.GM);
|
||||
if (!CanTargetNeutralBenign.GetBool() && !CanTargetNeutralEvil.GetBool() && !CanTargetNeutralKiller.GetBool()) targetList.RemoveAll(x => x.GetCustomRole().IsNeutral() || x.Is(CustomRoles.Bloodlust));
|
||||
|
||||
if (targetList.Count == 0)
|
||||
|
||||
Reference in new issue
Block a user