Compare commits

..
7 Commits
29 changed files with 1251 additions and 1159 deletions

No files matched your search

+1 -1
View File
@@ -293,7 +293,7 @@ internal static class FFAManager
}
else // Mixed
{
_ = new LateTask(killer.TPtoRndVent, 0.5f, "FFA-Event-TP");
_ = new LateTask(() => { killer.TPtoRndVent(); }, 0.5f, "FFA-Event-TP");
killer.Notify(GetString("FFA-Event-GetTP"));
Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat();
}
+348 -420
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using System.Linq;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Impostor;
@@ -194,95 +195,92 @@ internal static class CustomRolesHelper
};
}
public static CustomRoles GetErasedRole(this CustomRoles role)
{
return role.IsVanilla()
? role
: role switch
{
CustomRoles.Tracker => CustomRoles.CrewmateTOHE,
CustomRoles.Mayor => Options.MayorHasPortableButton.GetBool() ? CustomRoles.EngineerTOHE : CustomRoles.CrewmateTOHE,
CustomRoles.Observer => CustomRoles.CrewmateTOHE,
CustomRoles.DovesOfNeace => CustomRoles.EngineerTOHE,
CustomRoles.Monitor => Monitor.CanVent.GetBool() ? CustomRoles.EngineerTOHE : CustomRoles.CrewmateTOHE,
CustomRoles.Judge => CustomRoles.CrewmateTOHE,
CustomRoles.NiceSwapper => CustomRoles.CrewmateTOHE,
CustomRoles.Mortician => CustomRoles.CrewmateTOHE,
CustomRoles.Mediumshiper => CustomRoles.CrewmateTOHE,
CustomRoles.Bodyguard => CustomRoles.CrewmateTOHE,
CustomRoles.ParityCop => CustomRoles.CrewmateTOHE,
CustomRoles.Enigma => CustomRoles.CrewmateTOHE,
CustomRoles.Grenadier => CustomRoles.EngineerTOHE,
CustomRoles.SecurityGuard => CustomRoles.EngineerTOHE,
CustomRoles.Lighter => CustomRoles.EngineerTOHE,
CustomRoles.Ignitor => CustomRoles.EngineerTOHE,
CustomRoles.Speedrunner => CustomRoles.CrewmateTOHE,
CustomRoles.Transporter => CustomRoles.CrewmateTOHE,
CustomRoles.Veteran => CustomRoles.CrewmateTOHE,
CustomRoles.GuardianAngelTOHE => CustomRoles.GuardianAngel,
CustomRoles.Detective => CustomRoles.CrewmateTOHE,
CustomRoles.NiceGuesser => CustomRoles.CrewmateTOHE,
CustomRoles.Cleanser => CustomRoles.CrewmateTOHE,
CustomRoles.Luckey => CustomRoles.CrewmateTOHE,
CustomRoles.Lookout => CustomRoles.CrewmateTOHE,
CustomRoles.CyberStar => CustomRoles.CrewmateTOHE,
CustomRoles.Demolitionist => CustomRoles.CrewmateTOHE,
CustomRoles.Ventguard => CustomRoles.EngineerTOHE,
CustomRoles.Express => CustomRoles.CrewmateTOHE,
CustomRoles.NiceEraser => CustomRoles.CrewmateTOHE,
CustomRoles.TaskManager => CustomRoles.CrewmateTOHE,
CustomRoles.Shiftguard => CustomRoles.CrewmateTOHE,
CustomRoles.Mole => CustomRoles.EngineerTOHE,
CustomRoles.Sentinel => CustomRoles.EngineerTOHE,
CustomRoles.Electric => CustomRoles.CrewmateTOHE,
CustomRoles.Philantropist => CustomRoles.CrewmateTOHE,
CustomRoles.Tornado => CustomRoles.CrewmateTOHE,
CustomRoles.Druid => CustomRoles.EngineerTOHE,
CustomRoles.Insight => CustomRoles.CrewmateTOHE,
CustomRoles.Tunneler => CustomRoles.CrewmateTOHE,
CustomRoles.Detour => CustomRoles.CrewmateTOHE,
CustomRoles.Drainer => CustomRoles.EngineerTOHE,
CustomRoles.GuessManager => CustomRoles.CrewmateTOHE,
CustomRoles.Benefactor => CustomRoles.CrewmateTOHE,
CustomRoles.Altruist => CustomRoles.CrewmateTOHE,
CustomRoles.Transmitter => CustomRoles.CrewmateTOHE,
CustomRoles.Autocrat => CustomRoles.CrewmateTOHE,
CustomRoles.Nightmare => CustomRoles.CrewmateTOHE,
CustomRoles.CameraMan => CustomRoles.EngineerTOHE,
CustomRoles.Spy => CustomRoles.CrewmateTOHE,
CustomRoles.Ricochet => CustomRoles.CrewmateTOHE,
CustomRoles.Aid => CustomRoles.CrewmateTOHE,
CustomRoles.DonutDelivery => CustomRoles.CrewmateTOHE,
CustomRoles.Gaulois => CustomRoles.CrewmateTOHE,
CustomRoles.Analyzer => CustomRoles.CrewmateTOHE,
CustomRoles.Escort => CustomRoles.CrewmateTOHE,
CustomRoles.Doormaster => CustomRoles.EngineerTOHE,
CustomRoles.Tether => CustomRoles.EngineerTOHE,
CustomRoles.Psychic => CustomRoles.CrewmateTOHE,
CustomRoles.Needy => CustomRoles.CrewmateTOHE,
CustomRoles.SuperStar => CustomRoles.CrewmateTOHE,
CustomRoles.Paranoia => CustomRoles.EngineerTOHE,
CustomRoles.EngineerTOHE => CustomRoles.EngineerTOHE,
CustomRoles.TimeMaster => CustomRoles.EngineerTOHE,
CustomRoles.CrewmateTOHE => CustomRoles.CrewmateTOHE,
CustomRoles.Doctor => CustomRoles.ScientistTOHE,
CustomRoles.ScientistTOHE => CustomRoles.ScientistTOHE,
CustomRoles.Tracefinder => CustomRoles.ScientistTOHE,
CustomRoles.SpeedBooster => CustomRoles.CrewmateTOHE,
CustomRoles.Dictator => CustomRoles.CrewmateTOHE,
CustomRoles.Snitch => CustomRoles.CrewmateTOHE,
CustomRoles.Marshall => CustomRoles.CrewmateTOHE,
CustomRoles.SabotageMaster => CustomRoles.EngineerTOHE,
//CustomRoles.Retributionist => CustomRoles.Crewmate,
CustomRoles.Witness => CustomRoles.CrewmateTOHE,
CustomRoles.Guardian => CustomRoles.CrewmateTOHE,
CustomRoles.Addict => CustomRoles.EngineerTOHE,
CustomRoles.Alchemist => CustomRoles.EngineerTOHE,
CustomRoles.Oracle => CustomRoles.CrewmateTOHE,
CustomRoles.Chameleon => CustomRoles.EngineerTOHE,
_ => role.IsImpostor() ? CustomRoles.ImpostorTOHE : CustomRoles.CrewmateTOHE,
};
}
public static CustomRoles GetErasedRole(this CustomRoles role) => role.IsVanilla()
? role
: role switch
{
CustomRoles.Tracker => CustomRoles.CrewmateTOHE,
CustomRoles.Mayor => Options.MayorHasPortableButton.GetBool() ? CustomRoles.EngineerTOHE : CustomRoles.CrewmateTOHE,
CustomRoles.Observer => CustomRoles.CrewmateTOHE,
CustomRoles.DovesOfNeace => CustomRoles.EngineerTOHE,
CustomRoles.Monitor => Monitor.CanVent.GetBool() ? CustomRoles.EngineerTOHE : CustomRoles.CrewmateTOHE,
CustomRoles.Judge => CustomRoles.CrewmateTOHE,
CustomRoles.NiceSwapper => CustomRoles.CrewmateTOHE,
CustomRoles.Mortician => CustomRoles.CrewmateTOHE,
CustomRoles.Mediumshiper => CustomRoles.CrewmateTOHE,
CustomRoles.Bodyguard => CustomRoles.CrewmateTOHE,
CustomRoles.ParityCop => CustomRoles.CrewmateTOHE,
CustomRoles.Enigma => CustomRoles.CrewmateTOHE,
CustomRoles.Grenadier => CustomRoles.EngineerTOHE,
CustomRoles.SecurityGuard => CustomRoles.EngineerTOHE,
CustomRoles.Lighter => CustomRoles.EngineerTOHE,
CustomRoles.Ignitor => CustomRoles.EngineerTOHE,
CustomRoles.Speedrunner => CustomRoles.CrewmateTOHE,
CustomRoles.Transporter => CustomRoles.CrewmateTOHE,
CustomRoles.Veteran => CustomRoles.CrewmateTOHE,
CustomRoles.GuardianAngelTOHE => CustomRoles.GuardianAngel,
CustomRoles.Detective => CustomRoles.CrewmateTOHE,
CustomRoles.NiceGuesser => CustomRoles.CrewmateTOHE,
CustomRoles.Cleanser => CustomRoles.CrewmateTOHE,
CustomRoles.Luckey => CustomRoles.CrewmateTOHE,
CustomRoles.Lookout => CustomRoles.CrewmateTOHE,
CustomRoles.CyberStar => CustomRoles.CrewmateTOHE,
CustomRoles.Demolitionist => CustomRoles.CrewmateTOHE,
CustomRoles.Ventguard => CustomRoles.EngineerTOHE,
CustomRoles.Express => CustomRoles.CrewmateTOHE,
CustomRoles.NiceEraser => CustomRoles.CrewmateTOHE,
CustomRoles.TaskManager => CustomRoles.CrewmateTOHE,
CustomRoles.Shiftguard => CustomRoles.CrewmateTOHE,
CustomRoles.Mole => CustomRoles.EngineerTOHE,
CustomRoles.Sentinel => CustomRoles.EngineerTOHE,
CustomRoles.Electric => CustomRoles.CrewmateTOHE,
CustomRoles.Philantropist => CustomRoles.CrewmateTOHE,
CustomRoles.Tornado => CustomRoles.CrewmateTOHE,
CustomRoles.Druid => CustomRoles.EngineerTOHE,
CustomRoles.Insight => CustomRoles.CrewmateTOHE,
CustomRoles.Tunneler => CustomRoles.CrewmateTOHE,
CustomRoles.Detour => CustomRoles.CrewmateTOHE,
CustomRoles.Drainer => CustomRoles.EngineerTOHE,
CustomRoles.GuessManager => CustomRoles.CrewmateTOHE,
CustomRoles.Benefactor => CustomRoles.CrewmateTOHE,
CustomRoles.Altruist => CustomRoles.CrewmateTOHE,
CustomRoles.Transmitter => CustomRoles.CrewmateTOHE,
CustomRoles.Autocrat => CustomRoles.CrewmateTOHE,
CustomRoles.Nightmare => CustomRoles.CrewmateTOHE,
CustomRoles.CameraMan => CustomRoles.EngineerTOHE,
CustomRoles.Spy => CustomRoles.CrewmateTOHE,
CustomRoles.Ricochet => CustomRoles.CrewmateTOHE,
CustomRoles.Aid => CustomRoles.CrewmateTOHE,
CustomRoles.DonutDelivery => CustomRoles.CrewmateTOHE,
CustomRoles.Gaulois => CustomRoles.CrewmateTOHE,
CustomRoles.Analyzer => CustomRoles.CrewmateTOHE,
CustomRoles.Escort => CustomRoles.CrewmateTOHE,
CustomRoles.Doormaster => CustomRoles.EngineerTOHE,
CustomRoles.Tether => CustomRoles.EngineerTOHE,
CustomRoles.Psychic => CustomRoles.CrewmateTOHE,
CustomRoles.Needy => CustomRoles.CrewmateTOHE,
CustomRoles.SuperStar => CustomRoles.CrewmateTOHE,
CustomRoles.Paranoia => CustomRoles.EngineerTOHE,
CustomRoles.EngineerTOHE => CustomRoles.EngineerTOHE,
CustomRoles.TimeMaster => CustomRoles.EngineerTOHE,
CustomRoles.CrewmateTOHE => CustomRoles.CrewmateTOHE,
CustomRoles.Doctor => CustomRoles.ScientistTOHE,
CustomRoles.ScientistTOHE => CustomRoles.ScientistTOHE,
CustomRoles.Tracefinder => CustomRoles.ScientistTOHE,
CustomRoles.SpeedBooster => CustomRoles.CrewmateTOHE,
CustomRoles.Dictator => CustomRoles.CrewmateTOHE,
CustomRoles.Snitch => CustomRoles.CrewmateTOHE,
CustomRoles.Marshall => CustomRoles.CrewmateTOHE,
CustomRoles.SabotageMaster => CustomRoles.EngineerTOHE,
//CustomRoles.Retributionist => CustomRoles.Crewmate,
CustomRoles.Witness => CustomRoles.CrewmateTOHE,
CustomRoles.Guardian => CustomRoles.CrewmateTOHE,
CustomRoles.Addict => CustomRoles.EngineerTOHE,
CustomRoles.Alchemist => CustomRoles.EngineerTOHE,
CustomRoles.Oracle => CustomRoles.CrewmateTOHE,
CustomRoles.Chameleon => CustomRoles.EngineerTOHE,
_ => role.IsImpostor() ? CustomRoles.ImpostorTOHE : CustomRoles.CrewmateTOHE,
};
public static RoleTypes GetDYRole(this CustomRoles role)
{
@@ -375,9 +373,7 @@ internal static class CustomRolesHelper
_ => RoleTypes.GuardianAngel
};
}
public static bool IsAdditionRole(this CustomRoles role)
{
return role is
public static bool IsAdditionRole(this CustomRoles role) => role is
CustomRoles.Lovers or
CustomRoles.LastImpostor or
CustomRoles.Ntr or
@@ -435,10 +431,8 @@ internal static class CustomRolesHelper
CustomRoles.DoubleShot or
CustomRoles.Ghoul or
CustomRoles.EvilSpirit;
}
public static bool IsNonNK(this CustomRoles role) // ROLE ASSIGNING, NOT NEUTRAL TYPE
{
return role is
=> role is
CustomRoles.Jester or
CustomRoles.Terrorist or
CustomRoles.Opportunist or
@@ -458,7 +452,7 @@ internal static class CustomRolesHelper
CustomRoles.Gamer or
CustomRoles.FFF or
CustomRoles.Workaholic or
// CustomRoles.Pelican or
// CustomRoles.Pelican or
CustomRoles.Collector or
CustomRoles.Sunnyboy or
CustomRoles.Maverick or
@@ -469,11 +463,9 @@ internal static class CustomRolesHelper
CustomRoles.VengefulRomantic or
CustomRoles.Doomsayer or
CustomRoles.Succubus;
}
public static bool IsAmneMaverick(this CustomRoles role) // ROLE ASSIGNING, NOT NEUTRAL TYPE
{
return role is
=> role is
CustomRoles.Jester or
CustomRoles.Terrorist or
CustomRoles.Opportunist or
@@ -499,7 +491,7 @@ internal static class CustomRolesHelper
CustomRoles.Gamer or
CustomRoles.FFF or
CustomRoles.Workaholic or
// CustomRoles.Pelican or
// CustomRoles.Pelican or
CustomRoles.Collector or
CustomRoles.Sunnyboy or
CustomRoles.Arsonist or
@@ -518,10 +510,7 @@ internal static class CustomRolesHelper
// CustomRoles.Poisoner or
// CustomRoles.HexMaster or
CustomRoles.Totocalcio;
}
public static bool IsAmneNK(this CustomRoles role)
{
return role is
public static bool IsAmneNK(this CustomRoles role) => role is
CustomRoles.Sidekick or
CustomRoles.Infectious or
CustomRoles.Glitch or
@@ -551,11 +540,8 @@ internal static class CustomRolesHelper
CustomRoles.Virus or
CustomRoles.Spiritcaller or
CustomRoles.Succubus;
}
public static bool IsNK(this CustomRoles role)
{
return role is
public static bool IsNK(this CustomRoles role) => role is
CustomRoles.Jackal or
CustomRoles.Glitch or
CustomRoles.Sidekick or
@@ -600,10 +586,7 @@ internal static class CustomRolesHelper
CustomRoles.RuthlessRomantic or
CustomRoles.PlagueBearer or
CustomRoles.Pestilence;
}
public static bool IsSnitchTarget(this CustomRoles role)
{
return role is
public static bool IsSnitchTarget(this CustomRoles role) => role is
CustomRoles.Jackal or
CustomRoles.Sidekick or
CustomRoles.HexMaster or
@@ -645,10 +628,7 @@ internal static class CustomRolesHelper
CustomRoles.RuthlessRomantic or
CustomRoles.PlagueBearer or
CustomRoles.Pestilence;
}
public static bool IsNE(this CustomRoles role)
{
return role is
public static bool IsNE(this CustomRoles role) => role is
CustomRoles.Jester or
CustomRoles.Gamer or
//CustomRoles.Masochist or
@@ -656,10 +636,7 @@ internal static class CustomRolesHelper
CustomRoles.Executioner or
CustomRoles.Doomsayer or
CustomRoles.Innocent;
}
public static bool IsNB(this CustomRoles role)
{
return role is
public static bool IsNB(this CustomRoles role) => role is
CustomRoles.Opportunist or
CustomRoles.Lawyer or
CustomRoles.Amnesiac or
@@ -672,10 +649,7 @@ internal static class CustomRolesHelper
CustomRoles.Romantic or
CustomRoles.VengefulRomantic or
CustomRoles.Totocalcio;
}
public static bool IsNC(this CustomRoles role)
{
return role is
public static bool IsNC(this CustomRoles role) => role is
CustomRoles.Mario or
CustomRoles.Terrorist or
//CustomRoles.Pirate or
@@ -688,10 +662,7 @@ internal static class CustomRolesHelper
CustomRoles.Workaholic or
CustomRoles.Collector or
CustomRoles.Provocateur;
}
public static bool IsNeutralKilling(this CustomRoles role)
{
return role is
public static bool IsNeutralKilling(this CustomRoles role) => role is
CustomRoles.Terrorist or
CustomRoles.Arsonist or
CustomRoles.Juggernaut or
@@ -743,10 +714,7 @@ internal static class CustomRolesHelper
CustomRoles.RuthlessRomantic or
CustomRoles.PlagueBearer or
CustomRoles.Pestilence;
}
public static bool IsCK(this CustomRoles role)
{
return role is
public static bool IsCK(this CustomRoles role) => role is
CustomRoles.SwordsMan or
CustomRoles.Veteran or
CustomRoles.CopyCat or
@@ -758,10 +726,8 @@ internal static class CustomRolesHelper
//CustomRoles.Retributionist or
CustomRoles.Sheriff or
CustomRoles.Jailor;
}
public static bool IsImpostor(this CustomRoles role) // IsImp
{
return role is
=> role is
CustomRoles.Impostor or
CustomRoles.Godfather or
CustomRoles.Shapeshifter or
@@ -839,10 +805,7 @@ internal static class CustomRolesHelper
CustomRoles.Camouflager or
CustomRoles.Twister or
CustomRoles.Lurker;
}
public static bool IsNeutral(this CustomRoles role)
{
return role is
public static bool IsNeutral(this CustomRoles role) => role is
//SoloKombat
CustomRoles.KB_Normal or
//FFA
@@ -929,11 +892,8 @@ internal static class CustomRolesHelper
CustomRoles.Succubus or
CustomRoles.Doomsayer or
CustomRoles.Spiritcaller;
}
public static bool IsAbleToBeSidekicked(this CustomRoles role)
{
return role is
public static bool IsAbleToBeSidekicked(this CustomRoles role) => role is
CustomRoles.BloodKnight or
CustomRoles.Virus or
CustomRoles.Medusa or
@@ -1000,11 +960,7 @@ internal static class CustomRolesHelper
CustomRoles.Parasite or
CustomRoles.PlagueBearer;
}
public static bool IsEvilAddons(this CustomRoles role)
{
return role is
public static bool IsEvilAddons(this CustomRoles role) => role is
CustomRoles.Madmate or
CustomRoles.Egoist or
CustomRoles.Charmed or
@@ -1014,19 +970,13 @@ internal static class CustomRolesHelper
CustomRoles.Rogue or
CustomRoles.Rascal or
CustomRoles.Soulless;
}
public static bool IsMadmate(this CustomRoles role)
{
return role is
public static bool IsMadmate(this CustomRoles role) => role is
CustomRoles.Crewpostor or
CustomRoles.Convict or
CustomRoles.Refugee or
CustomRoles.Parasite;
}
public static bool IsTasklessCrewmate(this CustomRoles role)
{
return !role.UsesPetInsteadOfKill() && role is
public static bool IsTasklessCrewmate(this CustomRoles role) => !role.UsesPetInsteadOfKill() && role is
CustomRoles.Sheriff or
CustomRoles.Admirer or
CustomRoles.Medic or
@@ -1045,98 +995,93 @@ internal static class CustomRolesHelper
CustomRoles.Farseer or
CustomRoles.SwordsMan or
CustomRoles.Deputy;
}
public static bool PetActivatedAbility(this CustomRoles role)
public static bool PetActivatedAbility(this CustomRoles role) => Options.UsePets.GetBool() && role switch
{
return Options.UsePets.GetBool() && role switch
{
CustomRoles.Doormaster or
CustomRoles.Tether or
CustomRoles.Mayor or
CustomRoles.Paranoia or
CustomRoles.Grenadier or
CustomRoles.Veteran or
CustomRoles.Lighter or
CustomRoles.SecurityGuard or
CustomRoles.DovesOfNeace or
CustomRoles.Alchemist or
CustomRoles.TimeMaster or
CustomRoles.Sapper or
CustomRoles.CameraMan or
CustomRoles.NiceHacker or
CustomRoles.Druid or
CustomRoles.Tunneler or
CustomRoles.Tornado or
CustomRoles.Sentinel or
CustomRoles.Lookout or
CustomRoles.Sniper or
CustomRoles.Warlock or
CustomRoles.Assassin or
CustomRoles.Undertaker or
CustomRoles.Disperser or
CustomRoles.Twister or
CustomRoles.QuickShooter or
CustomRoles.Miner or
CustomRoles.Escapee or
CustomRoles.RiftMaker or
CustomRoles.Bomber or
CustomRoles.Nuker or
CustomRoles.Glitch or
CustomRoles.Magician or
CustomRoles.WeaponMaster or
CustomRoles.Enderman or
CustomRoles.Mycologist or
CustomRoles.Hookshot or
CustomRoles.Sprayer
=> true,
CustomRoles.Doormaster or
CustomRoles.Tether or
CustomRoles.Mayor or
CustomRoles.Paranoia or
CustomRoles.Grenadier or
CustomRoles.Veteran or
CustomRoles.Lighter or
CustomRoles.SecurityGuard or
CustomRoles.DovesOfNeace or
CustomRoles.Alchemist or
CustomRoles.TimeMaster or
CustomRoles.Sapper or
CustomRoles.CameraMan or
CustomRoles.NiceHacker or
CustomRoles.Druid or
CustomRoles.Tunneler or
CustomRoles.Tornado or
CustomRoles.Sentinel or
CustomRoles.Lookout or
CustomRoles.Sniper or
CustomRoles.Warlock or
CustomRoles.Assassin or
CustomRoles.Undertaker or
CustomRoles.Disperser or
CustomRoles.Twister or
CustomRoles.QuickShooter or
CustomRoles.Miner or
CustomRoles.Escapee or
CustomRoles.RiftMaker or
CustomRoles.Bomber or
CustomRoles.Nuker or
CustomRoles.Glitch or
CustomRoles.Magician or
CustomRoles.WeaponMaster or
CustomRoles.Enderman or
CustomRoles.Mycologist or
CustomRoles.Hookshot or
CustomRoles.Sprayer
=> true,
CustomRoles.Gaulois when Gaulois.UsePet.GetBool() => true,
CustomRoles.Aid when Aid.UsePet.GetBool() => true,
CustomRoles.Escort when Escort.UsePet.GetBool() => true,
CustomRoles.DonutDelivery when DonutDelivery.UsePet.GetBool() => true,
CustomRoles.Analyzer when Analyzer.UsePet.GetBool() => true,
CustomRoles.Jailor when Jailor.UsePet.GetBool() => true,
CustomRoles.Sheriff when Sheriff.UsePet.GetBool() => true,
CustomRoles.SwordsMan when SwordsMan.UsePet.GetBool() => true,
CustomRoles.Medic when Medic.UsePet.GetBool() => true,
CustomRoles.Monarch when Monarch.UsePet.GetBool() => true,
CustomRoles.CopyCat when CopyCat.UsePet.GetBool() => true,
CustomRoles.Farseer when Farseer.UsePet.GetBool() => true,
CustomRoles.Deputy when Deputy.UsePet.GetBool() => true,
CustomRoles.Admirer when Admirer.UsePet.GetBool() => true,
CustomRoles.Crusader when Crusader.UsePet.GetBool() => true,
CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true,
CustomRoles.Gaulois when Gaulois.UsePet.GetBool() => true,
CustomRoles.Aid when Aid.UsePet.GetBool() => true,
CustomRoles.Escort when Escort.UsePet.GetBool() => true,
CustomRoles.DonutDelivery when DonutDelivery.UsePet.GetBool() => true,
CustomRoles.Analyzer when Analyzer.UsePet.GetBool() => true,
CustomRoles.Jailor when Jailor.UsePet.GetBool() => true,
CustomRoles.Sheriff when Sheriff.UsePet.GetBool() => true,
CustomRoles.SwordsMan when SwordsMan.UsePet.GetBool() => true,
CustomRoles.Medic when Medic.UsePet.GetBool() => true,
CustomRoles.Monarch when Monarch.UsePet.GetBool() => true,
CustomRoles.CopyCat when CopyCat.UsePet.GetBool() => true,
CustomRoles.Farseer when Farseer.UsePet.GetBool() => true,
CustomRoles.Deputy when Deputy.UsePet.GetBool() => true,
CustomRoles.Admirer when Admirer.UsePet.GetBool() => true,
CustomRoles.Crusader when Crusader.UsePet.GetBool() => true,
CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true,
_ => false,
};
}
public static bool UsesPetInsteadOfKill(this CustomRoles role)
_ => false,
};
public static bool UsesPetInsteadOfKill(this CustomRoles role) => Options.UsePets.GetBool() && role switch
{
return Options.UsePets.GetBool() && role switch
{
CustomRoles.Gaulois when Gaulois.UsePet.GetBool() => true,
CustomRoles.Aid when Aid.UsePet.GetBool() => true,
CustomRoles.Escort when Escort.UsePet.GetBool() => true,
CustomRoles.DonutDelivery when DonutDelivery.UsePet.GetBool() => true,
CustomRoles.Analyzer when Analyzer.UsePet.GetBool() => true,
CustomRoles.Jailor when Jailor.UsePet.GetBool() => true,
CustomRoles.Sheriff when Sheriff.UsePet.GetBool() => true,
CustomRoles.SwordsMan when SwordsMan.UsePet.GetBool() => true,
CustomRoles.Medic when Medic.UsePet.GetBool() => true,
CustomRoles.Monarch when Monarch.UsePet.GetBool() => true,
CustomRoles.CopyCat when CopyCat.UsePet.GetBool() => true,
CustomRoles.Farseer when Farseer.UsePet.GetBool() => true,
CustomRoles.Deputy when Deputy.UsePet.GetBool() => true,
CustomRoles.Admirer when Admirer.UsePet.GetBool() => true,
CustomRoles.Crusader when Crusader.UsePet.GetBool() => true,
CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true,
CustomRoles.Gaulois when Gaulois.UsePet.GetBool() => true,
CustomRoles.Aid when Aid.UsePet.GetBool() => true,
CustomRoles.Escort when Escort.UsePet.GetBool() => true,
CustomRoles.DonutDelivery when DonutDelivery.UsePet.GetBool() => true,
CustomRoles.Analyzer when Analyzer.UsePet.GetBool() => true,
CustomRoles.Jailor when Jailor.UsePet.GetBool() => true,
CustomRoles.Sheriff when Sheriff.UsePet.GetBool() => true,
CustomRoles.SwordsMan when SwordsMan.UsePet.GetBool() => true,
CustomRoles.Medic when Medic.UsePet.GetBool() => true,
CustomRoles.Monarch when Monarch.UsePet.GetBool() => true,
CustomRoles.CopyCat when CopyCat.UsePet.GetBool() => true,
CustomRoles.Farseer when Farseer.UsePet.GetBool() => true,
CustomRoles.Deputy when Deputy.UsePet.GetBool() => true,
CustomRoles.Admirer when Admirer.UsePet.GetBool() => true,
CustomRoles.Crusader when Crusader.UsePet.GetBool() => true,
CustomRoles.Witness when Options.WitnessUsePet.GetBool() => true,
_ => false,
};
}
public static bool NeedUpdateOnLights(this CustomRoles role)
{
return (!role.UsesPetInsteadOfKill()) && (role.GetDYRole() != RoleTypes.GuardianAngel || role is
_ => false,
};
public static List<CustomRoles> OnlySpawnsWithPetsRoleList = [
CustomRoles.Tunneler,
CustomRoles.Tornado
];
public static bool NeedUpdateOnLights(this CustomRoles role) => (!role.UsesPetInsteadOfKill()) && (role.GetDYRole() != RoleTypes.GuardianAngel || role is
CustomRoles.Sheriff or
CustomRoles.Medic or
CustomRoles.CopyCat or
@@ -1221,35 +1166,28 @@ internal static class CustomRolesHelper
CustomRoles.Bandit or
CustomRoles.Agitater or
CustomRoles.Deputy);
}
public static bool IsBetrayalAddon(this CustomRoles role)
{
return role is CustomRoles.Charmed or
CustomRoles.Recruit or
CustomRoles.Infected or
CustomRoles.Contagious or
CustomRoles.Lovers or
CustomRoles.Madmate or
CustomRoles.Soulless or
CustomRoles.Admired or
CustomRoles.Egoist;
}
public static bool IsBetrayalAddon(this CustomRoles role) => role is
CustomRoles.Charmed or
CustomRoles.Recruit or
CustomRoles.Infected or
CustomRoles.Contagious or
CustomRoles.Lovers or
CustomRoles.Madmate or
CustomRoles.Soulless or
CustomRoles.Admired or
CustomRoles.Egoist;
public static bool IsImpOnlyAddon(this CustomRoles role)
{
return role is CustomRoles.Mare or
CustomRoles.LastImpostor or
CustomRoles.Mare or
CustomRoles.Mimic or
CustomRoles.Damocles or
CustomRoles.DeadlyQuota or
CustomRoles.TicketsStealer or
CustomRoles.Swift;
}
public static bool IsTaskBasedCrewmate(this CustomRoles role)
{
return role is
public static bool IsImpOnlyAddon(this CustomRoles role) => role is
CustomRoles.Mare or
CustomRoles.LastImpostor or
CustomRoles.Mare or
CustomRoles.Mimic or
CustomRoles.Damocles or
CustomRoles.DeadlyQuota or
CustomRoles.TicketsStealer or
CustomRoles.Swift;
public static bool IsTaskBasedCrewmate(this CustomRoles role) => role is
CustomRoles.Snitch or
CustomRoles.Divinator or
CustomRoles.Marshall or
@@ -1259,154 +1197,147 @@ internal static class CustomRolesHelper
CustomRoles.Merchant or
CustomRoles.Mayor or
CustomRoles.Transporter;
}
public static bool IsNotKnightable(this CustomRoles role)
public static bool IsNotKnightable(this CustomRoles role) => role is
CustomRoles.Mayor or
CustomRoles.Vindicator or
CustomRoles.Dictator or
CustomRoles.Knighted or
CustomRoles.Glitch or
CustomRoles.Pickpocket or
CustomRoles.TicketsStealer;
public static bool CheckAddonConflictV2(CustomRoles addon, CustomRoles mainRole) => addon.IsAdditionRole() && mainRole is not CustomRoles.GuardianAngelTOHE and not CustomRoles.God and not CustomRoles.GM && addon is not CustomRoles.Lovers && addon switch
{
return role is
CustomRoles.Mayor or
CustomRoles.Vindicator or
CustomRoles.Dictator or
CustomRoles.Knighted or
CustomRoles.Glitch or
CustomRoles.Pickpocket or
CustomRoles.TicketsStealer;
}
public static bool CheckAddonConflictV2(CustomRoles addon, CustomRoles mainRole)
{
return addon.IsAdditionRole() && mainRole is not CustomRoles.GuardianAngelTOHE and not CustomRoles.God and not CustomRoles.GM && addon is not CustomRoles.Lovers && addon switch
{
CustomRoles.Lovers when mainRole is CustomRoles.RuthlessRomantic or CustomRoles.Romantic or CustomRoles.VengefulRomantic => false,
CustomRoles.Autopsy when mainRole is CustomRoles.Doctor or CustomRoles.Tracefinder or CustomRoles.Scientist or CustomRoles.ScientistTOHE or CustomRoles.Sunnyboy => false,
CustomRoles.Necroview when mainRole is CustomRoles.Doctor => false,
CustomRoles.Lazy when mainRole is CustomRoles.Speedrunner => false,
CustomRoles.Loyal when mainRole.IsCrewmate() && !Options.CrewCanBeLoyal.GetBool() => false,
CustomRoles.DualPersonality when mainRole.IsCrewmate() && !Options.CrewCanBeDualPersonality.GetBool() => false,
CustomRoles.Lazy when mainRole is CustomRoles.Needy or CustomRoles.Snitch or CustomRoles.Marshall or CustomRoles.Transporter or CustomRoles.Guardian => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Needy or CustomRoles.Snitch or CustomRoles.Marshall or CustomRoles.Transporter or CustomRoles.Guardian => false,
CustomRoles.Egoist when mainRole.IsCrewmate() && !Options.CrewCanBeEgoist.GetBool() => false,
CustomRoles.Brakar when mainRole is CustomRoles.Dictator => false,
CustomRoles.Stressed when !mainRole.IsCrewmate() || mainRole.IsTasklessCrewmate() => false,
CustomRoles.Avanger when mainRole.IsImpostor() && !Options.ImpCanBeAvanger.GetBool() => false,
CustomRoles.Ghoul when mainRole.IsNeutral() || mainRole.IsImpostor() || mainRole.IsTasklessCrewmate() || mainRole.IsTaskBasedCrewmate() => false,
CustomRoles.Lazy when mainRole.IsNeutral() || mainRole.IsImpostor() || mainRole.IsTasklessCrewmate() && !Options.TasklessCrewCanBeLazy.GetBool() || mainRole.IsTaskBasedCrewmate() && !Options.TaskBasedCrewCanBeLazy.GetBool() => false,
CustomRoles.TicketsStealer or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when mainRole is CustomRoles.Bomber or CustomRoles.Nuker or CustomRoles.BoobyTrap or CustomRoles.Capitalism => false,
CustomRoles.TicketsStealer or CustomRoles.Mimic or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when !mainRole.IsImpostor() => false,
CustomRoles.Torch when !mainRole.IsCrewmate() || mainRole is CustomRoles.Bewilder or CustomRoles.Sunglasses or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Torch or CustomRoles.GuardianAngelTOHE or CustomRoles.Sunglasses => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Torch or CustomRoles.GuardianAngelTOHE or CustomRoles.Bewilder => false,
CustomRoles.Guesser when mainRole.IsCrewmate() && (!Options.CrewCanBeGuesser.GetBool() || mainRole is CustomRoles.NiceGuesser) || mainRole.IsNeutral() && !Options.NeutralCanBeGuesser.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGuesser.GetBool() || mainRole is CustomRoles.EvilGuesser or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Madmate when mainRole is CustomRoles.Egoist or CustomRoles.Rascal => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Detective or CustomRoles.Cleaner or CustomRoles.Medusa or CustomRoles.Mortician or CustomRoles.Mediumshiper or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Youtuber when !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate or CustomRoles.Sheriff or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Egoist when mainRole.IsImpostor() && !Options.ImpCanBeEgoist.GetBool() => false,
CustomRoles.Egoist when mainRole.IsNeutral() || mainRole is CustomRoles.Madmate => false,
CustomRoles.Damocles when mainRole is CustomRoles.Bomber or CustomRoles.Nuker or CustomRoles.SerialKiller or CustomRoles.Cantankerous => false,
CustomRoles.Necroview when mainRole is CustomRoles.Visionary => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Lazy => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Needy => false,
CustomRoles.Lazy when mainRole is CustomRoles.Ghoul => false,
CustomRoles.Mimic when mainRole is CustomRoles.Mafia => false,
CustomRoles.Rascal when !mainRole.IsCrewmate() => false,
CustomRoles.Needy when mainRole.IsAdditionRole() => false,
CustomRoles.TicketsStealer when mainRole is CustomRoles.Vindicator => false,
CustomRoles.Mare when mainRole is CustomRoles.Underdog => false,
CustomRoles.Mare when mainRole is CustomRoles.Inhibitor => false,
CustomRoles.Mare when mainRole is CustomRoles.Saboteur => false,
CustomRoles.Mare when mainRole is CustomRoles.Swift => false,
CustomRoles.Mare when mainRole is CustomRoles.Mafia => false,
CustomRoles.Mare when mainRole is CustomRoles.Sniper => false,
CustomRoles.Mare when mainRole is CustomRoles.FireWorks => false,
CustomRoles.Mare when mainRole is CustomRoles.Swooper => false,
CustomRoles.Mare when mainRole is CustomRoles.Vampire => false,
CustomRoles.Torch when mainRole is CustomRoles.Lighter => false,
CustomRoles.Torch when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Lighter => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Lighter => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Bait when mainRole is CustomRoles.Demolitionist => false,
CustomRoles.Trapper when mainRole is CustomRoles.Demolitionist => false,
CustomRoles.Lovers when mainRole is CustomRoles.Romantic => false,
CustomRoles.Mare when mainRole is CustomRoles.LastImpostor => false,
CustomRoles.Swift when mainRole is CustomRoles.Mare => false,
CustomRoles.DualPersonality when !mainRole.IsImpostor() && !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate => false,
CustomRoles.DualPersonality when mainRole.IsImpostor() && !Options.ImpCanBeDualPersonality.GetBool() => false,
CustomRoles.Loyal when !mainRole.IsImpostor() && !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate => false,
CustomRoles.Loyal when mainRole.IsImpostor() && !Options.ImpCanBeLoyal.GetBool() => false,
CustomRoles.Seer when mainRole.IsCrewmate() && (!Options.CrewCanBeSeer.GetBool() || mainRole is CustomRoles.Mortician) || mainRole.IsNeutral() && !Options.NeutralCanBeSeer.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeSeer.GetBool() || mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bait when mainRole.IsCrewmate() && !Options.CrewCanBeBait.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeBait.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeBait.GetBool() => false,
CustomRoles.Bewilder when mainRole.IsCrewmate() && !Options.CrewCanBeBewilder.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeBewilder.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeBewilder.GetBool() => false,
CustomRoles.Sunglasses when mainRole.IsCrewmate() && !Options.CrewCanBeSunglasses.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeSunglasses.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeSunglasses.GetBool() => false,
CustomRoles.Autopsy when mainRole.IsCrewmate() && !Options.CrewCanBeAutopsy.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeAutopsy.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeAutopsy.GetBool() => false,
CustomRoles.Glow when mainRole.IsCrewmate() && !Options.CrewCanBeGlow.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeGlow.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGlow.GetBool() => false,
CustomRoles.Trapper when mainRole.IsCrewmate() && !Options.CrewCanBeTrapper.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeTrapper.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeTrapper.GetBool() => false,
CustomRoles.Sidekick when mainRole is CustomRoles.Madmate => false,
CustomRoles.Onbound when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Rascal when mainRole is CustomRoles.SuperStar or CustomRoles.Madmate => false,
CustomRoles.Madmate when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Gravestone when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Sidekick when mainRole.IsNeutral() && !Options.NeutralCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole.IsCrewmate() && !Options.CrewmateCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole.IsImpostor() && !Options.ImpostorCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole is CustomRoles.Jackal => false,
CustomRoles.Lucky when mainRole is CustomRoles.Guardian => false,
CustomRoles.Bait when mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bait when mainRole is CustomRoles.Trapper => false,
CustomRoles.Trapper when mainRole is CustomRoles.Bait => false,
CustomRoles.DualPersonality when mainRole is CustomRoles.Dictator => false,
CustomRoles.Swift when mainRole is CustomRoles.Swooper => false,
CustomRoles.Swift when mainRole is CustomRoles.Vampire => false,
CustomRoles.Swift when mainRole is CustomRoles.Scavenger => false,
CustomRoles.Swift when mainRole is CustomRoles.Puppeteer => false,
CustomRoles.Swift when mainRole is CustomRoles.Warlock => false,
CustomRoles.Swift when mainRole is CustomRoles.EvilDiviner => false,
CustomRoles.Swift when mainRole is CustomRoles.Witch => false,
CustomRoles.Swift when mainRole is CustomRoles.Mafia => false,
CustomRoles.Reach when mainRole is CustomRoles.Mafioso => false,
CustomRoles.Trapper when mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Watcher when mainRole.IsCrewmate() && !Options.CrewCanBeWatcher.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeWatcher.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeWatcher.GetBool() => false,
CustomRoles.Diseased when mainRole.IsCrewmate() && !Options.CrewCanBeDiseased.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeDiseased.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeDiseased.GetBool() => false,
CustomRoles.Antidote when mainRole.IsCrewmate() && !Options.CrewCanBeAntidote.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeAntidote.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeAntidote.GetBool() => false,
CustomRoles.Diseased when mainRole is CustomRoles.Antidote => false,
CustomRoles.Antidote when mainRole is CustomRoles.Diseased => false,
CustomRoles.Necroview when mainRole.IsCrewmate() && !Options.CrewCanBeNecroview.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeNecroview.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeNecroview.GetBool() => false,
CustomRoles.Oblivious when mainRole.IsCrewmate() && !Options.CrewCanBeOblivious.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeOblivious.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeOblivious.GetBool() => false,
CustomRoles.Brakar when mainRole.IsCrewmate() && !Options.CrewCanBeTiebreaker.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeTiebreaker.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeTiebreaker.GetBool() => false,
CustomRoles.Guesser when mainRole.IsCrewmate() && !Options.CrewCanBeGuesser.GetBool() && mainRole is CustomRoles.NiceGuesser || mainRole.IsNeutral() && !Options.NeutralCanBeGuesser.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGuesser.GetBool() && mainRole is CustomRoles.EvilGuesser => false,
CustomRoles.Onbound when mainRole.IsCrewmate() && !Options.CrewCanBeOnbound.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeOnbound.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeOnbound.GetBool() => false,
CustomRoles.Unreportable when mainRole.IsCrewmate() && !Options.CrewCanBeUnreportable.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeUnreportable.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeUnreportable.GetBool() => false,
CustomRoles.Lucky when mainRole.IsCrewmate() && !Options.CrewCanBeLucky.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeLucky.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeLucky.GetBool() => false,
CustomRoles.Unlucky when mainRole.IsCrewmate() && !Options.CrewCanBeUnlucky.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeUnlucky.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeUnlucky.GetBool() => false,
CustomRoles.Rogue when mainRole.IsCrewmate() && !Options.CrewCanBeRogue.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeRogue.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeRogue.GetBool() => false,
CustomRoles.Gravestone when mainRole.IsCrewmate() && !Options.CrewCanBeGravestone.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeGravestone.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGravestone.GetBool() => false,
CustomRoles.Flashman when mainRole is CustomRoles.Swooper or CustomRoles.Wraith or CustomRoles.Chameleon or CustomRoles.Alchemist => false,
CustomRoles.Bait when mainRole is CustomRoles.Unreportable => false,
CustomRoles.Nimble when !mainRole.IsCrewmate() => false,
CustomRoles.Physicist when !mainRole.IsCrewmate() => false,
CustomRoles.Unreportable when mainRole is CustomRoles.Bait => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Bloodhound => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Vulture => false,
CustomRoles.Vulture when mainRole is CustomRoles.Oblivious => false,
CustomRoles.Guesser when mainRole is CustomRoles.CopyCat or CustomRoles.Doomsayer => false,
CustomRoles.CopyCat when mainRole is CustomRoles.Guesser => false,
CustomRoles.DoubleShot when mainRole is CustomRoles.CopyCat => false,
CustomRoles.CopyCat when mainRole is CustomRoles.DoubleShot => false,
CustomRoles.Brakar when mainRole is CustomRoles.Dictator => false,
CustomRoles.Lucky when mainRole is CustomRoles.Luckey => false,
CustomRoles.Unlucky when mainRole is CustomRoles.Luckey => false,
CustomRoles.Unlucky when mainRole is CustomRoles.Lucky => false,
CustomRoles.Lucky when mainRole is CustomRoles.Unlucky => false,
CustomRoles.Fool when mainRole.IsCrewmate() && !Options.CrewCanBeFool.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeFool.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeFool.GetBool() || mainRole is CustomRoles.SabotageMaster or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bloodhound when mainRole is CustomRoles.Oblivious => false,
CustomRoles.DoubleShot when mainRole.GetCustomRoleTypes() is CustomRoleTypes.Impostor && !Options.ImpCanBeDoubleShot.GetBool() || mainRole.GetCustomRoleTypes() is CustomRoleTypes.Crewmate && !Options.CrewCanBeDoubleShot.GetBool() || mainRole.GetCustomRoleTypes() is CustomRoleTypes.Neutral && !Options.NeutralCanBeDoubleShot.GetBool() => false,
CustomRoles.DoubleShot when mainRole is not CustomRoles.EvilGuesser && mainRole is not CustomRoles.NiceGuesser && !Options.GuesserMode.GetBool() => false,
CustomRoles.DoubleShot when Options.ImpCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && mainRole is not CustomRoles.EvilGuesser && mainRole.GetCustomRoleTypes() is CustomRoleTypes.Impostor && !Options.ImpostorsCanGuess.GetBool() => false,
CustomRoles.DoubleShot when Options.CrewCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && mainRole is not CustomRoles.NiceGuesser && mainRole.GetCustomRoleTypes() is CustomRoleTypes.Crewmate && !Options.CrewmatesCanGuess.GetBool() => false,
CustomRoles.DoubleShot when Options.NeutralCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && (mainRole.IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool() || mainRole.IsNK() && !Options.NeutralKillersCanGuess.GetBool()) => false,
_ => true
};
}
CustomRoles.Lovers when mainRole is CustomRoles.RuthlessRomantic or CustomRoles.Romantic or CustomRoles.VengefulRomantic => false,
CustomRoles.Autopsy when mainRole is CustomRoles.Doctor or CustomRoles.Tracefinder or CustomRoles.Scientist or CustomRoles.ScientistTOHE or CustomRoles.Sunnyboy => false,
CustomRoles.Necroview when mainRole is CustomRoles.Doctor => false,
CustomRoles.Lazy when mainRole is CustomRoles.Speedrunner => false,
CustomRoles.Loyal when mainRole.IsCrewmate() && !Options.CrewCanBeLoyal.GetBool() => false,
CustomRoles.DualPersonality when mainRole.IsCrewmate() && !Options.CrewCanBeDualPersonality.GetBool() => false,
CustomRoles.Lazy when mainRole is CustomRoles.Needy or CustomRoles.Snitch or CustomRoles.Marshall or CustomRoles.Transporter or CustomRoles.Guardian => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Needy or CustomRoles.Snitch or CustomRoles.Marshall or CustomRoles.Transporter or CustomRoles.Guardian => false,
CustomRoles.Egoist when mainRole.IsCrewmate() && !Options.CrewCanBeEgoist.GetBool() => false,
CustomRoles.Brakar when mainRole is CustomRoles.Dictator => false,
CustomRoles.Stressed when !mainRole.IsCrewmate() || mainRole.IsTasklessCrewmate() => false,
CustomRoles.Avanger when mainRole.IsImpostor() && !Options.ImpCanBeAvanger.GetBool() => false,
CustomRoles.Ghoul when mainRole.IsNeutral() || mainRole.IsImpostor() || mainRole.IsTasklessCrewmate() || mainRole.IsTaskBasedCrewmate() => false,
CustomRoles.Lazy when mainRole.IsNeutral() || mainRole.IsImpostor() || mainRole.IsTasklessCrewmate() && !Options.TasklessCrewCanBeLazy.GetBool() || mainRole.IsTaskBasedCrewmate() && !Options.TaskBasedCrewCanBeLazy.GetBool() => false,
CustomRoles.TicketsStealer or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when mainRole is CustomRoles.Bomber or CustomRoles.Nuker or CustomRoles.BoobyTrap or CustomRoles.Capitalism => false,
CustomRoles.TicketsStealer or CustomRoles.Mimic or CustomRoles.Swift or CustomRoles.DeadlyQuota or CustomRoles.Damocles or CustomRoles.Mare when !mainRole.IsImpostor() => false,
CustomRoles.Torch when !mainRole.IsCrewmate() || mainRole is CustomRoles.Bewilder or CustomRoles.Sunglasses or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Torch or CustomRoles.GuardianAngelTOHE or CustomRoles.Sunglasses => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Torch or CustomRoles.GuardianAngelTOHE or CustomRoles.Bewilder => false,
CustomRoles.Guesser when mainRole.IsCrewmate() && (!Options.CrewCanBeGuesser.GetBool() || mainRole is CustomRoles.NiceGuesser) || mainRole.IsNeutral() && !Options.NeutralCanBeGuesser.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGuesser.GetBool() || mainRole is CustomRoles.EvilGuesser or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Madmate when mainRole is CustomRoles.Egoist or CustomRoles.Rascal => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Detective or CustomRoles.Cleaner or CustomRoles.Medusa or CustomRoles.Mortician or CustomRoles.Mediumshiper or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Youtuber when !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate or CustomRoles.Sheriff or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Egoist when mainRole.IsImpostor() && !Options.ImpCanBeEgoist.GetBool() => false,
CustomRoles.Egoist when mainRole.IsNeutral() || mainRole is CustomRoles.Madmate => false,
CustomRoles.Damocles when mainRole is CustomRoles.Bomber or CustomRoles.Nuker or CustomRoles.SerialKiller or CustomRoles.Cantankerous => false,
CustomRoles.Necroview when mainRole is CustomRoles.Visionary => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Lazy => false,
CustomRoles.Ghoul when mainRole is CustomRoles.Needy => false,
CustomRoles.Lazy when mainRole is CustomRoles.Ghoul => false,
CustomRoles.Mimic when mainRole is CustomRoles.Mafia => false,
CustomRoles.Rascal when !mainRole.IsCrewmate() => false,
CustomRoles.Needy when mainRole.IsAdditionRole() => false,
CustomRoles.TicketsStealer when mainRole is CustomRoles.Vindicator => false,
CustomRoles.Mare when mainRole is CustomRoles.Underdog => false,
CustomRoles.Mare when mainRole is CustomRoles.Inhibitor => false,
CustomRoles.Mare when mainRole is CustomRoles.Saboteur => false,
CustomRoles.Mare when mainRole is CustomRoles.Swift => false,
CustomRoles.Mare when mainRole is CustomRoles.Mafia => false,
CustomRoles.Mare when mainRole is CustomRoles.Sniper => false,
CustomRoles.Mare when mainRole is CustomRoles.FireWorks => false,
CustomRoles.Mare when mainRole is CustomRoles.Swooper => false,
CustomRoles.Mare when mainRole is CustomRoles.Vampire => false,
CustomRoles.Torch when mainRole is CustomRoles.Lighter => false,
CustomRoles.Torch when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Lighter => false,
CustomRoles.Bewilder when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Lighter => false,
CustomRoles.Sunglasses when mainRole is CustomRoles.Ignitor => false,
CustomRoles.Bait when mainRole is CustomRoles.Demolitionist => false,
CustomRoles.Trapper when mainRole is CustomRoles.Demolitionist => false,
CustomRoles.Lovers when mainRole is CustomRoles.Romantic => false,
CustomRoles.Mare when mainRole is CustomRoles.LastImpostor => false,
CustomRoles.Swift when mainRole is CustomRoles.Mare => false,
CustomRoles.DualPersonality when !mainRole.IsImpostor() && !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate => false,
CustomRoles.DualPersonality when mainRole.IsImpostor() && !Options.ImpCanBeDualPersonality.GetBool() => false,
CustomRoles.Loyal when !mainRole.IsImpostor() && !mainRole.IsCrewmate() || mainRole is CustomRoles.Madmate => false,
CustomRoles.Loyal when mainRole.IsImpostor() && !Options.ImpCanBeLoyal.GetBool() => false,
CustomRoles.Seer when mainRole.IsCrewmate() && (!Options.CrewCanBeSeer.GetBool() || mainRole is CustomRoles.Mortician) || mainRole.IsNeutral() && !Options.NeutralCanBeSeer.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeSeer.GetBool() || mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bait when mainRole.IsCrewmate() && !Options.CrewCanBeBait.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeBait.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeBait.GetBool() => false,
CustomRoles.Bewilder when mainRole.IsCrewmate() && !Options.CrewCanBeBewilder.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeBewilder.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeBewilder.GetBool() => false,
CustomRoles.Sunglasses when mainRole.IsCrewmate() && !Options.CrewCanBeSunglasses.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeSunglasses.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeSunglasses.GetBool() => false,
CustomRoles.Autopsy when mainRole.IsCrewmate() && !Options.CrewCanBeAutopsy.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeAutopsy.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeAutopsy.GetBool() => false,
CustomRoles.Glow when mainRole.IsCrewmate() && !Options.CrewCanBeGlow.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeGlow.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGlow.GetBool() => false,
CustomRoles.Trapper when mainRole.IsCrewmate() && !Options.CrewCanBeTrapper.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeTrapper.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeTrapper.GetBool() => false,
CustomRoles.Sidekick when mainRole is CustomRoles.Madmate => false,
CustomRoles.Onbound when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Rascal when mainRole is CustomRoles.SuperStar or CustomRoles.Madmate => false,
CustomRoles.Madmate when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Gravestone when mainRole is CustomRoles.SuperStar => false,
CustomRoles.Sidekick when mainRole.IsNeutral() && !Options.NeutralCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole.IsCrewmate() && !Options.CrewmateCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole.IsImpostor() && !Options.ImpostorCanBeSidekick.GetBool() => false,
CustomRoles.Sidekick when mainRole is CustomRoles.Jackal => false,
CustomRoles.Lucky when mainRole is CustomRoles.Guardian => false,
CustomRoles.Bait when mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bait when mainRole is CustomRoles.Trapper => false,
CustomRoles.Trapper when mainRole is CustomRoles.Bait => false,
CustomRoles.DualPersonality when mainRole is CustomRoles.Dictator => false,
CustomRoles.Swift when mainRole is CustomRoles.Swooper => false,
CustomRoles.Swift when mainRole is CustomRoles.Vampire => false,
CustomRoles.Swift when mainRole is CustomRoles.Scavenger => false,
CustomRoles.Swift when mainRole is CustomRoles.Puppeteer => false,
CustomRoles.Swift when mainRole is CustomRoles.Warlock => false,
CustomRoles.Swift when mainRole is CustomRoles.EvilDiviner => false,
CustomRoles.Swift when mainRole is CustomRoles.Witch => false,
CustomRoles.Swift when mainRole is CustomRoles.Mafia => false,
CustomRoles.Reach when mainRole is CustomRoles.Mafioso => false,
CustomRoles.Trapper when mainRole is CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Watcher when mainRole.IsCrewmate() && !Options.CrewCanBeWatcher.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeWatcher.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeWatcher.GetBool() => false,
CustomRoles.Diseased when mainRole.IsCrewmate() && !Options.CrewCanBeDiseased.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeDiseased.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeDiseased.GetBool() => false,
CustomRoles.Antidote when mainRole.IsCrewmate() && !Options.CrewCanBeAntidote.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeAntidote.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeAntidote.GetBool() => false,
CustomRoles.Diseased when mainRole is CustomRoles.Antidote => false,
CustomRoles.Antidote when mainRole is CustomRoles.Diseased => false,
CustomRoles.Necroview when mainRole.IsCrewmate() && !Options.CrewCanBeNecroview.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeNecroview.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeNecroview.GetBool() => false,
CustomRoles.Oblivious when mainRole.IsCrewmate() && !Options.CrewCanBeOblivious.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeOblivious.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeOblivious.GetBool() => false,
CustomRoles.Brakar when mainRole.IsCrewmate() && !Options.CrewCanBeTiebreaker.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeTiebreaker.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeTiebreaker.GetBool() => false,
CustomRoles.Guesser when mainRole.IsCrewmate() && !Options.CrewCanBeGuesser.GetBool() && mainRole is CustomRoles.NiceGuesser || mainRole.IsNeutral() && !Options.NeutralCanBeGuesser.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGuesser.GetBool() && mainRole is CustomRoles.EvilGuesser => false,
CustomRoles.Onbound when mainRole.IsCrewmate() && !Options.CrewCanBeOnbound.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeOnbound.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeOnbound.GetBool() => false,
CustomRoles.Unreportable when mainRole.IsCrewmate() && !Options.CrewCanBeUnreportable.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeUnreportable.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeUnreportable.GetBool() => false,
CustomRoles.Lucky when mainRole.IsCrewmate() && !Options.CrewCanBeLucky.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeLucky.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeLucky.GetBool() => false,
CustomRoles.Unlucky when mainRole.IsCrewmate() && !Options.CrewCanBeUnlucky.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeUnlucky.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeUnlucky.GetBool() => false,
CustomRoles.Rogue when mainRole.IsCrewmate() && !Options.CrewCanBeRogue.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeRogue.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeRogue.GetBool() => false,
CustomRoles.Gravestone when mainRole.IsCrewmate() && !Options.CrewCanBeGravestone.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeGravestone.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeGravestone.GetBool() => false,
CustomRoles.Flashman when mainRole is CustomRoles.Swooper or CustomRoles.Wraith or CustomRoles.Chameleon or CustomRoles.Alchemist => false,
CustomRoles.Bait when mainRole is CustomRoles.Unreportable => false,
CustomRoles.Nimble when !mainRole.IsCrewmate() => false,
CustomRoles.Physicist when !mainRole.IsCrewmate() => false,
CustomRoles.Unreportable when mainRole is CustomRoles.Bait => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Bloodhound => false,
CustomRoles.Oblivious when mainRole is CustomRoles.Vulture => false,
CustomRoles.Vulture when mainRole is CustomRoles.Oblivious => false,
CustomRoles.Guesser when mainRole is CustomRoles.CopyCat or CustomRoles.Doomsayer => false,
CustomRoles.CopyCat when mainRole is CustomRoles.Guesser => false,
CustomRoles.DoubleShot when mainRole is CustomRoles.CopyCat => false,
CustomRoles.CopyCat when mainRole is CustomRoles.DoubleShot => false,
CustomRoles.Brakar when mainRole is CustomRoles.Dictator => false,
CustomRoles.Lucky when mainRole is CustomRoles.Luckey => false,
CustomRoles.Unlucky when mainRole is CustomRoles.Luckey => false,
CustomRoles.Unlucky when mainRole is CustomRoles.Lucky => false,
CustomRoles.Lucky when mainRole is CustomRoles.Unlucky => false,
CustomRoles.Fool when mainRole.IsCrewmate() && !Options.CrewCanBeFool.GetBool() || mainRole.IsNeutral() && !Options.NeutralCanBeFool.GetBool() || mainRole.IsImpostor() && !Options.ImpCanBeFool.GetBool() || mainRole is CustomRoles.SabotageMaster or CustomRoles.GuardianAngelTOHE => false,
CustomRoles.Bloodhound when mainRole is CustomRoles.Oblivious => false,
CustomRoles.DoubleShot when mainRole.GetCustomRoleTypes() is CustomRoleTypes.Impostor && !Options.ImpCanBeDoubleShot.GetBool() || mainRole.GetCustomRoleTypes() is CustomRoleTypes.Crewmate && !Options.CrewCanBeDoubleShot.GetBool() || mainRole.GetCustomRoleTypes() is CustomRoleTypes.Neutral && !Options.NeutralCanBeDoubleShot.GetBool() => false,
CustomRoles.DoubleShot when mainRole is not CustomRoles.EvilGuesser && mainRole is not CustomRoles.NiceGuesser && !Options.GuesserMode.GetBool() => false,
CustomRoles.DoubleShot when Options.ImpCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && mainRole is not CustomRoles.EvilGuesser && mainRole.GetCustomRoleTypes() is CustomRoleTypes.Impostor && !Options.ImpostorsCanGuess.GetBool() => false,
CustomRoles.DoubleShot when Options.CrewCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && mainRole is not CustomRoles.NiceGuesser && mainRole.GetCustomRoleTypes() is CustomRoleTypes.Crewmate && !Options.CrewmatesCanGuess.GetBool() => false,
CustomRoles.DoubleShot when Options.NeutralCanBeDoubleShot.GetBool() && mainRole is not CustomRoles.Guesser && (mainRole.IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool() || mainRole.IsNK() && !Options.NeutralKillersCanGuess.GetBool()) => false,
_ => true
};
public static bool CheckAddonConflict(CustomRoles role, PlayerControl pc)
{
if (!role.IsAdditionRole()) return false;
@@ -1632,16 +1563,13 @@ internal static class CustomRolesHelper
public static bool IsNeutralKillerTeam(this CustomRoles role) => role.IsNK() && !role.IsMadmate();
public static bool IsPassiveNeutralTeam(this CustomRoles role) => role.IsNonNK() && !role.IsMadmate();
public static bool IsNNK(this CustomRoles role) => role.IsNeutral() && !role.IsNK();
public static bool IsVanilla(this CustomRoles role)
{
return role is
public static bool IsVanilla(this CustomRoles role) => role is
CustomRoles.Crewmate or
CustomRoles.Engineer or
CustomRoles.Scientist or
CustomRoles.GuardianAngel or
CustomRoles.Impostor or
CustomRoles.Shapeshifter;
}
public static CustomRoleTypes GetCustomRoleTypes(this CustomRoles role)
{
CustomRoleTypes type = CustomRoleTypes.Crewmate;
+2
View File
@@ -72,6 +72,8 @@ public static class DevManager
DevUserList.Add(new(code: "swiftlord#0872", color: "null", tag: "null", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "But What About"));
DevUserList.Add(new(code: "ovalinstep#2984", color: "null", tag: "null", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "Seleneous"));
DevUserList.Add(new(code: "innerruler#4140", color: "null", tag: "null", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "thewhiskas27"));
DevUserList.Add(new(code: "urbanecalf#4975", color: "#420773", tag: "Streamer", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "Gugutsik"));
DevUserList.Add(new(code: "crustzonal#9589", color: "null", tag: "null", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "aviiiv0102"));
// Sponsor
DevUserList.Add(new(code: "recentduct#6068", color: "#FF00FF", tag: "高冷男模法师", isUp: false, isDev: false, colorCmd: false, deBug: true, upName: null));
+48 -44
View File
@@ -69,7 +69,6 @@ internal class EAC
break;
case RpcCalls.SendChat:
var text = sr.ReadString();
if (text.StartsWith("/")) return false;
if (
text.Contains('░') ||
text.Contains('▄') ||
@@ -85,7 +84,7 @@ internal class EAC
}
break;
case RpcCalls.StartMeeting:
//Client will never send StartMeeting rpc
// Non-Host Clients will never send StartMeeting RPC
WarnHost();
Report(pc, "Bad StartMeeting");
HandleCheat(pc, "Bad StartMeeting");
@@ -133,6 +132,13 @@ internal class EAC
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the color and has been rejected", "EAC");
return true;
}
if (pc.AmOwner)
{
WarnHost();
Report(pc, "Illegal setting of host color");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the host's color, which has been rejected", "EAC");
return true;
}
break;
case RpcCalls.CheckMurder:
if (GameStates.IsLobby)
@@ -145,28 +151,29 @@ internal class EAC
}
break;
case RpcCalls.MurderPlayer:
//If using version protocol, client should never directly send Murder player rpc
// Calls will only be sent by server / host
Report(pc, "Directly Murder Player");
HandleCheat(pc, "Directly Murder Player");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] killed directly, rejected", "EAC");
return true;
case RpcCalls.Shapeshift:
case RpcCalls.CheckShapeshift:
if (GameStates.IsLobby)
{
Report(pc, "ShapeShift in lobby");
HandleCheat(pc, "ShapeShift in lobby");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] lobby is deformed and has been rejected", "EAC");
return true;
}
var target = sr.ReadNetObject<PlayerControl>();
if (target == null)
{
Report(pc, "ShapeShift to null player!");
//HandleCheat(pc, "ShapeShift to null player!");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally transformed into an empty player and has been rejected", "EAC");
Report(pc, "Lobby CheckShapeshift");
HandleCheat(pc, "Lobby CheckShapeshift");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] directly shapeshifted and has been rejected", "EAC");
return true;
}
break;
case RpcCalls.Shapeshift:
Report(pc, "Directly Shapeshift");
var swriter = AmongUsClient.Instance.StartRpcImmediately(pc.NetId, (byte)RpcCalls.Shapeshift, SendOption.Reliable, -1);
swriter.WriteNetObject(pc);
swriter.Write(false);
AmongUsClient.Instance.FinishRpcImmediately(swriter);
HandleCheat(pc, "Directly Shapeshift");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] directly shapeshifted and has been rejected", "EAC");
return true;
}
switch (callId)
{
@@ -177,6 +184,7 @@ internal class EAC
HandleCheat(pc, GetString("EAC.CheatDetected.EAC"));
return true;
case 7:
case 8:
if (!GameStates.IsLobby)
{
WarnHost();
@@ -204,49 +212,45 @@ internal class EAC
return true;
}
break;
case 41:
case 38:
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "Illegal pet setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set a pet and has been rejected", "EAC");
Report(pc, "Set level in game");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] changed the level in the game and it has been rejected", "EAC");
return true;
}
break;
case 40:
if (GameStates.IsInGame)
if (sr.ReadPackedUInt32() > 0)
{
WarnHost();
Report(pc, "Illegal skin setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the skin and has been rejected", "EAC");
return true;
}
break;
case 42:
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "Illegal facial decoration");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set facial decoration and has been rejected", "EAC");
return true;
uint ClientDataLevel = pc.GetClient() == null ? pc.GetClient().PlayerLevel : 0;
uint PlayerControlLevel = sr.ReadPackedUInt32();
if (ClientDataLevel != 0 && Math.Abs(PlayerControlLevel - ClientDataLevel) > 4)
{
WarnHost();
Report(pc, "Sus Level Change");
AmongUsClient.Instance.KickPlayer(pc.GetClientId(), false);
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] changed the level in the game and it has been rejected", "EAC");
return true;
}
}
break;
case 39:
case 40:
case 41:
case 42:
case 43:
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "Illegal hat setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set a hat and has been rejected", "EAC");
Report(pc, "Change skin in game");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] changed the skin in the game and it has been rejected", "EAC");
return true;
}
break;
case 43:
if (sr.BytesRemaining > 0 && sr.ReadBoolean()) return false;
if (GameStates.IsInGame)
if (pc.AmOwner)
{
WarnHost();
Report(pc, "Illegal setting of game name");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the name and has been rejected", "EAC");
Report(pc, "Change Host skin");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] changed the owner's skin and it has been rejected", "EAC");
return true;
}
break;
@@ -280,7 +284,7 @@ internal class EAC
//Update system rpc can not get received by playercontrol.handlerpc
var Mapid = Main.NormalOptions.MapId;
Logger.Info("Check sabotage RPC" + ", PlayerName: " + player.GetNameWithRole() + ", SabotageType: " + systemType.ToString() + ", amount: " + amount.ToString(), "EAC");
if (player.AmOwner || !AmongUsClient.Instance.AmHost) return false;
if (!AmongUsClient.Instance.AmHost) return false;
switch (systemType) //Normal sabotage using buttons
{
case SystemTypes.Sabotage:
@@ -402,7 +406,7 @@ internal class EAC
string msg = $"{pc.GetClientId()}|{pc.FriendCode}|{pc.Data.PlayerName}|{pc.GetClient().GetHashedPuid()}|{reason}";
//Cloud.SendData(msg);
Logger.Fatal($"EAC report: {msg}", "EAC Cloud");
Logger.SendInGame(string.Format(GetString("Message.NoticeByEAC"), $"{pc?.Data?.PlayerName} | {pc.GetClient().GetHashedPuid()}", reason));
if (Options.CheatResponses.GetInt() != 5) Logger.SendInGame(string.Format(GetString("Message.NoticeByEAC"), $"{pc?.Data?.PlayerName} | {pc.GetClient().GetHashedPuid()}", reason));
}
public static bool ReceiveInvalidRpc(PlayerControl pc, byte callId)
{
+14 -7
View File
@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using TOHE.Modules;
using TOHE.Roles.AddOns.Crewmate;
using TOHE.Roles.AddOns.Impostor;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Impostor;
@@ -1381,17 +1382,17 @@ static class ExtendedPlayerControl
return (pos, roomName);
}
public static void TP(this PlayerControl pc, PlayerControl target)
public static bool TP(this PlayerControl pc, PlayerControl target)
{
Utils.TP(pc.NetTransform, target.Pos());
return Utils.TP(pc.NetTransform, target.Pos());
}
public static void TP(this PlayerControl pc, Vector2 location)
public static bool TP(this PlayerControl pc, Vector2 location)
{
Utils.TP(pc.NetTransform, location);
return Utils.TP(pc.NetTransform, location);
}
public static void TPtoRndVent(this PlayerControl pc)
public static bool TPtoRndVent(this PlayerControl pc)
{
Utils.TPtoRndVent(pc.NetTransform);
return Utils.TPtoRndVent(pc.NetTransform);
}
public static void Kill(this PlayerControl killer, PlayerControl target)
{
@@ -1399,6 +1400,12 @@ static class ExtendedPlayerControl
if (Options.CurrentGameMode == CustomGameMode.SoloKombat) return;
if (target.GetTeam() is Team.Impostor or Team.Neutral) Stressed.OnNonCrewmateDead();
if (killer.Is(CustomRoles.Damocles)) Damocles.OnMurder();
else if (killer.Is(Team.Impostor)) Damocles.OnOtherImpostorMurder();
if (target.Is(Team.Impostor)) Damocles.OnImpostorDeath();
if (killer.PlayerId == target.PlayerId && killer.shapeshifting)
{
_ = new LateTask(() => { killer.RpcMurderPlayerV2(target); }, 1.5f, "Shapeshifting Suicide Delay");
@@ -1437,7 +1444,7 @@ static class ExtendedPlayerControl
}
target.Data.IsDead = true;
NotifyRoles(SpecifySeer: killer);
NotifyRoles(SpecifySeer: killer, SpecifyTarget: target);
NotifyRoles(SpecifySeer: target);
}
public static bool RpcCheckAndMurder(this PlayerControl killer, PlayerControl target, bool check = false) => CheckMurderPatch.RpcCheckAndMurder(killer, target, check);
+2 -1
View File
@@ -118,7 +118,8 @@ public static class Options
"Ban",
"Kick",
"NoticeMe",
"NoticeEveryone"
"NoticeEveryone",
"OnlyCancel"
];
public static readonly string[] ConfirmEjectionsMode =
[
+2 -8
View File
@@ -6,14 +6,8 @@ public class StringOptionItem(int id, string name, int defaultValue, TabGroup ta
public IntegerValueRule Rule = (0, selections.Length - 1, 1);
public string[] Selections = selections;
public static StringOptionItem Create(
int id, string name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue
)
{
return new StringOptionItem(
id, name, defaultIndex, tab, isSingleValue, selections
);
}
public static StringOptionItem Create(int id, string name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue)
=> new(id, name, defaultIndex, tab, isSingleValue, selections);
// Getter
public override int GetInt() => Rule.GetValueByIndex(CurrentValue);
+8
View File
@@ -58,6 +58,8 @@ enum CustomRPC
//Roles
SetDrawPlayer,
SyncMycologist,
SyncBubble,
AddTornado,
RemoveTornado,
SyncSprayer,
@@ -585,6 +587,12 @@ internal class RPCHandlerPatch
case CustomRPC.SendFireWorksState:
FireWorks.ReceiveRPC(reader);
break;
case CustomRPC.SyncMycologist:
Mycologist.ReceiveRPC(reader);
break;
case CustomRPC.SyncBubble:
Bubble.ReceiveRPC(reader);
break;
case CustomRPC.SetCurrentDousingTarget:
byte arsonistId = reader.ReadByte();
byte dousingTargetId = reader.ReadByte();
+6 -5
View File
@@ -79,13 +79,13 @@ public static class Utils
}
}
public static void TP(CustomNetworkTransform nt, Vector2 location)
public static bool TP(CustomNetworkTransform nt, Vector2 location)
{
var pc = nt.myPlayer;
if (pc.inVent || pc.inMovingPlat || !pc.IsAlive())
if (pc.inVent || pc.inMovingPlat || !pc.IsAlive() || pc.MyPhysics.Animations.IsPlayingAnyLadderAnimation() || pc.MyPhysics.Animations.IsPlayingEnterVentAnimation())
{
Logger.Warn($"Target ({pc.GetNameWithRole().RemoveHtmlTags()}) is in an un-teleportable state - Teleporting canceled", "TP");
return;
return false;
}
// Modded
@@ -98,15 +98,16 @@ public static class Utils
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
Logger.Info($"{pc.GetNameWithRole().RemoveHtmlTags()} => {location}", "TP");
return true;
}
public static void TPtoRndVent(CustomNetworkTransform nt)
public static bool TPtoRndVent(CustomNetworkTransform nt)
{
var vents = UnityEngine.Object.FindObjectsOfType<Vent>();
var vent = vents[IRandom.Instance.Next(0, vents.Count)];
Logger.Info($"{nt.myPlayer.GetNameWithRole().RemoveHtmlTags()} => {vent.transform.position} (vent)", "TP");
TP(nt, new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f));
return TP(nt, new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f));
}
public static ClientData GetClientById(int id)
{
+36 -29
View File
@@ -29,6 +29,7 @@ internal class ChatCommands
}
public static List<string> ChatHistory = [];
public static Dictionary<byte, long> LastSentCommand = [];
public static bool Prefix(ChatController __instance)
{
@@ -75,7 +76,7 @@ internal class ChatCommands
switch (args[0])
{
case "/dump":
canceled = true;
//canceled = true;
Utils.DumpLog();
break;
case "/v":
@@ -430,11 +431,11 @@ internal class ChatCommands
Utils.SendMessage(string.Format(GetString("Message.SetColor"), subArgs), localPlayerId);
break;
case "/quit":
case "/qt":
canceled = true;
Utils.SendMessage(GetString("Message.CanNotUseByHost"), localPlayerId);
break;
//case "/quit":
//case "/qt":
// canceled = true;
// Utils.SendMessage(GetString("Message.CanNotUseByHost"), localPlayerId);
// break;
case "/xf":
canceled = true;
@@ -840,6 +841,8 @@ internal class ChatCommands
{
canceled = false;
if (!AmongUsClient.Instance.AmHost) return;
long now = Utils.GetTimeStamp();
if (LastSentCommand.TryGetValue(player.PlayerId, out var ts) && ts + 2 >= now) { Logger.Warn("Command Ignored, it was sent too soon after their last command", "ReceiveChat"); return; }
if (player.PlayerId != 0) ChatManager.SendMessage(player, text);
if (text.StartsWith("\n")) text = text[1..];
//if (!text.StartsWith("/")) return;
@@ -847,22 +850,24 @@ internal class ChatCommands
string subArgs = string.Empty;
//if (text.Length >= 3) if (text[..2] == "/r" && text[..3] != "/rn") args[0] = "/r";
// if (SpamManager.CheckSpam(player, text)) return;
if (GuessManager.GuesserMsg(player, text)) { canceled = true; return; }
if (Judge.TrialMsg(player, text)) { canceled = true; return; }
if (NiceSwapper.SwapMsg(player, text)) { canceled = true; return; }
if (ParityCop.ParityCheckMsg(player, text)) { canceled = true; return; }
if (GuessManager.GuesserMsg(player, text)) { canceled = true; LastSentCommand[player.PlayerId] = now; return; }
if (Judge.TrialMsg(player, text)) { canceled = true; LastSentCommand[player.PlayerId] = now; return; }
if (NiceSwapper.SwapMsg(player, text)) { canceled = true; LastSentCommand[player.PlayerId] = now; return; }
if (ParityCop.ParityCheckMsg(player, text)) { canceled = true; LastSentCommand[player.PlayerId] = now; return; }
//if (Pirate.DuelCheckMsg(player, text)) { canceled = true; return; }
if (Councillor.MurderMsg(player, text)) { canceled = true; return; }
if (Mediumshiper.MsMsg(player, text)) return;
if (MafiaRevengeManager.MafiaMsgCheck(player, text)) return;
if (Councillor.MurderMsg(player, text)) { canceled = true; LastSentCommand[player.PlayerId] = now; return; }
if (Mediumshiper.MsMsg(player, text)) { LastSentCommand[player.PlayerId] = now; return; }
if (MafiaRevengeManager.MafiaMsgCheck(player, text)) { LastSentCommand[player.PlayerId] = now; return; }
//if (RetributionistRevengeManager.RetributionistMsgCheck(player, text)) return;
if (Blackmailer.ForBlackmailer.Contains(player.PlayerId) && player.IsAlive() && player.PlayerId != 0)
{
ChatManager.SendPreviousMessagesToAll();
ChatManager.cancel = false;
canceled = true;
LastSentCommand[player.PlayerId] = now;
return;
}
bool isCommand = true;
switch (args[0])
{
case "/l":
@@ -967,22 +972,22 @@ internal class ChatCommands
}
break;
case "/quit":
case "/qt":
subArgs = args.Length < 2 ? string.Empty : args[1];
var cid = player.PlayerId.ToString();
cid = cid.Length != 1 ? cid.Substring(1, 1) : cid;
if (subArgs.Equals(cid))
{
string name = player.GetRealName();
Utils.SendMessage(string.Format(GetString("Message.PlayerQuitForever"), name));
AmongUsClient.Instance.KickPlayer(player.GetClientId(), true);
}
else
{
Utils.SendMessage(string.Format(GetString("SureUse.quit"), cid), player.PlayerId);
}
break;
//case "/quit":
//case "/qt":
// subArgs = args.Length < 2 ? string.Empty : args[1];
// var cid = player.PlayerId.ToString();
// cid = cid.Length != 1 ? cid.Substring(1, 1) : cid;
// if (subArgs.Equals(cid))
// {
// string name = player.GetRealName();
// Utils.SendMessage(string.Format(GetString("Message.PlayerQuitForever"), name));
// AmongUsClient.Instance.KickPlayer(player.GetClientId(), true);
// }
// else
// {
// Utils.SendMessage(string.Format(GetString("SureUse.quit"), cid), player.PlayerId);
// }
// break;
case "/id":
if (Options.ApplyModeratorList.GetValue() == 0 || !IsPlayerModerator(player.FriendCode)) break;
@@ -1133,8 +1138,10 @@ internal class ChatCommands
}
default:
isCommand = false;
break;
}
if (isCommand) LastSentCommand[player.PlayerId] = now;
if (SpamManager.CheckSpam(player, text)) return;
}
}
+7 -6
View File
@@ -447,17 +447,18 @@ class GameEndChecker
foreach (PlayerControl x in Main.AllAlivePlayerControls)
{
if (x.GetCustomRole().IsImpostor() && x.Is(CustomRoles.DualPersonality)) Imp++;
if (x.GetCustomRole().IsCrewmate() && x.Is(CustomRoles.DualPersonality)) Crew++;
if (x.GetCustomRole().IsImpostor() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
if (x.GetCustomRole().IsNeutral() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
if (x.GetCustomRole().IsCrewmate() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
CustomRoles role = x.GetCustomRole();
if ((x.Is(CustomRoles.Madmate) && x.Is(CustomRoles.DualPersonality)) ||
(role.IsImpostor() && x.Is(CustomRoles.DualPersonality))) Imp++;
if (role.IsCrewmate() && x.Is(CustomRoles.DualPersonality)) Crew++;
if (role.IsImpostor() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
if (role.IsNeutral() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
if (role.IsCrewmate() && x.Is(CustomRoles.Admired) && x.Is(CustomRoles.DualPersonality)) Crew++;
if (x.Is(CustomRoles.Charmed) && x.Is(CustomRoles.DualPersonality)) roleCounts[(null, CustomWinner.Succubus)]++;
if (x.Is(CustomRoles.Sidekick) && x.Is(CustomRoles.DualPersonality)) roleCounts[(null, CustomWinner.Jackal)]++;
if (x.Is(CustomRoles.Recruit) && x.Is(CustomRoles.DualPersonality)) roleCounts[(null, CustomWinner.Jackal)]++;
if (x.Is(CustomRoles.Infected) && x.Is(CustomRoles.DualPersonality)) roleCounts[(null, CustomWinner.Infectious)]++;
if (x.Is(CustomRoles.Contagious) && x.Is(CustomRoles.DualPersonality)) roleCounts[(null, CustomWinner.Virus)]++;
if (x.Is(CustomRoles.Madmate) && x.Is(CustomRoles.DualPersonality)) Imp++;
}
int totalNKAlive = roleCounts.Values.Sum();
+3
View File
@@ -263,6 +263,9 @@ public class StringOptionEnablePatch
__instance.OnValueChanged = new Action<OptionBehaviour>((o) => { });
__instance.TitleText.text = option.GetName();
if (option.Id == Options.UsePets.Id) LoadLangs();
else if (!Options.UsePets.GetBool() && CustomRolesHelper.OnlySpawnsWithPetsRoleList.Any(role => role.ToString().Equals(option.GetName().RemoveHtmlTags())))
__instance.TitleText.text += GetString("RequiresPetIndicator");
__instance.Value = __instance.oldValue = option.CurrentValue;
__instance.ValueText.text = option.GetString();
+16 -1
View File
@@ -591,9 +591,18 @@ class HudManagerPatch
__instance.KillButton?.ToggleVisible(false);
}
bool CanUseVent = player.CanUseImpostorVentButton() && GameStates.IsInTask;
bool CanUseVent = (player.CanUseImpostorVentButton() || player.inVent || player.MyPhysics.Animations.IsPlayingEnterVentAnimation()) && GameStates.IsInTask;
__instance.ImpostorVentButton?.ToggleVisible(CanUseVent);
player.Data.Role.CanVent = CanUseVent;
if (player.PlayerId == 0 && player.inVent && GameStates.IsInTask)
{
__instance.ImpostorVentButton.canInteract = true;
__instance.ImpostorVentButton.enabled = true;
__instance.ImpostorVentButton.isCoolingDown = false;
__instance.ImpostorVentButton.SetEnabled();
__instance.ImpostorVentButton.currentTarget = TryMoveToVentPatch.HostVentTarget;
__instance.ImpostorVentButton.SetTarget(TryMoveToVentPatch.HostVentTarget);
}
}
else
{
@@ -773,6 +782,12 @@ class VentButtonDoClickPatch
{
var pc = PlayerControl.LocalPlayer;
{
if (pc.inVent)
{
pc.MyPhysics.RpcExitVent(TryMoveToVentPatch.HostVentTarget.Id);
TryMoveToVentPatch.HostVentTarget.SetButtons(false);
return true;
}
if (!pc.Is(CustomRoles.Swooper) || !pc.Is(CustomRoles.Wraith) || !pc.Is(CustomRoles.Chameleon) || pc.inVent || __instance.currentTarget == null || !pc.CanMove || !__instance.isActiveAndEnabled) return true;
pc?.MyPhysics?.RpcEnterVent(__instance.currentTarget.Id);
return false;
+13 -12
View File
@@ -113,6 +113,7 @@ class SetEverythingUpPatch
try
{
// ---------- Code from TOR (The Other Roles)! ----------
if (Options.CurrentGameMode is not CustomGameMode.Standard) goto End;
int num = Mathf.CeilToInt(7.5f);
List<WinningPlayerData> winningPlayerDataList = TempData.winners.ToArray().ToList();
@@ -144,19 +145,20 @@ class SetEverythingUpPatch
poolablePlayer.cosmetics.nameText.color = Color.white;
poolablePlayer.cosmetics.nameText.transform.localScale = new Vector3(1f / vector.x, 1f / vector.y, 1f / vector.z);
poolablePlayer.cosmetics.nameText.transform.localPosition = new Vector3(poolablePlayer.cosmetics.nameText.transform.localPosition.x, !lowered ? poolablePlayer.cosmetics.nameText.transform.localPosition.y - 0.6f : poolablePlayer.cosmetics.nameText.transform.localPosition.y - 1.4f, -15f);
poolablePlayer.cosmetics.nameText.text = winningPlayerData2.PlayerName;
Vector3 defaultPos = poolablePlayer.cosmetics.nameText.transform.localPosition;
for (int i1 = 0; i1 < Main.winnerList.Count; i1++)
{
byte id = Main.winnerList[i1];
if (Main.winnerNameList[i1].RemoveHtmlTags() != winningPlayerData2?.PlayerName.RemoveHtmlTags()) continue;
var color = Main.roleColors[Main.winnerRolesList[i1]];
var rolename = Utils.GetRoleName(Main.PlayerStates[id].MainRole);
var role = Main.PlayerStates[id].MainRole;
var color = Main.roleColors[role];
var rolename = Utils.GetRoleName(role);
poolablePlayer.cosmetics.nameText.text += $"\n<color={color}>{rolename}</color>";
poolablePlayer.cosmetics.nameText.transform.localPosition = new Vector3(defaultPos.x, !lowered || role.IsImpostor() || role.IsNK() ? defaultPos.y - 0.6f : defaultPos.y - 1.4f, -15f);
}
poolablePlayer.cosmetics.nameText.text += $"<size=0>";
}
}
catch (Exception e)
@@ -316,21 +318,21 @@ class SetEverythingUpPatch
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#######################################
// ==最終結果表示==
//#######################################
//########################################
// ==The final result indicates==
//########################################
var Pos = Camera.main.ViewportToWorldPoint(new Vector3(0f, 1f, Camera.main.nearClipPlane));
var RoleSummaryObject = UnityEngine.Object.Instantiate(__instance.WinText.gameObject);
RoleSummaryObject.transform.position = new Vector3(__instance.Navigation.ExitButton.transform.position.x + 0.1f, Pos.y - 0.1f, -15f);
RoleSummaryObject.transform.localScale = new Vector3(1f, 1f, 1f);
StringBuilder sb = new($"{GetString("RoleSummaryText")}\n");
StringBuilder sb = new($"{GetString("RoleSummaryText")}\n<b>");
List<byte> cloneRoles = new(Main.PlayerStates.Keys);
foreach (byte id in Main.winnerList.ToArray())
{
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append($"\n<b>").Append(EndGamePatch.SummaryText[id]);
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
cloneRoles.Remove(id);
}
switch (Options.CurrentGameMode)
@@ -379,8 +381,7 @@ class SetEverythingUpPatch
sb.Append($"</b>\n");
foreach (byte id in cloneRoles.ToArray())
{
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>"))
continue;
if (EndGamePatch.SummaryText[id].Contains("<INVALID:NotAssigned>")) continue;
sb.Append('\n').Append(EndGamePatch.SummaryText[id]);
}
+25 -6
View File
@@ -1238,12 +1238,6 @@ class MurderPlayerPatch
break;
}
if (target.GetTeam() is Team.Impostor or Team.Neutral) Stressed.OnNonCrewmateDead();
if (killer.Is(CustomRoles.Damocles)) Damocles.OnMurder();
else if (killer.Is(Team.Impostor)) Damocles.OnOtherImpostorMurder();
if (target.Is(Team.Impostor)) Damocles.OnImpostorDeath();
if (killer.Is(CustomRoles.TicketsStealer) && killer.PlayerId != target.PlayerId)
killer.Notify(string.Format(GetString("TicketsStealerGetTicket"), ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * Options.TicketsPerKill.GetFloat()).ToString("0.0#####")));
@@ -3123,6 +3117,19 @@ class SetColorPatch
}
}
[HarmonyPatch(typeof(Vent), nameof(Vent.TryMoveToVent))]
class TryMoveToVentPatch
{
public static Vent HostVentTarget;
public static void Postfix(Vent __instance, [HarmonyArgument(0)] Vent otherVent, bool __result)
{
if (__result && AmongUsClient.Instance.AmHost && PlayerControl.LocalPlayer.PlayerId == 0 && PlayerControl.LocalPlayer.inVent && (HostVentTarget.Equals(__instance) || HostVentTarget == __instance))
{
Logger.Info($"(Move) {__instance.name} => {otherVent.name}", "HostVentTarget");
HostVentTarget = otherVent;
}
}
}
[HarmonyPatch(typeof(Vent), nameof(Vent.ExitVent))]
class ExitVentPatch
{
@@ -3130,6 +3137,12 @@ class ExitVentPatch
{
Logger.Info($" {pc.GetNameWithRole()}, Vent ID: {__instance.Id} ({__instance.name})", "ExitVent");
if (pc.PlayerId == 0)
{
Logger.Info("(Exit) " + __instance.name, "HostVentTarget");
TryMoveToVentPatch.HostVentTarget = __instance;
}
Drainer.OnAnyoneExitVent(pc, __instance.Id);
}
}
@@ -3140,6 +3153,12 @@ class EnterVentPatch
{
Logger.Info($" {pc.GetNameWithRole()}, Vent ID: {__instance.Id} ({__instance.name})", "EnterVent");
if (pc.PlayerId == 0)
{
Logger.Info("(Enter) " + __instance.name, "HostVentTarget");
TryMoveToVentPatch.HostVentTarget = __instance;
}
Drainer.OnAnyoneEnterVent(pc, __instance);
Analyzer.OnAnyoneEnterVent(pc);
+40 -28
View File
@@ -74,9 +74,11 @@ class RepairSystemPatch
{
case CustomRoles.SabotageMaster:
SabotageMaster.RepairSystem(__instance, systemType, amount);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
break;
case CustomRoles.Alchemist when Alchemist.FixNextSabo:
Alchemist.RepairSystem(systemType, amount);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
break;
}
@@ -118,6 +120,9 @@ class RepairSystemPatch
case CustomRoles.Enderman:
Enderman.MarkPosition();
return false;
case CustomRoles.Hookshot:
Hookshot.ExecuteAction();
return false;
case CustomRoles.Mycologist when Mycologist.SpreadAction.GetValue() == 1 || (Mycologist.SpreadAction.GetValue() == 2 && !Options.UsePets.GetBool()):
Mycologist.SpreadSpores();
return false;
@@ -160,37 +165,44 @@ class RepairSystemPatch
{
Camouflage.CheckCamouflage();
if (systemType == SystemTypes.Electrical && 0 <= amount && amount <= 4)
switch (systemType)
{
var SwitchSystem = ShipStatus.Instance?.Systems?[SystemTypes.Electrical]?.Cast<SwitchSystem>();
if (SwitchSystem != null && SwitchSystem.IsActive)
{
switch (player.GetCustomRole())
case SystemTypes.Electrical when 0 <= amount && amount <= 4:
{
case CustomRoles.SabotageMaster:
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()} instant-fix-lights", "SwitchSystem");
SabotageMaster.SwitchSystemRepair(SwitchSystem, amount);
break;
case CustomRoles.Alchemist when Alchemist.FixNextSabo:
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()} instant-fix-lights", "SwitchSystem");
SwitchSystem.ActualSwitches = 0;
SwitchSystem.ExpectedSwitches = 0;
Alchemist.FixNextSabo = false;
break;
}
}
}
var SwitchSystem = ShipStatus.Instance?.Systems?[SystemTypes.Electrical]?.Cast<SwitchSystem>();
if (SwitchSystem != null && SwitchSystem.IsActive)
{
switch (player.GetCustomRole())
{
case CustomRoles.SabotageMaster:
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()} instant-fix-lights", "SwitchSystem");
SabotageMaster.SwitchSystemRepair(SwitchSystem, amount);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
break;
case CustomRoles.Alchemist when Alchemist.FixNextSabo:
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()} instant-fix-lights", "SwitchSystem");
SwitchSystem.ActualSwitches = 0;
SwitchSystem.ExpectedSwitches = 0;
Alchemist.FixNextSabo = false;
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
break;
}
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage();
if (player.Is(CustomRoles.Stressed) && Stressed.countRepairSabotage) Stressed.OnRepairSabotage(player);
}
if (systemType is
SystemTypes.Reactor or
SystemTypes.LifeSupp or
SystemTypes.Comms or
SystemTypes.Laboratory or
SystemTypes.HeliSabotage or
SystemTypes.Electrical)
{
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage();
if (player.Is(CustomRoles.Stressed) && Stressed.countRepairSabotage) Stressed.OnRepairSabotage(player);
break;
}
case SystemTypes.Reactor:
case SystemTypes.LifeSupp:
case SystemTypes.Comms:
case SystemTypes.Laboratory:
case SystemTypes.HeliSabotage:
case SystemTypes.Electrical:
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage();
if (player.Is(CustomRoles.Stressed) && Stressed.countRepairSabotage) Stressed.OnRepairSabotage(player);
break;
}
}
public static void CheckAndOpenDoorsRange(ShipStatus __instance, int amount, int min, int max)
File diff suppressed because it is too large. Load diff
+7 -1
View File
@@ -1158,7 +1158,7 @@
"DisableReportWhenCC","小黑人时禁止报告尸体","Disable body reporting while camouflaged","Запретить репортить трупы при Камуфляже","小灰人時禁止報告屍體","小黑人时禁止报告尸体"
"EnableDebugMode","开启调试模式","Enable Debug Mode","Включить режим отладки","開啟偵錯模式","开启调试模式"
"ChangeNameToRoleInfo","刚开局用玩家名字显示职业简介","Show Role Info to Unmodded Clients Round 1","Показать краткую информацию о роли для игроков без мода","開始遊戲時用玩家名字顯示職業簡介","刚开局用玩家名字显示职业简介"
"SendRoleDescriptionFirstMeeting","首次会议自动向非模组玩家发送职业介绍","Show Role Descriptions to Unmodded Clients at First Meeting","Показать полное описание роли для игроков без мода на первой встрече","首次會議自動向非模組玩家傳送職業介紹","首次会议自动向非模组玩家发送职业介绍"
"SendRoleDescriptionFirstMeeting","首次会议自动向非模组玩家发送职业介绍","Show Role Descriptions to Unmodded Clients on First Meeting","Показать полное описание роли для игроков без мода на первой встрече","首次會議自動向非模組玩家傳送職業介紹","首次会议自动向非模组玩家发送职业介绍"
"RoleAssigningAlgorithm","职业分配算法","Role Assigning Algorithm","Алгоритм назначения Ролей","職業分配算法","职业分配算法"
"RoleAssigningAlgorithm.Default","默认","Default","По Умолчанию","預設","默认"
"RoleAssigningAlgorithm.NetRandom",".NET系统",".NET System.Random","Случайный",".NET系統",".NET系统"
@@ -1198,6 +1198,7 @@
"Kick","踢出","Kick","Кикнуть","踢出","踢出"
"NoticeMe","通知我","Notify me","Уведомить меня","通知我","通知我"
"NoticeEveryone","通知所有人(除了它)","Notify everyone","Уведомить всех","通知所有人(除了他)","通知所有人(除了它)"
"OnlyCancel","","Cancel Action Only","","",""
"CheatResponses","检测到外挂时","When a cheating player is found","Когда обнаружен взлом","檢測到外掛時","检测到外挂时"
"NeutralRoleWinTogether","同种职业<color=#7f8c8d>中立</color>玩家共同胜利","<color=#7f8c8d>Neutrals</color> win together","<color=#7f8c8d>Нейтралы</color> побеждают вместе","同種職業的<color=#7f8c8d>中立</color>玩家共同獲勝","同种职业<color=#7f8c8d>中立</color>玩家共同胜利"
"NeutralWinTogether","全体<color=#7f8c8d>中立</color>阵营玩家共同胜利","All <color=#7f8c8d>Neutrals</color> win together","<color=#7f8c8d>Нейтралы</color> побеждают вместе","全體<color=#7f8c8d>中立</color>陣營玩家共同獲勝","全体<color=#7f8c8d>中立</color>阵营玩家共同胜利"
@@ -1450,6 +1451,7 @@
"NotifyGodAlive","如果神存活则在会议上通知所有人","Inform players at meetings that God is still alive","Сообщать игрокам на встрече что Дьявол ещё жив","若神存活則在會議上通知所有人","如果神存活则在会议上通知所有人"
"TransporterTeleportMax","传送次数上限","Max number of teleports","Максимальное колличество телепортов","傳送次數上限","传送次数上限"
"TriggerKill","击杀","Kill","Убийство","殺死","击杀"
"RequiresPetIndicator",""," <#ff0000>PET</color>","","",""
"UsePetInsteadOfKillButton","","Use Pet Button As Kill Button","","",""
"UsePets","","Use Pet button instead of Vent / Shapeshift","","",""
"PetToAssign","","Pet to Assign to Everyone","","",""
@@ -2321,6 +2323,7 @@
"ReportButtonText","报告","Report","РЕПОРТ","",""
"VentButtonText","通风管","Vent","ВЕНТАНУТЬСЯ","",""
"SabotageButtonText","破坏","Sabotage","САБОТАЖ","",""
"GauloisKillButtonText","","Speed Up","","",""
"SniperSnipeButtonText","狙击","Snipe","ЗАСТРЕЛИТЬ","狙擊","狙击"
"FireWorksExplosionButtonText","引爆","Detonate","ЗАЖЕЧЬ","引爆","引爆"
"FireWorksInstallAtionButtonText","设置","Install","УСТАНОВИТЬ","安裝","设置"
@@ -2911,6 +2914,7 @@
"MycologistInfoLong","","(Neutral):\nAs the Mycologist, you can infect players around you by entering a vent/sabotaging/petting your pet. You can only kill the ones you've infected.","","",""
"MycologistAction","","Action To Infect","","",""
"InfectRadius","","Infect Radius","","",""
"InfectDelay","","Infect Delay","","",""
"MycologistNotify","","Spores spread successfully","","",""
"## Bubble"
@@ -3076,6 +3080,8 @@
"GamblerInfo","","Each Kill gets you an Effect","","",""
"GamblerInfoLong","","(Impostors):\nAs the Gambler, a random event happens after each kill you get. These effects can be anywhere between a self-report and an extra sniper shot.","","",""
"GamblerKillDelay","","Delayed Kills are delayed by","","",""
"GamblerBSRDelay","","Self-Report Delay","","",""
"GamblerTPDelay","","Swap Delay","","",""
"GamblerShieldDur","","Shield Duration","","",""
"GamblerFreezeDur","","Freeze Duration","","",""
"GamblerLowVision","","Lower Vision","","",""
Can't render this file because it is too large.
+1 -1
View File
@@ -29,7 +29,7 @@ public static class Judge
public static void SetupCustomOption()
{
Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Judge);
TrialLimitPerMeeting = IntegerOptionItem.Create(Id + 10, "TrialLimitPerMeeting", new(1, 10, 1), 1, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge])
TrialLimitPerMeeting = IntegerOptionItem.Create(Id + 10, "TrialLimitPerMeeting", new(1, 15, 1), 1, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge])
.SetValueFormat(OptionFormat.Times);
CanTrialMadmate = BooleanOptionItem.Create(Id + 12, "JudgeCanTrialMadmate", true, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
CanTrialCharmed = BooleanOptionItem.Create(Id + 16, "JudgeCanTrialCharmed", true, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]);
+1 -1
View File
@@ -29,7 +29,7 @@ public static class Councillor
Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Councillor);
KillCooldown = FloatOptionItem.Create(Id + 15, "KillCooldown", new(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor])
.SetValueFormat(OptionFormat.Seconds);
MurderLimitPerMeeting = IntegerOptionItem.Create(Id + 10, "MurderLimitPerMeeting", new(0, 5, 1), 0, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor])
MurderLimitPerMeeting = IntegerOptionItem.Create(Id + 10, "MurderLimitPerMeeting", new(0, 15, 1), 0, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor])
.SetValueFormat(OptionFormat.Times);
// MurderLimitPerGame = IntegerOptionItem.Create(Id + 13, "MurderLimitPerGame", new(1, 99, 1), 2, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor])
// .SetValueFormat(OptionFormat.Times);
+2 -2
View File
@@ -97,13 +97,13 @@ namespace TOHE.Roles.Impostor
{
DuelPair.Remove(pair.Key);
SendRPC(pair.Key, pair.Value, true);
_ = new LateTask(duellist.TPtoRndVent, 0.5f, log: false);
_ = new LateTask(() => { duellist.TPtoRndVent(); }, 0.5f, log: false);
}
else if (TAlive && !DAlive)
{
DuelPair.Remove(pair.Key);
SendRPC(pair.Key, pair.Value, true);
_ = new LateTask(target.TPtoRndVent, 0.5f, log: false);
_ = new LateTask(() => { target.TPtoRndVent(); }, 0.5f, log: false);
}
else continue;
}
+4 -4
View File
@@ -60,13 +60,13 @@ namespace TOHE.Roles.Impostor
.SetValueFormat(OptionFormat.Multiplier);
SpeedDur = IntegerOptionItem.Create(Id + 17, "GamblerSpeedupDur", new(1, 20, 1), 5, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
.SetValueFormat(OptionFormat.Seconds);
BSRDelay = IntegerOptionItem.Create(Id + 18, "GamblerKillDelay", new(0, 10, 1), 2, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
BSRDelay = IntegerOptionItem.Create(Id + 18, "GamblerBSRDelay", new(0, 10, 1), 2, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
.SetValueFormat(OptionFormat.Seconds);
HighKCD = FloatOptionItem.Create(Id + 19, "GamblerHighKCD", new(10f, 60f, 2.5f), 30f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
.SetValueFormat(OptionFormat.Seconds);
LowKCD = FloatOptionItem.Create(Id + 20, "GamblerLowKCD", new(10f, 60f, 2.5f), 17.5f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
.SetValueFormat(OptionFormat.Seconds);
TPDelay = IntegerOptionItem.Create(Id + 21, "GamblerKillDelay", new(0, 10, 1), 2, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
TPDelay = IntegerOptionItem.Create(Id + 21, "GamblerTPDelay", new(0, 10, 1), 2, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
.SetValueFormat(OptionFormat.Seconds);
WhatToIgnore = BooleanOptionItem.Create(Id + 22, "GamblerWhatToIgnore", true, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler]);
IgnoreMedicShield = BooleanOptionItem.Create(Id + 23, "GamblerIgnoreMedicShield", true, TabGroup.ImpostorRoles, false).SetParent(WhatToIgnore);
@@ -153,7 +153,7 @@ namespace TOHE.Roles.Impostor
}
else
{
killer.Kill(target);
killer.RpcCheckAndMurder(target);
return false;
}
case 6: // Low KCD
@@ -261,7 +261,7 @@ namespace TOHE.Roles.Impostor
public static void OnReportDeadBody()
{
EffectID = byte.MaxValue;
foreach (var playerId in waitingDelayedKills.Keys)
foreach (var playerId in waitingDelayedKills.Keys.ToArray())
{
var pc = GetPlayerById(playerId);
if (pc.IsAlive()) pc.Kill(pc);
+24
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using Hazel;
using System.Collections.Generic;
using System.Linq;
using static TOHE.Options;
@@ -61,10 +62,29 @@ namespace TOHE.Roles.Neutral
public static bool IsEnable => BubbleId != byte.MaxValue;
public static void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
public static void ApplyGameOptions(IGameOptions opt) => opt.SetVision(HasImpostorVision.GetBool());
private static void SendRPC(byte id = byte.MaxValue, bool remove = false, bool clear = false)
{
if (!IsEnable || !DoRPC) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncBubble, SendOption.Reliable, -1);
writer.Write(remove);
writer.Write(clear);
writer.Write(id);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
public static void ReceiveRPC(MessageReader reader)
{
bool remove = reader.ReadBoolean();
bool clear = reader.ReadBoolean();
byte id = reader.ReadByte();
if (clear) EncasedPlayers.Clear();
else if (remove) EncasedPlayers.Remove(id);
else EncasedPlayers.Add(id, GetTimeStamp());
}
public static void OnCheckMurder(PlayerControl target)
{
if (!IsEnable || target == null) return;
EncasedPlayers.Add(target.PlayerId, GetTimeStamp());
SendRPC(target.PlayerId);
Bubble_.SetKillCooldown();
}
public static void OnFixedUpdate()
@@ -85,12 +105,16 @@ namespace TOHE.Roles.Neutral
}
pc.Suicide(realKiller: Bubble_);
}
EncasedPlayers.Remove(id);
SendRPC(id, remove: true);
}
}
public static void OnReportDeadBody()
{
if (IsEnable) return;
foreach (var pc in EncasedPlayers.Keys.Select(x => GetPlayerById(x)).Where(x => x != null && x.IsAlive())) pc.Suicide(realKiller: Bubble_);
EncasedPlayers.Clear();
SendRPC(clear: true);
}
}
}
+29 -17
View File
@@ -72,27 +72,39 @@ public static class Executioner
playerIdList.Add(playerId);
//ターゲット割り当て
if (AmongUsClient.Instance.AmHost)
try
{
List<PlayerControl> targetList = [];
var rand = IRandom.Instance;
foreach (PlayerControl target in Main.AllPlayerControls)
if (AmongUsClient.Instance.AmHost)
{
if (playerId == target.PlayerId) continue;
else if (!CanTargetImpostor.GetBool() && target.Is(CustomRoleTypes.Impostor)) continue;
else if (!CanTargetNeutralKiller.GetBool() && target.IsNeutralKiller()) continue;
else if (!CanTargetNeutralBenign.GetBool() && target.IsNeutralBenign()) continue;
else if (!CanTargetNeutralEvil.GetBool() && target.IsNeutralEvil()) continue;
else if (!CanTargetNeutralChaos.GetBool() && target.IsNeutralChaos()) continue;
if (target.GetCustomRole() is CustomRoles.GM or CustomRoles.SuperStar) continue;
if (Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) continue;
List<PlayerControl> targetList = [];
var rand = IRandom.Instance;
foreach (PlayerControl target in Main.AllPlayerControls)
{
if (playerId == target.PlayerId) continue;
else if (!CanTargetImpostor.GetBool() && target.Is(CustomRoleTypes.Impostor)) continue;
else if (!CanTargetNeutralKiller.GetBool() && target.IsNeutralKiller()) continue;
else if (!CanTargetNeutralBenign.GetBool() && target.IsNeutralBenign()) continue;
else if (!CanTargetNeutralEvil.GetBool() && target.IsNeutralEvil()) continue;
else if (!CanTargetNeutralChaos.GetBool() && target.IsNeutralChaos()) continue;
if (target.GetCustomRole() is CustomRoles.GM or CustomRoles.SuperStar) continue;
if (Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) continue;
targetList.Add(target);
targetList.Add(target);
}
if (targetList.Count == 0)
{
ChangeRole(Utils.GetPlayerById(playerId));
return;
}
var SelectedTarget = targetList[rand.Next(targetList.Count)];
Target.Add(playerId, SelectedTarget.PlayerId);
SendRPC(playerId, SelectedTarget.PlayerId, "SetTarget");
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()}:{SelectedTarget.GetNameWithRole().RemoveHtmlTags()}", "Executioner");
}
var SelectedTarget = targetList[rand.Next(targetList.Count)];
Target.Add(playerId, SelectedTarget.PlayerId);
SendRPC(playerId, SelectedTarget.PlayerId, "SetTarget");
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()}:{SelectedTarget.GetNameWithRole().RemoveHtmlTags()}", "Executioner");
}
catch (System.Exception ex)
{
Logger.Error(ex.ToString(), "Executioner.Add");
}
}
public static bool IsEnable() => playerIdList.Count > 0;
+22 -11
View File
@@ -51,9 +51,14 @@ namespace TOHE.Roles.Neutral
if (!IsEnable || !DoRPC) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncHookshot, SendOption.Reliable, -1);
writer.Write(ToTargetTP);
writer.Write(MarkedPlayerId);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
public static void ReceiveRPC(MessageReader reader) => ToTargetTP = reader.ReadBoolean();
public static void ReceiveRPC(MessageReader reader)
{
ToTargetTP = reader.ReadBoolean();
MarkedPlayerId = reader.ReadByte();
}
public static void ExecuteAction()
{
if (MarkedPlayerId == byte.MaxValue) return;
@@ -62,19 +67,20 @@ namespace TOHE.Roles.Neutral
if (markedPlayer == null)
{
MarkedPlayerId = byte.MaxValue;
SendRPC();
return;
}
if (ToTargetTP)
{
Hookshot_.TP(markedPlayer);
}
else
{
markedPlayer.TP(Hookshot_);
}
bool isTPsuccess;
MarkedPlayerId = byte.MaxValue;
if (ToTargetTP) isTPsuccess = Hookshot_.TP(markedPlayer);
else isTPsuccess = markedPlayer.TP(Hookshot_);
if (isTPsuccess)
{
MarkedPlayerId = byte.MaxValue;
SendRPC();
}
}
public static void SwitchActionMode()
{
@@ -89,10 +95,15 @@ namespace TOHE.Roles.Neutral
return Hookshot_.CheckDoubleTrigger(target, () =>
{
MarkedPlayerId = target.PlayerId;
SendRPC();
Hookshot_.SetKillCooldown(5f);
});
}
public static void OnReportDeadBody() => MarkedPlayerId = byte.MaxValue;
public static void OnReportDeadBody()
{
MarkedPlayerId = byte.MaxValue;
SendRPC();
}
public static string SuffixText => $"<#00ffa5>Mode:</color> <#ffffff>{(ToTargetTP ? "TP to Target" : "Pull Target")}</color>";
}
}
+33 -28
View File
@@ -75,27 +75,39 @@ public static class Lawyer
playerIdList.Add(playerId);
//ターゲット割り当て
if (AmongUsClient.Instance.AmHost)
try
{
List<PlayerControl> targetList = [];
var rand = IRandom.Instance;
foreach (PlayerControl target in Main.AllPlayerControls)
if (AmongUsClient.Instance.AmHost)
{
if (playerId == target.PlayerId) continue;
else if (!CanTargetImpostor.GetBool() && target.Is(CustomRoleTypes.Impostor)) continue;
else if (!CanTargetNeutralKiller.GetBool() && target.IsNeutralKiller()) continue;
else if (!CanTargetCrewmate.GetBool() && target.Is(CustomRoleTypes.Crewmate)) continue;
else if (!CanTargetJester.GetBool() && target.Is(CustomRoles.Jester)) continue;
else if (target.Is(CustomRoleTypes.Neutral) && !target.IsNeutralKiller() && !target.Is(CustomRoles.Jester)) continue;
if (target.GetCustomRole() is CustomRoles.GM or CustomRoles.SuperStar) continue;
if (Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) continue;
List<PlayerControl> targetList = [];
var rand = IRandom.Instance;
foreach (PlayerControl target in Main.AllPlayerControls)
{
if (playerId == target.PlayerId) continue;
else if (!CanTargetImpostor.GetBool() && target.Is(CustomRoleTypes.Impostor)) continue;
else if (!CanTargetNeutralKiller.GetBool() && target.IsNeutralKiller()) continue;
else if (!CanTargetCrewmate.GetBool() && target.Is(CustomRoleTypes.Crewmate)) continue;
else if (!CanTargetJester.GetBool() && target.Is(CustomRoles.Jester)) continue;
else if (target.Is(CustomRoleTypes.Neutral) && !target.IsNeutralKiller() && !target.Is(CustomRoles.Jester)) continue;
if (target.GetCustomRole() is CustomRoles.GM or CustomRoles.SuperStar) continue;
if (Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) continue;
targetList.Add(target);
targetList.Add(target);
}
if (targetList.Count == 0)
{
ChangeRole(Utils.GetPlayerById(playerId));
return;
}
var SelectedTarget = targetList[rand.Next(targetList.Count)];
Target.Add(playerId, SelectedTarget.PlayerId);
SendRPC(playerId, SelectedTarget.PlayerId, "SetTarget");
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()}:{SelectedTarget.GetNameWithRole().RemoveHtmlTags()}", "Lawyer");
}
var SelectedTarget = targetList[rand.Next(targetList.Count)];
Target.Add(playerId, SelectedTarget.PlayerId);
SendRPC(playerId, SelectedTarget.PlayerId, "SetTarget");
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()}:{SelectedTarget.GetNameWithRole().RemoveHtmlTags()}", "Lawyer");
}
catch (System.Exception ex)
{
Logger.Error(ex.ToString(), "Lawyer.Add");
}
}
public static bool IsEnable() => playerIdList.Count > 0;
@@ -139,11 +151,12 @@ public static class Lawyer
if (x.Value == target.PlayerId)
Lawyer = x.Key;
});
Utils.GetPlayerById(Lawyer).RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]);
PlayerControl lawyer = Utils.GetPlayerById(Lawyer);
lawyer.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]);
Target.Remove(Lawyer);
SendRPC(Lawyer);
Utils.NotifyRoles(SpecifySeer: Utils.GetPlayerById(Lawyer), SpecifyTarget: target);
Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: Utils.GetPlayerById(Lawyer));
Utils.NotifyRoles(SpecifySeer: lawyer, SpecifyTarget: target);
Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: lawyer);
}
public static bool KnowRole(PlayerControl player, PlayerControl target)
{
@@ -161,7 +174,6 @@ public static class Lawyer
var GetValue = Target.TryGetValue(seer.PlayerId, out var targetId);
return GetValue && targetId == target.PlayerId ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lawyer), "§") : string.Empty;
}
public static void ChangeRole(PlayerControl lawyer)
{
lawyer.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]);
@@ -171,13 +183,6 @@ public static class Lawyer
text = string.Format(text, Utils.ColorString(Utils.GetRoleColor(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]), Translator.GetString(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()].ToString())));
lawyer.Notify(text);
}
public static string TargetMark(PlayerControl seer, PlayerControl target)
{
if (!seer.Is(CustomRoles.Lawyer)) return string.Empty; //エクスキューショナー以外処理しない
var GetValue = Target.TryGetValue(seer.PlayerId, out var targetId);
return GetValue && targetId == target.PlayerId ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lawyer), "§") : string.Empty;
}
public static bool CheckExileTarget(GameData.PlayerInfo exiled/*, bool DecidedWinner, bool Check = false*/)
{
foreach (var kvp in Target.Where(x => x.Value == exiled.PlayerId))
+21 -1
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using Hazel;
using System.Collections.Generic;
using System.Linq;
using static TOHE.Options;
@@ -45,7 +46,7 @@ namespace TOHE.Roles.Neutral
InfectRadius = FloatOptionItem.Create(Id + 5, "InfectRadius", new(0.1f, 5f, 0.1f), 3f, TabGroup.NeutralRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Mycologist])
.SetValueFormat(OptionFormat.Multiplier);
InfectTime = IntegerOptionItem.Create(Id + 6, "PlagueDoctorInfectTime", new(0, 60, 1), 5, TabGroup.NeutralRoles, false)
InfectTime = IntegerOptionItem.Create(Id + 6, "InfectDelay", new(0, 60, 1), 5, TabGroup.NeutralRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Mycologist])
.SetValueFormat(OptionFormat.Seconds);
}
@@ -65,6 +66,23 @@ namespace TOHE.Roles.Neutral
public static bool IsEnable => MycologistId != byte.MaxValue;
public static void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
public static void ApplyGameOptions(IGameOptions opt) => opt.SetVision(HasImpostorVision.GetBool());
private static void SendRPC()
{
if (!IsEnable || !DoRPC) return;
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncMycologist, SendOption.Reliable, -1);
writer.Write(InfectedPlayers.Count);
if (InfectedPlayers.Count > 0) foreach (var x in InfectedPlayers) writer.Write(x);
AmongUsClient.Instance.FinishRpcImmediately(writer);
}
public static void ReceiveRPC(MessageReader reader)
{
InfectedPlayers.Clear();
var length = reader.ReadInt32();
for (int i = 0; i < length; i++)
{
InfectedPlayers.Add(reader.ReadByte());
}
}
public static void SpreadSpores()
{
if (!IsEnable || Mycologist_.HasAbilityCD()) return;
@@ -72,6 +90,8 @@ namespace TOHE.Roles.Neutral
_ = new LateTask(() =>
{
InfectedPlayers.AddRange(GetPlayersInRadius(InfectRadius.GetFloat(), Mycologist_.Pos()).Select(x => x.PlayerId));
SendRPC();
NotifyRoles(SpecifySeer: Mycologist_);
}, InfectTime.GetFloat(), "Mycologist Infect Time");
Mycologist_.Notify(GetString("MycologistNotify"));
}
+1 -1
View File
@@ -92,7 +92,7 @@ public static class Vengeance
if (target == null) return false;
if (IsRevenge) return true;
_ = new LateTask(target.TPtoRndVent, 0.01f);
_ = new LateTask(() => { target.TPtoRndVent(); }, 0.01f);
Timer = RevengeTime.GetInt();
Countdown(Timer, target);
+2 -2
View File
@@ -33,8 +33,8 @@ public class Main : BasePlugin
public static ConfigEntry<string> DebugKeyInput { get; private set; }
public static readonly string MainMenuText = " ";
public const string PluginGuid = "com.gurge44.toheplus";
public const string PluginVersion = "2.2.0";
public const string PluginDisplayVersion = "2.2.0";
public const string PluginVersion = "2.2.2";
public const string PluginDisplayVersion = "2.2.2";
public static readonly string SupportedAUVersion = "2023.10.24";
public const int PluginCreate = 3;
public const bool Canary = false;