mirror of
https://github.com/Gurge44/EndlessHostRoles.git
synced 2026-10-20 11:39:54 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9b06aff9a | ||
|
|
063b9ff964 | ||
|
|
9a944d9fd3 | ||
|
|
b2013dc25f | ||
|
|
cc8244f487 | ||
|
|
0dc6fc2164 | ||
|
|
1e57d4e171 | ||
|
|
9abed63369 | ||
|
|
2713b69f86 | ||
|
|
2260f90180 | ||
|
|
9c1464582c | ||
|
|
3c5b8f982b |
No files matched your search
@@ -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();
|
||||
}
|
||||
|
||||
@@ -88,15 +88,12 @@ internal class CustomRoleSelector
|
||||
{
|
||||
object cr = list[i1];
|
||||
CustomRoles role = (CustomRoles)Enum.Parse(typeof(CustomRoles), cr.ToString());
|
||||
if (role.IsVanilla() || role.IsAdditionRole()) continue;
|
||||
if (!Main.UseVersionProtocol.Value && !role.IsAbleToHostPublic()) continue;
|
||||
if (role.IsVanilla() || role.IsAdditionRole() || (CustomRolesHelper.OnlySpawnsWithPetsRoleList.Contains(role) && !Options.UsePets.GetBool()) || (!Main.UseVersionProtocol.Value && !role.IsAbleToHostPublic())) continue;
|
||||
switch (role)
|
||||
{
|
||||
case CustomRoles.DarkHide when (MapNames)Main.NormalOptions.MapId == MapNames.Fungle:
|
||||
case CustomRoles.Pelican when roleList.Contains(CustomRoles.Duellist):
|
||||
case CustomRoles.Duellist when roleList.Contains(CustomRoles.Pelican):
|
||||
case CustomRoles.Tunneler when !Options.UsePets.GetBool():
|
||||
case CustomRoles.Tornado when !Options.UsePets.GetBool():
|
||||
case CustomRoles.GM:
|
||||
case CustomRoles.NotAssigned:
|
||||
continue;
|
||||
|
||||
+348
-420
@@ -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;
|
||||
|
||||
@@ -15,7 +15,7 @@ public class DevUser(string code = "", string color = "null", string tag = "null
|
||||
public string UpName { get; set; } = upName;
|
||||
|
||||
public bool HasTag() => Tag != "null";
|
||||
public string GetTag() => Color == "null" ? $"<size=1>{Tag}</size>\r\n" : $"<color={Color}><size=1>{(Tag == "#Dev" ? Translator.GetString("Developer") : Tag)}</size></color>\r\n";
|
||||
public string GetTag() => Color == "null" ? $"<size=1.4>{Tag}</size>\r\n" : $"<color={Color}><size=1.4>{(Tag == "#Dev" ? Translator.GetString("Developer") : Tag)}</size></color>\r\n";
|
||||
}
|
||||
|
||||
public static class DevManager
|
||||
@@ -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));
|
||||
|
||||
@@ -213,7 +213,10 @@ static class ExtendedPlayerControl
|
||||
Main.PlayerStates[pc.PlayerId].deathReason = deathReason;
|
||||
Main.PlayerStates[pc.PlayerId].SetDead();
|
||||
if (realKiller != null) pc.SetRealKiller(realKiller);
|
||||
|
||||
Medic.IsDead(pc);
|
||||
if (realKiller != null && realKiller.Is(CustomRoles.Damocles)) Damocles.OnMurder(realKiller.PlayerId);
|
||||
|
||||
pc.Kill(pc);
|
||||
}
|
||||
|
||||
@@ -624,8 +627,8 @@ static class ExtendedPlayerControl
|
||||
CustomRoles.YinYanger => pc.IsAlive(),
|
||||
CustomRoles.Librarian => pc.IsAlive() && Librarian.CanUseKillButton(pc),
|
||||
CustomRoles.Cantankerous => pc.IsAlive() && Cantankerous.CanUseKillButton(pc.PlayerId),
|
||||
CustomRoles.Inhibitor => !Utils.IsActive(SystemTypes.Electrical) && !Utils.IsActive(SystemTypes.Comms) && !Utils.IsActive(SystemTypes.MushroomMixupSabotage) && !Utils.IsActive(SystemTypes.Laboratory) && !Utils.IsActive(SystemTypes.LifeSupp) && !Utils.IsActive(SystemTypes.Reactor) && !Utils.IsActive(SystemTypes.HeliSabotage),
|
||||
CustomRoles.Saboteur => Utils.IsActive(SystemTypes.Electrical) || Utils.IsActive(SystemTypes.Comms) || Utils.IsActive(SystemTypes.MushroomMixupSabotage) || Utils.IsActive(SystemTypes.Laboratory) || Utils.IsActive(SystemTypes.LifeSupp) || Utils.IsActive(SystemTypes.Reactor) || Utils.IsActive(SystemTypes.HeliSabotage),
|
||||
CustomRoles.Inhibitor => !IsActive(SystemTypes.Electrical) && !IsActive(SystemTypes.Comms) && !IsActive(SystemTypes.MushroomMixupSabotage) && !IsActive(SystemTypes.Laboratory) && !IsActive(SystemTypes.LifeSupp) && !IsActive(SystemTypes.Reactor) && !IsActive(SystemTypes.HeliSabotage),
|
||||
CustomRoles.Saboteur => IsActive(SystemTypes.Electrical) || IsActive(SystemTypes.Comms) || IsActive(SystemTypes.MushroomMixupSabotage) || IsActive(SystemTypes.Laboratory) || IsActive(SystemTypes.LifeSupp) || IsActive(SystemTypes.Reactor) || IsActive(SystemTypes.HeliSabotage),
|
||||
CustomRoles.Sniper => Sniper.CanUseKillButton(pc),
|
||||
CustomRoles.Sheriff => Sheriff.CanUseKillButton(pc.PlayerId),
|
||||
CustomRoles.Crusader => Crusader.CanUseKillButton(pc.PlayerId),
|
||||
@@ -1209,7 +1212,6 @@ static class ExtendedPlayerControl
|
||||
case CustomRoles.Medusa:
|
||||
Medusa.SetKillCooldown(player.PlayerId);
|
||||
break;
|
||||
|
||||
case CustomRoles.Cleaner:
|
||||
Main.AllPlayerKillCooldown[player.PlayerId] = Options.CleanerKillCooldown.GetFloat();
|
||||
break;
|
||||
@@ -1382,17 +1384,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)
|
||||
{
|
||||
@@ -1402,7 +1404,7 @@ static class ExtendedPlayerControl
|
||||
|
||||
if (target.GetTeam() is Team.Impostor or Team.Neutral) Stressed.OnNonCrewmateDead();
|
||||
|
||||
if (killer.Is(CustomRoles.Damocles)) Damocles.OnMurder();
|
||||
if (killer.Is(CustomRoles.Damocles)) Damocles.OnMurder(killer.PlayerId);
|
||||
else if (killer.Is(Team.Impostor)) Damocles.OnOtherImpostorMurder();
|
||||
if (target.Is(Team.Impostor)) Damocles.OnImpostorDeath();
|
||||
|
||||
|
||||
@@ -1124,7 +1124,7 @@ public static class Options
|
||||
NameDisplayAddons = BooleanOptionItem.Create(210, "NameDisplayAddons", true, TabGroup.Addons, false)
|
||||
.SetGameMode(CustomGameMode.Standard)
|
||||
.SetHeader(true);
|
||||
NoLimitAddonsNumMax = IntegerOptionItem.Create(211, "NoLimitAddonsNumMax", new(1, 15, 1), 1, TabGroup.Addons, false)
|
||||
NoLimitAddonsNumMax = IntegerOptionItem.Create(211, "NoLimitAddonsNumMax", new(1, 90, 1), 1, TabGroup.Addons, false)
|
||||
.SetGameMode(CustomGameMode.Standard);
|
||||
|
||||
//==================================================================================================================================//
|
||||
@@ -3705,7 +3705,7 @@ public static class Options
|
||||
.SetHeader(true)
|
||||
.SetGameMode(customGameMode) as StringOptionItem;
|
||||
|
||||
var countOption = IntegerOptionItem.Create(id + 1, "Maximum", new(1, canSetNum ? 10 : 1, 1), 1, tab, false)
|
||||
var countOption = IntegerOptionItem.Create(id + 1, "Maximum", new(1, canSetNum ? 15 : 1, 1), 1, tab, false)
|
||||
.SetParent(spawnOption)
|
||||
.SetValueFormat(OptionFormat.Players)
|
||||
.SetHidden(!canSetNum)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
+147
-47
@@ -1,4 +1,3 @@
|
||||
using Csv;
|
||||
using HarmonyLib;
|
||||
using Il2CppInterop.Runtime.InteropTypes.Arrays;
|
||||
using System;
|
||||
@@ -7,6 +6,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace TOHE;
|
||||
@@ -17,55 +17,105 @@ public static class Translator
|
||||
public const string LANGUAGE_FOLDER_NAME = "Language";
|
||||
public static void Init()
|
||||
{
|
||||
Logger.Info("Loading language file...", "Translator");
|
||||
Logger.Info("Loading Custom Translations...", "Translator");
|
||||
LoadLangs();
|
||||
Logger.Info("Language file loaded successfully", "Translator");
|
||||
Logger.Info("Loaded Custom Translations", "Translator");
|
||||
}
|
||||
public static void LoadLangs()
|
||||
{
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
var stream = assembly.GetManifestResourceStream("TOHE.Resources.String.csv");
|
||||
translateMaps = [];
|
||||
try
|
||||
{
|
||||
// Get the directory containing the JSON files (e.g., TOHE.Resources.Lang)
|
||||
string jsonDirectory = "TOHE.Resources.Lang";
|
||||
// Get the assembly containing the resources
|
||||
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
string[] jsonFileNames = GetJsonFileNames(assembly, jsonDirectory);
|
||||
|
||||
var options = new CsvOptions()
|
||||
{
|
||||
HeaderMode = HeaderMode.HeaderPresent,
|
||||
AllowNewLineInEnclosedFieldValues = false,
|
||||
};
|
||||
foreach (var line in CsvReader.ReadFromStream(stream, options))
|
||||
{
|
||||
if (line.Values[0][0] == '#') continue;
|
||||
try
|
||||
translateMaps = [];
|
||||
|
||||
if (jsonFileNames.Length == 0)
|
||||
{
|
||||
Dictionary<int, string> dic = [];
|
||||
for (int i = 1; i < line.ColumnCount; i++)
|
||||
Logger.Warn("Json Translation files does not exist.", "Translator");
|
||||
return;
|
||||
}
|
||||
foreach (string jsonFileName in jsonFileNames)
|
||||
{
|
||||
// Read the JSON file content
|
||||
using Stream resourceStream = assembly.GetManifestResourceStream(jsonFileName);
|
||||
if (resourceStream != null)
|
||||
{
|
||||
int id = int.Parse(line.Headers[i]);
|
||||
dic[id] = line.Values[i].Replace("\\n", "\n").Replace("\\r", "\r");
|
||||
using StreamReader reader = new(resourceStream);
|
||||
string jsonContent = reader.ReadToEnd();
|
||||
|
||||
// Deserialize the JSON into a dictionary
|
||||
Dictionary<string, string> jsonDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(jsonContent);
|
||||
if (jsonDictionary.TryGetValue("LanguageID", out string languageIdObj) && int.TryParse(languageIdObj, out int languageId))
|
||||
{
|
||||
// Remove the "LanguageID" entry
|
||||
jsonDictionary.Remove("LanguageID");
|
||||
|
||||
// Handle the rest of the data and merge it into the resulting translation map
|
||||
MergeJsonIntoTranslationMap(translateMaps, languageId, jsonDictionary);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Logger.Warn(jsonDictionary["HostText"], "Translator");
|
||||
Logger.Warn($"Invalid JSON format in {jsonFileName}: Missing or invalid 'LanguageID' field.", "Translator");
|
||||
}
|
||||
}
|
||||
if (!translateMaps.TryAdd(line.Values[0], dic))
|
||||
Logger.Warn($"Duplicate in CSV file to be translated: line {line.Index} => \"{line.Values[0]}\"", "Translator");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
// Convert the resulting translation map to JSON
|
||||
string mergedJson = JsonSerializer.Serialize(translateMaps, new JsonSerializerOptions
|
||||
{
|
||||
Logger.Warn($"Translation file error: line {line.Index} => \"{line.Values[0]}\"", "Translator");
|
||||
Logger.Warn(ex.ToString(), "Translator");
|
||||
}
|
||||
WriteIndented = true
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error: {ex}", "Translator");
|
||||
}
|
||||
|
||||
// カスタム翻訳ファイルの読み込み
|
||||
// Loading custom translation files
|
||||
if (!Directory.Exists(LANGUAGE_FOLDER_NAME)) Directory.CreateDirectory(LANGUAGE_FOLDER_NAME);
|
||||
|
||||
// 翻訳テンプレートの作成
|
||||
// Creating a translation template
|
||||
CreateTemplateFile();
|
||||
System.Collections.IList list = Enum.GetValues(typeof(SupportedLangs));
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
foreach (var lang in EnumHelper.GetAllValues<SupportedLangs>())
|
||||
{
|
||||
object lang = list[i];
|
||||
if (File.Exists(@$"./{LANGUAGE_FOLDER_NAME}/{lang}.dat"))
|
||||
LoadCustomTranslation($"{lang}.dat", (SupportedLangs)lang);
|
||||
{
|
||||
UpdateCustomTranslation($"{lang}.dat", lang);
|
||||
LoadCustomTranslation($"{lang}.dat", lang);
|
||||
}
|
||||
}
|
||||
}
|
||||
static void MergeJsonIntoTranslationMap(Dictionary<string, Dictionary<int, string>> translationMaps, int languageId, Dictionary<string, string> jsonDictionary)
|
||||
{
|
||||
foreach (var kvp in jsonDictionary)
|
||||
{
|
||||
string textString = kvp.Key;
|
||||
if (kvp.Value is string translation)
|
||||
{
|
||||
|
||||
// If the textString is not already in the translation map, add it
|
||||
if (!translationMaps.ContainsKey(textString))
|
||||
{
|
||||
translationMaps[textString] = [];
|
||||
}
|
||||
|
||||
// Add or update the translation for the current id and textString
|
||||
translationMaps[textString][languageId] = translation.Replace("\\n", "\n").Replace("\\r", "\r");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to get a list of JSON file names in a directory
|
||||
static string[] GetJsonFileNames(System.Reflection.Assembly assembly, string directoryName)
|
||||
{
|
||||
string[] resourceNames = assembly.GetManifestResourceNames();
|
||||
return resourceNames.Where(resourceName => resourceName.StartsWith(directoryName) && resourceName.EndsWith(".json")).ToArray();
|
||||
}
|
||||
|
||||
public static string GetString(string s, Dictionary<string, string> replacementDic = null, bool console = false)
|
||||
{
|
||||
@@ -93,8 +143,8 @@ public static class Translator
|
||||
}
|
||||
if (!translateMaps.ContainsKey(str)) //translateMapsにない場合、StringNamesにあれば取得する
|
||||
{
|
||||
var stringNames = Enum.GetValues(typeof(StringNames)).Cast<StringNames>().Where(x => x.ToString() == str);
|
||||
if (stringNames != null && stringNames.Any())
|
||||
var stringNames = EnumHelper.GetAllValues<StringNames>().Where(x => x.ToString() == str).ToArray();
|
||||
if (stringNames != null && stringNames.Length > 0)
|
||||
res = GetString(stringNames.FirstOrDefault());
|
||||
}
|
||||
}
|
||||
@@ -132,34 +182,84 @@ public static class Translator
|
||||
return SupportedLangs.English;
|
||||
}
|
||||
}
|
||||
static void UpdateCustomTranslation(string filename, SupportedLangs lang)
|
||||
{
|
||||
string path = @$"./{LANGUAGE_FOLDER_NAME}/{filename}";
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Logger.Info("Updating Custom Translations", "UpdateCustomTranslation");
|
||||
try
|
||||
{
|
||||
List<string> textStrings = [];
|
||||
using (StreamReader reader = new(path, Encoding.GetEncoding("UTF-8")))
|
||||
{
|
||||
string line;
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
{
|
||||
// Split the line by ':' to get the first part
|
||||
string[] parts = line.Split(':');
|
||||
|
||||
// Check if there is at least one part before ':'
|
||||
if (parts.Length >= 1)
|
||||
{
|
||||
// Trim any leading or trailing spaces and add it to the list
|
||||
string textString = parts[0].Trim();
|
||||
textStrings.Add(textString);
|
||||
}
|
||||
}
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
foreach (var templateString in translateMaps.Keys)
|
||||
{
|
||||
if (!textStrings.Contains(templateString)) sb.Append($"{templateString}:\n");
|
||||
}
|
||||
using FileStream fileStream = new(path, FileMode.Append, FileAccess.Write);
|
||||
using StreamWriter writer = new(fileStream);
|
||||
writer.WriteLine(sb.ToString());
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("An error occurred: " + e.Message, "Translator");
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void LoadCustomTranslation(string filename, SupportedLangs lang)
|
||||
{
|
||||
string path = @$"./{LANGUAGE_FOLDER_NAME}/{filename}";
|
||||
if (File.Exists(path))
|
||||
{
|
||||
Logger.Info($"Loading custom translation file:{filename}", "LoadCustomTranslation");
|
||||
using StreamReader sr = new(path, Encoding.GetEncoding("UTF-8"));
|
||||
string text;
|
||||
string[] tmp = [];
|
||||
while ((text = sr.ReadLine()) != null)
|
||||
Logger.Info($"Loading Custom Translation File:{filename}", "LoadCustomTranslation");
|
||||
try
|
||||
{
|
||||
tmp = text.Split(":");
|
||||
if (tmp.Length > 1 && tmp[1] != "")
|
||||
using StreamReader sr = new(path, Encoding.GetEncoding("UTF-8"));
|
||||
string text;
|
||||
string[] tmp = [];
|
||||
while ((text = sr.ReadLine()) != null)
|
||||
{
|
||||
try
|
||||
tmp = text.Split(":");
|
||||
if (tmp.Length > 1 && tmp[1] != "")
|
||||
{
|
||||
translateMaps[tmp[0]][(int)lang] = tmp.Skip(1).Join(delimiter: ":").Replace("\\n", "\n").Replace("\\r", "\r");
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
Logger.Warn($"Invalid key:{tmp[0]}", "LoadCustomTranslation");
|
||||
try
|
||||
{
|
||||
translateMaps[tmp[0]][(int)lang] = tmp.Skip(1).Join(delimiter: ":").Replace("\\n", "\n").Replace("\\r", "\r");
|
||||
}
|
||||
catch (KeyNotFoundException)
|
||||
{
|
||||
Logger.Warn($"Invalid Key:{tmp[0]}", "LoadCustomTranslation");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ObjectDisposedException) { }
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToString(), "Translator.LoadCustomTranslation");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Error($"Custom translation file not found:{filename}", "LoadCustomTranslation");
|
||||
Logger.Error($"Custom Translation File Not Found:{filename}", "LoadCustomTranslation");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-37
@@ -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)
|
||||
{
|
||||
@@ -382,32 +383,8 @@ public static class Utils
|
||||
|
||||
if (Options.NameDisplayAddons.GetBool() && !pure && self)
|
||||
{
|
||||
if (Options.AddBracketsToAddons.GetBool())
|
||||
{
|
||||
if (Options.ImpEgoistVisibalToAllies.GetBool())
|
||||
{
|
||||
foreach (var subRole in targetSubRoles.Where(x => x is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Admired and not CustomRoles.Soulless and not CustomRoles.Lovers and not CustomRoles.Infected and not CustomRoles.Contagious))
|
||||
RoleText = ColorString(GetRoleColor(subRole), GetString("PrefixB." + subRole.ToString())) + RoleText;
|
||||
}
|
||||
if (!Options.ImpEgoistVisibalToAllies.GetBool())
|
||||
{
|
||||
foreach (var subRole in targetSubRoles.Where(x => x is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Admired and not CustomRoles.Soulless and not CustomRoles.Lovers and not CustomRoles.Infected and not CustomRoles.Contagious))
|
||||
RoleText = ColorString(GetRoleColor(subRole), GetString("PrefixB." + subRole.ToString())) + RoleText;
|
||||
}
|
||||
}
|
||||
else if (!Options.AddBracketsToAddons.GetBool())
|
||||
{
|
||||
if (Options.ImpEgoistVisibalToAllies.GetBool())
|
||||
{
|
||||
foreach (var subRole in targetSubRoles.Where(x => x is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Admired and not CustomRoles.Soulless and not CustomRoles.Lovers and not CustomRoles.Infected and not CustomRoles.Contagious))
|
||||
RoleText = ColorString(GetRoleColor(subRole), GetString("Prefix." + subRole.ToString())) + RoleText;
|
||||
}
|
||||
if (!Options.ImpEgoistVisibalToAllies.GetBool())
|
||||
{
|
||||
foreach (var subRole in targetSubRoles.Where(x => x is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Admired and not CustomRoles.Soulless and not CustomRoles.Lovers and not CustomRoles.Infected and not CustomRoles.Contagious))
|
||||
RoleText = ColorString(GetRoleColor(subRole), GetString("Prefix." + subRole.ToString())) + RoleText;
|
||||
}
|
||||
}
|
||||
foreach (var subRole in targetSubRoles.Where(x => x is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not CustomRoles.Recruit and not CustomRoles.Admired and not CustomRoles.Soulless and not CustomRoles.Lovers and not CustomRoles.Infected and not CustomRoles.Contagious))
|
||||
RoleText = ColorString(GetRoleColor(subRole), (Options.AddBracketsToAddons.GetBool() ? "<#ffffff>(</color>" : string.Empty) + GetString("Prefix." + subRole.ToString()) + (Options.AddBracketsToAddons.GetBool() ? "<#ffffff>)</color>" : string.Empty) + " ") + RoleText;
|
||||
}
|
||||
|
||||
if (targetSubRoles.Contains(CustomRoles.Madmate))
|
||||
@@ -1153,7 +1130,7 @@ public static class Utils
|
||||
Logger.Error($"For {pc.GetNameWithRole().RemoveHtmlTags()}, failed to get progress text: " + ex.ToString(), "Utils.GetProgressText");
|
||||
}
|
||||
|
||||
if (pc.Is(CustomRoles.Damocles)) ProgressText.Append(' ' + Damocles.GetProgressText());
|
||||
if (pc.Is(CustomRoles.Damocles)) ProgressText.Append(' ' + Damocles.GetProgressText(playerId));
|
||||
if (pc.Is(CustomRoles.Stressed)) ProgressText.Append(' ' + Stressed.GetProgressText(playerId));
|
||||
|
||||
if (ProgressText.Length != 0 && !ProgressText.ToString().StartsWith(' '))
|
||||
@@ -1881,12 +1858,13 @@ public static class Utils
|
||||
}
|
||||
|
||||
DevUser devUser = player.FriendCode.GetDevUser();
|
||||
if (!name.Contains('\r') && devUser.HasTag())
|
||||
bool isMod = ChatCommands.IsPlayerModerator(player.FriendCode);
|
||||
if (!name.Contains('\r') && (devUser.HasTag() || isMod))
|
||||
{
|
||||
string tag = devUser.GetTag();
|
||||
if (player.AmOwner || player.IsModClient())
|
||||
name = tag + name;
|
||||
else name = tag.Replace("\r\n", " - ") + name;
|
||||
name = tag + (isMod ? ("<size=1.4>" + GetString("ModeratorTag") + "\r\n</size>") : string.Empty) + name;
|
||||
else name = tag.Replace("\r\n", " - ") + (isMod ? ("<size=1.4>" + GetString("ModeratorTag") + " - </size>") : string.Empty) + name;
|
||||
}
|
||||
|
||||
if (player.AmOwner)
|
||||
@@ -1962,6 +1940,8 @@ public static class Utils
|
||||
PlayerControl[] seerList = SpecifySeer != null ? ([SpecifySeer]) : Main.AllPlayerControls;
|
||||
PlayerControl[] targetList = SpecifyTarget != null ? ([SpecifyTarget]) : Main.AllPlayerControls;
|
||||
|
||||
Logger.Info($" Seers: {string.Join(", ", seerList.Select(x => x.GetNameWithRole()))} Targets: {string.Join(", ", targetList.Select(x => x.GetNameWithRole()))}", "NR");
|
||||
|
||||
//seer: Players who can see changes made here
|
||||
//target: Players subject to changes that seer can see
|
||||
foreach (PlayerControl seer in seerList)
|
||||
@@ -2214,7 +2194,6 @@ public static class Utils
|
||||
if (target.PlayerId == seer.PlayerId) continue;
|
||||
Logger.Info("NotifyRoles-Loop2-" + target.GetNameWithRole().RemoveHtmlTags() + ":START", "NotifyRoles");
|
||||
|
||||
|
||||
if ((IsActive(SystemTypes.MushroomMixupSabotage) || MushroomMixup) && target.IsAlive() && !seer.Is(CustomRoleTypes.Impostor) && Main.ResetCamPlayerList.Contains(seer.PlayerId))
|
||||
{
|
||||
seer.RpcSetNamePrivate("<size=0%>", true, force: NoCache);
|
||||
@@ -2490,6 +2469,7 @@ public static class Utils
|
||||
|
||||
TargetSuffix.Append(PlagueDoctor.GetLowerTextOthers(seer, target));
|
||||
TargetSuffix.Append(Stealth.GetSuffix(seer, target));
|
||||
TargetSuffix.Append(Bubble.GetEncasedPlayerSuffix(seer, target));
|
||||
|
||||
if (target.Is(CustomRoles.Librarian)) TargetSuffix.Append(Librarian.GetNameTextForSuffix(target.PlayerId));
|
||||
|
||||
@@ -2898,7 +2878,7 @@ public static class Utils
|
||||
neutralnum++;
|
||||
}
|
||||
}
|
||||
return (notify ? "<#777777>" : string.Empty) +
|
||||
return (notify ? "<#777777>" : string.Empty) +
|
||||
(impnum == 1 ? GetString("RemainingText.Prefix.SingleImp") : GetString("RemainingText.Prefix.PluralImp")) +
|
||||
(notify ? " " : "\n") +
|
||||
(notify ? "<#ffffff>" : "<b>") +
|
||||
@@ -3057,4 +3037,5 @@ public static class Utils
|
||||
public static int PlayersCount(CountTypes countTypes) => Main.PlayerStates.Values.Count(state => state.countTypes == countTypes);
|
||||
public static int AlivePlayersCount(CountTypes countTypes) => Main.AllAlivePlayerControls.Count(pc => pc.Is(countTypes));
|
||||
public static int IsOneAlive(CountTypes countTypes) => Main.AllAlivePlayerControls.Any(pc => pc.Is(countTypes)) ? 1 : 0;
|
||||
public static bool IsNonHostModClient(this byte id) => id != 0 && Main.playerVersion.ContainsKey(id);
|
||||
}
|
||||
+46
-36
@@ -20,15 +20,16 @@ namespace TOHE;
|
||||
internal class ChatCommands
|
||||
{
|
||||
// Function to check if a player is a moderator
|
||||
private static bool IsPlayerModerator(string friendCode)
|
||||
public static bool IsPlayerModerator(string friendCode)
|
||||
{
|
||||
if (friendCode == "" || friendCode == string.Empty) return false;
|
||||
if (friendCode == "" || friendCode == string.Empty || !Options.ApplyModeratorList.GetBool()) return false;
|
||||
var friendCodesFilePath = @"./TOHE_DATA/Moderators.txt";
|
||||
var friendCodes = File.ReadAllLines(friendCodesFilePath);
|
||||
return friendCodes.Any(code => code.Contains(friendCode));
|
||||
return friendCodes.Any(code => code.Contains(friendCode, StringComparison.CurrentCultureIgnoreCase));
|
||||
}
|
||||
|
||||
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":
|
||||
@@ -321,6 +322,7 @@ internal class ChatCommands
|
||||
Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"<color=#ff0000>{GetString("MessageFromTheHost")}</color>");
|
||||
break;
|
||||
|
||||
case "/ban":
|
||||
case "/kick":
|
||||
canceled = true;
|
||||
// Check if the kick command is enabled in the settings
|
||||
@@ -365,7 +367,7 @@ internal class ChatCommands
|
||||
}
|
||||
|
||||
// Kick the specified player
|
||||
AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), true);
|
||||
AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), args[0] == "/ban");
|
||||
string kickedPlayerName = kickedPlayer.GetRealName();
|
||||
string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")}";
|
||||
if (GameStates.IsInGame)
|
||||
@@ -430,11 +432,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;
|
||||
@@ -817,7 +819,8 @@ internal class ChatCommands
|
||||
if (isUp) return;
|
||||
}
|
||||
var sb = new StringBuilder();
|
||||
_ = sb.Append($"{devMark}<b>{roleName}</b>{Utils.GetRoleMode(rl)}{GetString($"{rl}InfoLong")}");
|
||||
var title = $"{devMark}<{Main.roleColors[rl]}>{roleName}</color> {Utils.GetRoleMode(rl)}";
|
||||
_ = sb.Append($"{GetString($"{rl}InfoLong")}");
|
||||
var settings = new StringBuilder();
|
||||
if (Options.CustomRoleSpawnChances.ContainsKey(rl))
|
||||
{
|
||||
@@ -828,7 +831,7 @@ internal class ChatCommands
|
||||
_ = sb.Clear().Append(txt);
|
||||
}
|
||||
Utils.SendMessage(text: "\n", sendTo: playerId, title: settings.ToString());
|
||||
Utils.SendMessage(text: sb.ToString(), sendTo: playerId);
|
||||
Utils.SendMessage(text: sb.ToString(), sendTo: playerId, title: title);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -840,6 +843,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 +852,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 +974,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;
|
||||
|
||||
@@ -994,6 +1001,7 @@ internal class ChatCommands
|
||||
|
||||
Utils.SendMessage(msgText, player.PlayerId);
|
||||
break;
|
||||
case "/ban":
|
||||
case "/kick":
|
||||
// Check if the kick command is enabled in the settings
|
||||
if (Options.ApplyModeratorList.GetValue() == 0)
|
||||
@@ -1037,7 +1045,7 @@ internal class ChatCommands
|
||||
}
|
||||
|
||||
// Kick the specified player
|
||||
AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), true);
|
||||
AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), args[0] == "/ban");
|
||||
string kickedPlayerName = kickedPlayer.GetRealName();
|
||||
string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")}";
|
||||
if (GameStates.IsInGame)
|
||||
@@ -1133,8 +1141,10 @@ internal class ChatCommands
|
||||
}
|
||||
|
||||
default:
|
||||
isCommand = false;
|
||||
break;
|
||||
}
|
||||
if (isCommand) LastSentCommand[player.PlayerId] = now;
|
||||
if (SpamManager.CheckSpam(player, text)) return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
+21
-4
@@ -594,14 +594,22 @@ class HudManagerPatch
|
||||
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)
|
||||
|
||||
var vents = Object.FindObjectsOfType<Vent>().ToArray();
|
||||
if (player.PlayerId == 0 && player.inVent && GameStates.IsInTask) SetVentButtonEnabled(TryMoveToVentPatch.HostVentTarget);
|
||||
else if (CanUseVent && vents.Any(vent => Vector2.Distance(new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f), player.Pos()) < 0.4f))
|
||||
{
|
||||
Vent vent = vents.FirstOrDefault(vent => Vector2.Distance(new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f), player.Pos()) < 0.4f);
|
||||
SetVentButtonEnabled(vent);
|
||||
}
|
||||
void SetVentButtonEnabled(Vent target)
|
||||
{
|
||||
__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);
|
||||
__instance.ImpostorVentButton.currentTarget = target;
|
||||
__instance.ImpostorVentButton.SetTarget(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -785,9 +793,18 @@ class VentButtonDoClickPatch
|
||||
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;
|
||||
if (pc.inVent || !pc.CanMove) return true;
|
||||
var vents = Object.FindObjectsOfType<Vent>().ToArray();
|
||||
if (vents.Any(vent => Vector2.Distance(new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f), pc.Pos()) < 0.4f))
|
||||
{
|
||||
Vent vent = vents.FirstOrDefault(vent => Vector2.Distance(new Vector2(vent.transform.position.x, vent.transform.position.y + 0.3636f), pc.Pos()) < 0.4f);
|
||||
pc.MyPhysics.RpcEnterVent(vent.Id);
|
||||
vent.SetButtons(true);
|
||||
return false;
|
||||
}
|
||||
pc?.MyPhysics?.RpcEnterVent(__instance.currentTarget.Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ class SetEverythingUpPatch
|
||||
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() ? defaultPos.y - 0.6f : defaultPos.y - 1.4f, -15f);
|
||||
poolablePlayer.cosmetics.nameText.transform.localPosition = new Vector3(defaultPos.x, !lowered || role.IsImpostorTeamV3() || role.IsNK() ? defaultPos.y - 0.6f : defaultPos.y - 1.4f, -15f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,12 @@ class ExternalRpcPetPatch
|
||||
Pelican.IsEaten(pc.PlayerId))
|
||||
return;
|
||||
|
||||
if (Mastermind.ManipulatedPlayers.ContainsKey(pc.PlayerId))
|
||||
{
|
||||
var killTarget = SelectKillButtonTarget(pc);
|
||||
if (killTarget != null) Mastermind.ForceKillForManipulatedPlayer(pc, killTarget);
|
||||
}
|
||||
|
||||
if (pc.HasAbilityCD()) return;
|
||||
|
||||
PlayerControl[] AllAlivePlayers = Main.AllAlivePlayerControls;
|
||||
|
||||
@@ -214,15 +214,14 @@ class CheckMurderPatch
|
||||
//非自杀场景下才会触发
|
||||
switch (killer.GetCustomRole())
|
||||
{
|
||||
//==========内鬼阵营==========//
|
||||
case CustomRoles.BountyHunter: //必须在击杀发生前处理
|
||||
case CustomRoles.BountyHunter:
|
||||
BountyHunter.OnCheckMurder(killer, target);
|
||||
break;
|
||||
case CustomRoles.Reckless:
|
||||
Reckless.OnCheckMurder(killer);
|
||||
break;
|
||||
case CustomRoles.YinYanger:
|
||||
if (YinYanger.OnCheckMurder(killer, target)) return false;
|
||||
if (!YinYanger.OnCheckMurder(killer, target)) return false;
|
||||
break;
|
||||
case CustomRoles.Magician:
|
||||
Magician.OnCheckMurder(killer);
|
||||
@@ -1395,7 +1394,7 @@ class ShapeshiftPatch
|
||||
isSSneeded = false;
|
||||
break;
|
||||
case CustomRoles.Librarian:
|
||||
if (shapeshifting) isSSneeded = Librarian.OnShapeshift(shapeshifter);
|
||||
isSSneeded = Librarian.OnShapeshift(shapeshifter, shapeshifting);
|
||||
break;
|
||||
case CustomRoles.Warlock:
|
||||
if (Main.CursedPlayers[shapeshifter.PlayerId] != null)//呪われた人がいるか確認
|
||||
@@ -1939,7 +1938,7 @@ class ReportDeadBodyPatch
|
||||
|
||||
if (player.Is(CustomRoles.Damocles))
|
||||
{
|
||||
Damocles.OnReport();
|
||||
Damocles.OnReport(player.PlayerId);
|
||||
}
|
||||
Damocles.OnMeetingStart();
|
||||
|
||||
@@ -1947,6 +1946,7 @@ class ReportDeadBodyPatch
|
||||
{
|
||||
Stressed.OnReport(player);
|
||||
}
|
||||
Stressed.OnMeetingStart();
|
||||
|
||||
if (Options.InhibitorCDAfterMeetings.GetFloat() != Options.InhibitorCD.GetFloat() || Options.SaboteurCD.GetFloat() != Options.SaboteurCDAfterMeetings.GetFloat())
|
||||
{
|
||||
@@ -2137,9 +2137,6 @@ class FixedUpdatePatch
|
||||
case CustomRoles.BountyHunter:
|
||||
BountyHunter.FixedUpdate(player);
|
||||
break;
|
||||
case CustomRoles.Tornado when !lowLoad:
|
||||
Tornado.OnFixedUpdate(player);
|
||||
break;
|
||||
case CustomRoles.Glitch when !lowLoad:
|
||||
Glitch.UpdateHackCooldown(player);
|
||||
break;
|
||||
@@ -2173,9 +2170,6 @@ class FixedUpdatePatch
|
||||
case CustomRoles.Bubble when !lowLoad:
|
||||
Bubble.OnFixedUpdate();
|
||||
break;
|
||||
case CustomRoles.Sprayer when !lowLoad:
|
||||
Sprayer.OnFixedUpdate();
|
||||
break;
|
||||
case CustomRoles.Sentinel when !lowLoad:
|
||||
Sentinel.OnFixedUpdate();
|
||||
break;
|
||||
@@ -2218,6 +2212,15 @@ class FixedUpdatePatch
|
||||
PlagueBearer.playerIdList.Remove(playerId);
|
||||
}
|
||||
|
||||
if (GameStates.IsInTask && player != null && player.IsAlive())
|
||||
{
|
||||
Druid.OnCheckPlayerPosition(player);
|
||||
Sentinel.OnCheckPlayerPosition(player);
|
||||
Tornado.OnCheckPlayerPosition(player);
|
||||
BallLightning.OnCheckPlayerPosition(player);
|
||||
Sprayer.OnCheckPlayerPosition(player);
|
||||
}
|
||||
|
||||
if (!lowLoad && Main.PlayerStates.TryGetValue(playerId, out var playerState) && GameStates.IsInTask)
|
||||
{
|
||||
if (playerState.SubRoles.Contains(CustomRoles.Damocles))
|
||||
@@ -2532,10 +2535,6 @@ class FixedUpdatePatch
|
||||
Pelican.OnFixedUpdate();
|
||||
break;
|
||||
|
||||
case CustomRoles.BallLightning:
|
||||
BallLightning.OnFixedUpdate();
|
||||
break;
|
||||
|
||||
case CustomRoles.Sapper:
|
||||
Sapper.OnFixedUpdate(player);
|
||||
break;
|
||||
@@ -2936,6 +2935,7 @@ class FixedUpdatePatch
|
||||
if (PlagueDoctor.IsEnable) Suffix.Append(PlagueDoctor.GetLowerTextOthers(seer, target));
|
||||
if (Stealth.IsEnable) Suffix.Append(Stealth.GetSuffix(seer, target));
|
||||
if (Tracker.IsEnable) Suffix.Append(Tracker.GetTrackerArrow(seer, target));
|
||||
if (Bubble.IsEnable) Suffix.Append(Bubble.GetEncasedPlayerSuffix(seer, target));
|
||||
|
||||
if (Deathpact.IsEnable)
|
||||
{
|
||||
@@ -3034,6 +3034,10 @@ class FixedUpdatePatch
|
||||
target.cosmetics.nameText.text = changeTo;
|
||||
|
||||
float offset = 0.2f;
|
||||
if (NameNotifyManager.Notice.TryGetValue(seer.PlayerId, out var notify) && notify.TEXT.Contains('\n'))
|
||||
{
|
||||
offset += 0.1f;
|
||||
}
|
||||
if (Suffix.ToString() != string.Empty)
|
||||
{
|
||||
// If the name is on two lines, the job title text needs to be moved up.
|
||||
@@ -3041,6 +3045,10 @@ class FixedUpdatePatch
|
||||
offset += 0.15f;
|
||||
target.cosmetics.nameText.text += "\r\n" + Suffix.ToString();
|
||||
}
|
||||
if (!seer.IsAlive())
|
||||
{
|
||||
offset += 0.1f;
|
||||
}
|
||||
if (isProgressTextLong)
|
||||
{
|
||||
offset += 0.3f;
|
||||
@@ -3067,14 +3075,12 @@ class FixedUpdatePatch
|
||||
{
|
||||
foreach (PlayerControl loversPlayer in Main.LoversPlayers.ToArray())
|
||||
{
|
||||
if (!loversPlayer.Data.IsDead && loversPlayer.PlayerId != deathId)
|
||||
continue;
|
||||
if (!loversPlayer.Data.IsDead && loversPlayer.PlayerId != deathId) continue;
|
||||
Main.isLoversDead = true;
|
||||
for (int i1 = 0; i1 < Main.LoversPlayers.Count; i1++)
|
||||
{
|
||||
PlayerControl partnerPlayer = Main.LoversPlayers[i1];
|
||||
if (loversPlayer.PlayerId == partnerPlayer.PlayerId)
|
||||
continue;
|
||||
if (loversPlayer.PlayerId == partnerPlayer.PlayerId) continue;
|
||||
if (partnerPlayer.PlayerId != deathId && !partnerPlayer.Data.IsDead)
|
||||
{
|
||||
if (partnerPlayer.Is(CustomRoles.Lovers))
|
||||
@@ -3125,7 +3131,7 @@ class TryMoveToVentPatch
|
||||
{
|
||||
if (__result && AmongUsClient.Instance.AmHost && PlayerControl.LocalPlayer.PlayerId == 0 && PlayerControl.LocalPlayer.inVent && (HostVentTarget.Equals(__instance) || HostVentTarget == __instance))
|
||||
{
|
||||
Logger.Info($"{__instance.name} => {otherVent.name}", "HostVentTarget");
|
||||
Logger.Info($"(Move) {__instance.name} => {otherVent.name}", "HostVentTarget");
|
||||
HostVentTarget = otherVent;
|
||||
}
|
||||
}
|
||||
@@ -3139,7 +3145,7 @@ class ExitVentPatch
|
||||
|
||||
if (pc.PlayerId == 0)
|
||||
{
|
||||
Logger.Info(__instance.name, "HostVentTarget");
|
||||
Logger.Info("(Exit) " + __instance.name, "HostVentTarget");
|
||||
TryMoveToVentPatch.HostVentTarget = __instance;
|
||||
}
|
||||
|
||||
@@ -3155,7 +3161,7 @@ class EnterVentPatch
|
||||
|
||||
if (pc.PlayerId == 0)
|
||||
{
|
||||
Logger.Info(__instance.name, "HostVentTarget");
|
||||
Logger.Info("(Enter) " + __instance.name, "HostVentTarget");
|
||||
TryMoveToVentPatch.HostVentTarget = __instance;
|
||||
}
|
||||
|
||||
@@ -3226,7 +3232,7 @@ class EnterVentPatch
|
||||
|
||||
if (pc.Is(CustomRoles.Damocles))
|
||||
{
|
||||
Damocles.OnEnterVent(__instance.Id);
|
||||
Damocles.OnEnterVent(pc.PlayerId, __instance.Id);
|
||||
}
|
||||
|
||||
switch (pc.GetCustomRole())
|
||||
|
||||
@@ -120,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;
|
||||
@@ -184,10 +187,9 @@ class RepairSystemPatch
|
||||
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
|
||||
break;
|
||||
}
|
||||
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage();
|
||||
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage(player.PlayerId);
|
||||
if (player.Is(CustomRoles.Stressed) && Stressed.countRepairSabotage) Stressed.OnRepairSabotage(player);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -197,7 +199,7 @@ class RepairSystemPatch
|
||||
case SystemTypes.Laboratory:
|
||||
case SystemTypes.HeliSabotage:
|
||||
case SystemTypes.Electrical:
|
||||
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage();
|
||||
if (player.Is(CustomRoles.Damocles) && Damocles.countRepairSabotage) Damocles.OnRepairSabotage(player.PlayerId);
|
||||
if (player.Is(CustomRoles.Stressed) && Stressed.countRepairSabotage) Stressed.OnRepairSabotage(player);
|
||||
break;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -103,10 +103,10 @@ namespace TOHE.Roles.AddOns.Crewmate
|
||||
|
||||
public static void Update(PlayerControl pc)
|
||||
{
|
||||
if (!LastUpdates.TryGetValue(pc.PlayerId, out var x) || x >= GetTimeStamp() || !Timers.ContainsKey(pc.PlayerId) || !IsEnable || !GameStates.IsInTask || !pc.IsAlive() || !pc.Is(CustomRoles.Stressed)) return;
|
||||
if (!LastUpdates.TryGetValue(pc.PlayerId, out var x) || x >= GetTimeStamp() || !Timers.ContainsKey(pc.PlayerId) || !IsEnable || !GameStates.IsInTask || !pc.Is(CustomRoles.Stressed)) return;
|
||||
LastUpdates[pc.PlayerId] = GetTimeStamp();
|
||||
|
||||
if (pc.GetPlayerTaskState().IsTaskFinished)
|
||||
if (pc.GetPlayerTaskState().IsTaskFinished || !pc.IsAlive())
|
||||
{
|
||||
Main.PlayerStates[pc.PlayerId].RemoveSubRole(CustomRoles.Stressed);
|
||||
Timers.Remove(pc.PlayerId);
|
||||
@@ -121,7 +121,7 @@ namespace TOHE.Roles.AddOns.Crewmate
|
||||
pc.Suicide();
|
||||
}
|
||||
|
||||
if (pc.IsModClient() && pc.PlayerId != 0) SendRPC(pc.PlayerId, Timers[pc.PlayerId], LastUpdates[pc.PlayerId]);
|
||||
if (pc.IsNonHostModClient()) SendRPC(pc.PlayerId, Timers[pc.PlayerId], LastUpdates[pc.PlayerId]);
|
||||
if (!pc.IsModClient()) NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
}
|
||||
|
||||
@@ -154,7 +154,6 @@ namespace TOHE.Roles.AddOns.Crewmate
|
||||
public static void AfterMeetingTasks()
|
||||
{
|
||||
if (!IsEnable) return;
|
||||
AdjustTime(TimeAfterMeeting + 9);
|
||||
countRepairSabotage = true;
|
||||
}
|
||||
|
||||
@@ -188,6 +187,12 @@ namespace TOHE.Roles.AddOns.Crewmate
|
||||
Timers[pc.PlayerId] += TimeAfterReport;
|
||||
}
|
||||
|
||||
public static void OnMeetingStart()
|
||||
{
|
||||
if (!IsEnable) return;
|
||||
AdjustTime(TimeAfterMeeting + 9);
|
||||
}
|
||||
|
||||
public static string GetProgressText(byte playerId) => Timers.TryGetValue(playerId, out var x) ? string.Format(GetString("DamoclesTimeLeft"), x) : string.Empty;
|
||||
|
||||
private static void AdjustTime(int change)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Hazel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Translator;
|
||||
using static TOHE.Utils;
|
||||
@@ -19,16 +20,16 @@ namespace TOHE.Roles.AddOns.Impostor
|
||||
private static int TimeAfterMeeting;
|
||||
private static int StartingTime;
|
||||
|
||||
public static int Timer;
|
||||
public static Dictionary<byte, int> Timer;
|
||||
|
||||
public static long lastUpdate;
|
||||
public static List<int> PreviouslyEnteredVents;
|
||||
public static Dictionary<byte, long> lastUpdate;
|
||||
public static Dictionary<byte, List<int>> PreviouslyEnteredVents;
|
||||
|
||||
public static bool countRepairSabotage;
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupAdtRoleOptions(Id, CustomRoles.Damocles, canSetNum: false);
|
||||
SetupAdtRoleOptions(Id, CustomRoles.Damocles, canSetNum: true);
|
||||
DamoclesExtraTimeAfterKill = IntegerOptionItem.Create(Id + 10, "DamoclesExtraTimeAfterKill", new(0, 60, 1), 30, TabGroup.Addons, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Damocles])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
@@ -46,109 +47,130 @@ namespace TOHE.Roles.AddOns.Impostor
|
||||
TimeAfterMeeting = DamoclesExtraTimeAfterMeeting.GetInt();
|
||||
StartingTime = DamoclesStartingTime.GetInt();
|
||||
|
||||
Timer = StartingTime;
|
||||
lastUpdate = GetTimeStamp() + 10;
|
||||
Timer = [];
|
||||
lastUpdate = [];
|
||||
PreviouslyEnteredVents = [];
|
||||
countRepairSabotage = true;
|
||||
}
|
||||
|
||||
public static void Update(PlayerControl pc)
|
||||
{
|
||||
if (lastUpdate >= GetTimeStamp() || !GameStates.IsInTask || pc == null) return;
|
||||
byte id = pc.PlayerId;
|
||||
if (lastUpdate.TryGetValue(id, out var ts) && ts >= GetTimeStamp() || !GameStates.IsInTask || pc == null) return;
|
||||
if (!pc.IsAlive())
|
||||
{
|
||||
Main.PlayerStates[pc.PlayerId].RemoveSubRole(CustomRoles.Damocles);
|
||||
Main.PlayerStates[id].RemoveSubRole(CustomRoles.Damocles);
|
||||
return;
|
||||
}
|
||||
lastUpdate = GetTimeStamp();
|
||||
lastUpdate[id] = GetTimeStamp();
|
||||
if (!Timer.ContainsKey(id)) Timer[id] = StartingTime + 8;
|
||||
|
||||
Timer--;
|
||||
Timer[id]--;
|
||||
|
||||
if (Timer < 0)
|
||||
if (Timer[id] < 0)
|
||||
{
|
||||
Timer = 0;
|
||||
Timer[id] = 0;
|
||||
pc.Suicide();
|
||||
}
|
||||
|
||||
if (pc.IsNonHostModClient()) SendRPC();
|
||||
NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
if (pc.IsNonHostModClient()) SendRPC(id);
|
||||
if (!pc.IsModClient()) NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
|
||||
}
|
||||
|
||||
public static void SendRPC()
|
||||
public static void SendRPC(byte playerId)
|
||||
{
|
||||
if (!DoRPC) return;
|
||||
MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncDamoclesTimer, SendOption.Reliable, -1);
|
||||
writer.Write(Timer);
|
||||
writer.Write(lastUpdate.ToString());
|
||||
writer.Write(PreviouslyEnteredVents.Count);
|
||||
if (PreviouslyEnteredVents.Count > 0) foreach (var vent in PreviouslyEnteredVents.ToArray()) writer.Write(vent);
|
||||
writer.Write(playerId);
|
||||
writer.Write(Timer[playerId]);
|
||||
writer.Write(lastUpdate[playerId].ToString());
|
||||
writer.Write(PreviouslyEnteredVents[playerId].Count);
|
||||
if (PreviouslyEnteredVents[playerId].Count > 0) foreach (var vent in PreviouslyEnteredVents[playerId].ToArray()) writer.Write(vent);
|
||||
AmongUsClient.Instance.FinishRpcImmediately(writer);
|
||||
}
|
||||
|
||||
public static void ReceiveRPC(MessageReader reader)
|
||||
{
|
||||
Timer = reader.ReadInt32();
|
||||
lastUpdate = long.Parse(reader.ReadString());
|
||||
byte playerId = reader.ReadByte();
|
||||
Timer[playerId] = reader.ReadInt32();
|
||||
lastUpdate[playerId] = long.Parse(reader.ReadString());
|
||||
var elements = reader.ReadInt32();
|
||||
if (elements > 0) for (int i = 0; i < elements; i++) PreviouslyEnteredVents.Add(reader.ReadInt32());
|
||||
if (elements > 0) for (int i = 0; i < elements; i++) PreviouslyEnteredVents[playerId].Add(reader.ReadInt32());
|
||||
}
|
||||
|
||||
public static void OnMurder()
|
||||
public static void OnMurder(byte id)
|
||||
{
|
||||
Timer += TimeAfterKill;
|
||||
Timer[id] += TimeAfterKill;
|
||||
}
|
||||
|
||||
public static void OnOtherImpostorMurder()
|
||||
{
|
||||
Timer += 10;
|
||||
AdjustTime(10);
|
||||
}
|
||||
|
||||
public static void OnEnterVent(int ventId)
|
||||
public static void OnEnterVent(byte id, int ventId)
|
||||
{
|
||||
if (PreviouslyEnteredVents.Contains(ventId)) return;
|
||||
if (!PreviouslyEnteredVents.ContainsKey(id)) PreviouslyEnteredVents[id] = [];
|
||||
if (PreviouslyEnteredVents[id].Contains(ventId)) return;
|
||||
|
||||
PreviouslyEnteredVents.Add(ventId);
|
||||
Timer += 10;
|
||||
PreviouslyEnteredVents[id].Add(ventId);
|
||||
Timer[id] += 10;
|
||||
}
|
||||
|
||||
public static void AfterMeetingTasks()
|
||||
{
|
||||
PreviouslyEnteredVents.Clear();
|
||||
|
||||
Timer += TimeAfterMeeting;
|
||||
AdjustTime(TimeAfterMeeting);
|
||||
countRepairSabotage = true;
|
||||
}
|
||||
|
||||
public static void OnMeetingStart()
|
||||
{
|
||||
Timer += 9;
|
||||
AdjustTime(9);
|
||||
}
|
||||
|
||||
public static void OnCrewmateEjected()
|
||||
{
|
||||
Timer = (int)Math.Round(Timer * 1.3);
|
||||
AdjustTimeByPercent(1.3);
|
||||
}
|
||||
|
||||
public static void OnRepairSabotage()
|
||||
public static void OnRepairSabotage(byte id)
|
||||
{
|
||||
Timer -= 15;
|
||||
Timer[id] -= 15;
|
||||
}
|
||||
|
||||
public static void OnImpostorDeath()
|
||||
{
|
||||
Timer -= 20;
|
||||
AdjustTime(-20);
|
||||
}
|
||||
|
||||
public static void OnReport()
|
||||
public static void OnReport(byte id)
|
||||
{
|
||||
Timer = (int)Math.Round(Timer * 0.9);
|
||||
Timer[id] = (int)Math.Round(Timer[id] * 0.9);
|
||||
}
|
||||
|
||||
public static void OnImpostorEjected()
|
||||
{
|
||||
Timer = (int)Math.Round(Timer * 0.8);
|
||||
AdjustTimeByPercent(0.8);
|
||||
}
|
||||
|
||||
public static string GetProgressText() => string.Format(GetString("DamoclesTimeLeft"), Timer);
|
||||
private static void AdjustTime(int change)
|
||||
{
|
||||
foreach (var item in Timer.Keys.ToArray())
|
||||
{
|
||||
Timer[item] += change;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AdjustTimeByPercent(double percent)
|
||||
{
|
||||
foreach (var item in Timer.Keys.ToArray())
|
||||
{
|
||||
Timer[item] = (int)Math.Round(Timer[item] * percent);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetProgressText(byte id) => string.Format(GetString("DamoclesTimeLeft"), Timer.TryGetValue(id, out var time) ? time : StartingTime);
|
||||
}
|
||||
}
|
||||
+30
-37
@@ -169,52 +169,45 @@ namespace TOHE.Roles.Crewmate
|
||||
SendRPCSyncAbilityUse(pc.PlayerId);
|
||||
}
|
||||
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsEnable || !GameStates.IsInTask || Triggers.Count <= 0 || playerIdList.Contains(pc.PlayerId)) return;
|
||||
|
||||
foreach (var triggers in Triggers.ToArray()) // Check for all Druids' traps - Most likely just 1 loop
|
||||
{
|
||||
foreach (var trigger in triggers.Value.Where(trigger => Vector2.Distance(trigger.Key, pc.Pos()) <= 1.5f)) // Check for all traps of the current Druid - Most likely 0-3 loops
|
||||
{
|
||||
GetPlayerById(triggers.Key).Notify(string.Format(GetString("DruidTriggerTriggered"), GetFormattedRoomName(trigger.Value), GetFormattedVectorText(trigger.Key)));
|
||||
Triggers[triggers.Key].Remove(trigger.Key);
|
||||
SendRPCRemoveTrigger(triggers.Key, trigger.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnFixedUpdate()
|
||||
{
|
||||
if (!IsEnable || !GameStates.IsInTask || Triggers.Count == 0 && TriggerDelays.Count == 0) return;
|
||||
if (!IsEnable || !GameStates.IsInTask || TriggerDelays.Count <= 0) return;
|
||||
|
||||
long now = GetTimeStamp();
|
||||
|
||||
if (TriggerDelays.Count > 0)
|
||||
foreach (var x in TriggerDelays.ToArray())
|
||||
{
|
||||
foreach (var x in TriggerDelays.ToArray())
|
||||
var id = x.Key;
|
||||
var pc = GetPlayerById(id);
|
||||
if (pc == null) continue;
|
||||
|
||||
if (x.Value + TriggerPlaceDelay.GetInt() < now)
|
||||
{
|
||||
var id = x.Key;
|
||||
var pc = GetPlayerById(id);
|
||||
if (pc == null) continue;
|
||||
|
||||
if (x.Value + TriggerPlaceDelay.GetInt() < now)
|
||||
{
|
||||
TriggerDelays.Remove(id);
|
||||
var (LOCATION, ROOM_NAME) = pc.GetPositionInfo();
|
||||
if (!Triggers.ContainsKey(id)) Triggers.Add(id, []);
|
||||
Triggers[id].TryAdd(LOCATION, ROOM_NAME);
|
||||
SendRPCAddTrigger(id, LOCATION, ROOM_NAME);
|
||||
continue;
|
||||
}
|
||||
|
||||
var timeLeft = TriggerPlaceDelay.GetInt() - (now - x.Value);
|
||||
if (lastUpdate < now) pc.Notify(string.Format(GetString("DruidTimeLeft"), timeLeft, 2f));
|
||||
TriggerDelays.Remove(id);
|
||||
var (LOCATION, ROOM_NAME) = pc.GetPositionInfo();
|
||||
if (!Triggers.ContainsKey(id)) Triggers.Add(id, []);
|
||||
Triggers[id].TryAdd(LOCATION, ROOM_NAME);
|
||||
SendRPCAddTrigger(id, LOCATION, ROOM_NAME);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (Triggers.Count > 0)
|
||||
{
|
||||
foreach (var pc in Main.AllAlivePlayerControls.Where(pc => !playerIdList.Contains(pc.PlayerId)).ToArray()) // Check for all alive players except Druids - Worst case scenario it's 14 loops
|
||||
{
|
||||
foreach (var triggers in Triggers.ToArray()) // Check for all Druids' traps - Most likely just 1 loop
|
||||
{
|
||||
foreach (var trigger in triggers.Value.ToArray()) // Check for all traps of the current Druid - Most likely 0-3 loops
|
||||
{
|
||||
if (Vector2.Distance(trigger.Key, pc.Pos()) <= 1.5f)
|
||||
{
|
||||
GetPlayerById(triggers.Key).Notify(string.Format(GetString("DruidTriggerTriggered"), GetFormattedRoomName(trigger.Value), GetFormattedVectorText(trigger.Key)));
|
||||
Triggers[triggers.Key].Remove(trigger.Key);
|
||||
SendRPCRemoveTrigger(triggers.Key, trigger.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var timeLeft = TriggerPlaceDelay.GetInt() - (now - x.Value);
|
||||
if (lastUpdate < now) pc.Notify(string.Format(GetString("DruidTimeLeft"), timeLeft, 2f));
|
||||
}
|
||||
|
||||
lastUpdate = now;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -24,6 +24,7 @@ public static class Medic
|
||||
public static OptionItem GuesserIgnoreShield;
|
||||
private static OptionItem AmountOfShields;
|
||||
public static OptionItem UsePet;
|
||||
public static OptionItem CD;
|
||||
|
||||
public static readonly string[] MedicWhoCanSeeProtectName =
|
||||
[
|
||||
@@ -67,6 +68,9 @@ public static class Medic
|
||||
AmountOfShields = IntegerOptionItem.Create(Id + 34, "MedicAmountOfShields", new(1, 14, 1), 1, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]);
|
||||
UsePet = Options.CreatePetUseSetting(Id + 36, CustomRoles.Medic);
|
||||
CD = FloatOptionItem.Create(Id + 38, "AbilityCooldown", new(0f, 180f, 2.5f), 7.5f, TabGroup.CrewmateRoles, false)
|
||||
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
}
|
||||
public static void Init()
|
||||
{
|
||||
@@ -124,7 +128,7 @@ public static class Medic
|
||||
public static bool CanUseKillButton(byte playerId)
|
||||
=> !Main.PlayerStates[playerId].IsDead
|
||||
&& (ProtectLimit.TryGetValue(playerId, out var x) ? x : 1) >= 1;
|
||||
public static void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = CanUseKillButton(id) ? 5f : 300f;
|
||||
public static void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = CanUseKillButton(id) ? CD.GetFloat() : 300f;
|
||||
public static string GetSkillLimit(byte playerId) => Utils.ColorString(CanUseKillButton(playerId) ? Utils.GetRoleColor(CustomRoles.Medic).ShadeColor(0.25f) : Color.gray, ProtectLimit.TryGetValue(playerId, out var protectLimit) ? $"({protectLimit})" : "Invalid");
|
||||
public static bool InProtect(byte id) => ProtectList.Contains(id) && Main.PlayerStates.TryGetValue(id, out var ps) && !ps.IsDead;
|
||||
public static void OnCheckMurderFormedicaler(PlayerControl killer, PlayerControl target)
|
||||
|
||||
+28
-12
@@ -49,22 +49,30 @@ namespace TOHE.Roles.Crewmate
|
||||
FinishPatrolling();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsPatrolling) return;
|
||||
|
||||
long now = GetTimeStamp();
|
||||
if (LastUpdate >= now) return;
|
||||
LastUpdate = now;
|
||||
|
||||
var killers = NearbyKillers;
|
||||
|
||||
foreach (var pc in Main.AllAlivePlayerControls)
|
||||
{
|
||||
bool nowInRange = killers.Any(x => x.PlayerId == pc.PlayerId);
|
||||
bool wasInRange = LastNearbyKillers.Contains(pc.PlayerId);
|
||||
bool nowInRange = killers.Any(x => x.PlayerId == pc.PlayerId);
|
||||
bool wasInRange = LastNearbyKillers.Contains(pc.PlayerId);
|
||||
|
||||
if (wasInRange && !nowInRange)
|
||||
{
|
||||
pc.Notify(GetString("KillerEscapedFromSentinel"));
|
||||
}
|
||||
if (nowInRange)
|
||||
{
|
||||
pc.Notify(string.Format(GetString("KillerNotifyPatrol"), PatrolDuration - (now - PatrolStartTimeStamp)));
|
||||
}
|
||||
if (wasInRange && !nowInRange)
|
||||
{
|
||||
pc.Notify(GetString("KillerEscapedFromSentinel"));
|
||||
LastNearbyKillers.Remove(pc.PlayerId);
|
||||
}
|
||||
if (nowInRange)
|
||||
{
|
||||
pc.Notify(string.Format(GetString("KillerNotifyPatrol"), PatrolDuration - (GetTimeStamp() - PatrolStartTimeStamp)));
|
||||
LastNearbyKillers.Add(pc.PlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,5 +179,13 @@ namespace TOHE.Roles.Crewmate
|
||||
state.Update();
|
||||
}
|
||||
}
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsEnable) return;
|
||||
foreach (PatrollingState state in PatrolStates)
|
||||
{
|
||||
state.OnCheckPlayerPosition(pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace TOHE.Roles.Crewmate
|
||||
Tornados.Add(info, now);
|
||||
SendRPCAddTornado(info.LOCATION, info.ROOM_NAME, now);
|
||||
}
|
||||
public static void OnFixedUpdate(PlayerControl tornadoPc)
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsEnable || !GameStates.IsInTask || Tornados.Count == 0) return;
|
||||
|
||||
@@ -114,10 +114,8 @@ namespace TOHE.Roles.Crewmate
|
||||
var tornadoRange = TornadoRange.GetFloat();
|
||||
var tornadoDuration = TornadoDuration.GetInt();
|
||||
|
||||
foreach (var pc in Main.AllAlivePlayerControls)
|
||||
foreach (var tornadoPc in playerIdList.Select(x => GetPlayerById(x)).Where(x => x.PlayerId != pc.PlayerId).ToArray())
|
||||
{
|
||||
if (playerIdList.Contains(pc.PlayerId)) continue;
|
||||
|
||||
foreach (var tornado in Tornados)
|
||||
{
|
||||
if (Vector2.Distance(tornado.Key.LOCATION, pc.Pos()) <= tornadoRange)
|
||||
@@ -139,11 +137,11 @@ namespace TOHE.Roles.Crewmate
|
||||
SendRPCRemoveTornado(tornado.Key.LOCATION, tornado.Key.ROOM_NAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tornadoPc == null || LastNotify >= now || !tornadoPc.Is(CustomRoles.Tornado) || tornadoPc.HasAbilityCD()) return;
|
||||
NotifyRoles(SpecifySeer: tornadoPc, SpecifyTarget: tornadoPc);
|
||||
LastNotify = now;
|
||||
if (tornadoPc == null || LastNotify >= now || !tornadoPc.Is(CustomRoles.Tornado) || tornadoPc.HasAbilityCD()) return;
|
||||
NotifyRoles(SpecifySeer: tornadoPc, SpecifyTarget: tornadoPc);
|
||||
LastNotify = now;
|
||||
}
|
||||
}
|
||||
public static string GetSuffixText(byte playerId, bool isHUD = false) => string.Join(isHUD ? "\n" : ", ", Tornados.Select(x => $"Tornado {GetFormattedRoomName(x.Key.ROOM_NAME)} {GetFormattedVectorText(x.Key.LOCATION)} ({(int)(TornadoDuration.GetInt() - (GetTimeStamp() - x.Value) + 1)}s)"));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ public static class BallLightning
|
||||
RealKiller.TryAdd(killer.PlayerId, target);
|
||||
StartConvertCountDown(target, killer);
|
||||
}
|
||||
public static void OnFixedUpdate()
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsEnable || !GameStates.IsInTask) return;
|
||||
List<byte> deList = [];
|
||||
@@ -115,7 +115,7 @@ public static class BallLightning
|
||||
deList.Add(gs.PlayerId);
|
||||
continue;
|
||||
}
|
||||
foreach (var pc in Main.AllAlivePlayerControls.Where(x => x.PlayerId != gs.PlayerId && x.IsAlive() && !x.Is(CustomRoles.BallLightning) && !IsGhost(x) && !Pelican.IsEaten(x.PlayerId)).ToArray())
|
||||
if (pc.PlayerId != gs.PlayerId && pc.IsAlive() && !pc.Is(CustomRoles.BallLightning) && !IsGhost(pc) && !Pelican.IsEaten(pc.PlayerId))
|
||||
{
|
||||
var pos = gs.transform.position;
|
||||
var dis = Vector2.Distance(pos, pc.Pos());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+23
-20
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using MS.Internal.Xml.XPath;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TOHE.Roles.Crewmate;
|
||||
@@ -33,8 +34,8 @@ namespace TOHE.Roles.Impostor
|
||||
public static OptionItem IgnorePestilence;
|
||||
public static OptionItem PositiveEffectChance;
|
||||
|
||||
public static byte EffectID = byte.MaxValue;
|
||||
public static bool isPositiveEffect;
|
||||
public static Dictionary<byte, byte> EffectID = [];
|
||||
public static Dictionary<byte, bool> isPositiveEffect = [];
|
||||
|
||||
public static Dictionary<byte, long> waitingDelayedKills = [];
|
||||
public static Dictionary<byte, long> isShielded = [];
|
||||
@@ -43,7 +44,7 @@ namespace TOHE.Roles.Impostor
|
||||
|
||||
public static void SetupCustomOption()
|
||||
{
|
||||
SetupSingleRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Gambler, 1);
|
||||
SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Gambler);
|
||||
KillCooldown = FloatOptionItem.Create(Id + 10, "KillCooldown", new(0f, 60f, 2.5f), 25f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
|
||||
.SetValueFormat(OptionFormat.Seconds);
|
||||
KillDelay = IntegerOptionItem.Create(Id + 11, "GamblerKillDelay", new(0, 10, 1), 3, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
|
||||
@@ -60,13 +61,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);
|
||||
@@ -74,17 +75,18 @@ namespace TOHE.Roles.Impostor
|
||||
IgnoreVeteranAlert = BooleanOptionItem.Create(Id + 25, "GamblerIgnoreVeteranAlert", false, TabGroup.ImpostorRoles, false).SetParent(WhatToIgnore);
|
||||
IgnorePestilence = BooleanOptionItem.Create(Id + 26, "GamblerIgnorePestilence", false, TabGroup.ImpostorRoles, false).SetParent(WhatToIgnore);
|
||||
PositiveEffectChance = IntegerOptionItem.Create(Id + 27, "GamblerPositiveEffectChance", new(0, 100, 5), 70, TabGroup.ImpostorRoles, false)
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
|
||||
.SetValueFormat(OptionFormat.Percent);
|
||||
.SetParent(CustomRoleSpawnChances[CustomRoles.Gambler])
|
||||
.SetValueFormat(OptionFormat.Percent);
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
playerIdList = [];
|
||||
EffectID = byte.MaxValue;
|
||||
EffectID = [];
|
||||
waitingDelayedKills = [];
|
||||
isSpeedChange = [];
|
||||
isVisionChange = [];
|
||||
isPositiveEffect = [];
|
||||
}
|
||||
|
||||
public static void Add(byte playerId)
|
||||
@@ -99,17 +101,17 @@ namespace TOHE.Roles.Impostor
|
||||
if (killer == null) return false;
|
||||
if (target == null) return false;
|
||||
|
||||
if (EffectID != byte.MaxValue)
|
||||
if (EffectID.TryGetValue(killer.PlayerId, out var id) && id != byte.MaxValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var rd = IRandom.Instance;
|
||||
isPositiveEffect = rd.Next(1, 101) <= PositiveEffectChance.GetInt();
|
||||
if (isPositiveEffect)
|
||||
isPositiveEffect[killer.PlayerId] = rd.Next(1, 101) <= PositiveEffectChance.GetInt();
|
||||
if (isPositiveEffect[killer.PlayerId])
|
||||
{
|
||||
EffectID = (byte)rd.Next(1, 8);
|
||||
switch (EffectID)
|
||||
EffectID[killer.PlayerId] = (byte)rd.Next(1, 8);
|
||||
switch (EffectID[killer.PlayerId])
|
||||
{
|
||||
case 1: // Delayed kill
|
||||
killer.Notify(string.Format(GetString("GamblerGet.DelayedKill"), KillDelay.GetInt()));
|
||||
@@ -153,7 +155,7 @@ namespace TOHE.Roles.Impostor
|
||||
}
|
||||
else
|
||||
{
|
||||
killer.Kill(target);
|
||||
killer.RpcCheckAndMurder(target);
|
||||
return false;
|
||||
}
|
||||
case 6: // Low KCD
|
||||
@@ -176,8 +178,8 @@ namespace TOHE.Roles.Impostor
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectID = (byte)rd.Next(1, 5);
|
||||
switch (EffectID)
|
||||
EffectID[killer.PlayerId] = (byte)rd.Next(1, 5);
|
||||
switch (EffectID[killer.PlayerId])
|
||||
{
|
||||
case 1: // BSR
|
||||
var delay = Math.Max(0.15f, BSRDelay.GetFloat());
|
||||
@@ -211,7 +213,7 @@ namespace TOHE.Roles.Impostor
|
||||
}
|
||||
}
|
||||
|
||||
EffectID = byte.MaxValue;
|
||||
EffectID[killer.PlayerId] = byte.MaxValue;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -260,8 +262,9 @@ namespace TOHE.Roles.Impostor
|
||||
|
||||
public static void OnReportDeadBody()
|
||||
{
|
||||
EffectID = byte.MaxValue;
|
||||
foreach (var playerId in waitingDelayedKills.Keys)
|
||||
EffectID.Clear();
|
||||
isPositiveEffect.Clear();
|
||||
foreach (var playerId in waitingDelayedKills.Keys.ToArray())
|
||||
{
|
||||
var pc = GetPlayerById(playerId);
|
||||
if (pc.IsAlive()) pc.Kill(pc);
|
||||
|
||||
@@ -129,6 +129,7 @@ namespace TOHE.Roles.Impostor
|
||||
|
||||
if (librarian == null) return true;
|
||||
|
||||
reporter.SetRealKiller(librarian);
|
||||
if (librarian.RpcCheckAndMurder(reporter))
|
||||
{
|
||||
sssh.Add(librarian.PlayerId);
|
||||
@@ -143,7 +144,7 @@ namespace TOHE.Roles.Impostor
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool OnShapeshift(PlayerControl pc)
|
||||
public static bool OnShapeshift(PlayerControl pc, bool shapeshifting)
|
||||
{
|
||||
if (!IsEnable) return false;
|
||||
if (pc == null) return false;
|
||||
@@ -153,7 +154,7 @@ namespace TOHE.Roles.Impostor
|
||||
isInSilencingMode[id] = (!isInSilencingMode[id].SILENCING, GetTimeStamp());
|
||||
SendRPC(id, isInSilencingMode[id].SILENCING);
|
||||
|
||||
return ShowSSAnimation.GetBool();
|
||||
return !shapeshifting || ShowSSAnimation.GetBool();
|
||||
}
|
||||
|
||||
public static void OnFixedUpdate()
|
||||
@@ -179,13 +180,9 @@ namespace TOHE.Roles.Impostor
|
||||
sssh.Clear();
|
||||
}
|
||||
|
||||
public static string GetNameTextForSuffix(byte playerId)
|
||||
{
|
||||
if (!IsEnable) return string.Empty;
|
||||
return isInSilencingMode.TryGetValue(playerId, out var x) && x.SILENCING && sssh.Contains(playerId) && GameStates.IsInTask
|
||||
public static string GetNameTextForSuffix(byte playerId) => IsEnable && isInSilencingMode.TryGetValue(playerId, out var x) && x.SILENCING && sssh.Contains(playerId) && GameStates.IsInTask
|
||||
? GetString("LibrarianNameText")
|
||||
: string.Empty;
|
||||
}
|
||||
|
||||
public static string GetSelfSuffixAndHUDText(byte playerId)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Translator;
|
||||
using static TOHE.Utils;
|
||||
@@ -59,7 +60,7 @@ namespace TOHE.Roles.Impostor
|
||||
return killer.CheckDoubleTrigger(target, () =>
|
||||
{
|
||||
killer.SetKillCooldown(time: ManipulateCD);
|
||||
if (target.HasKillButton() || target.GetPlayerTaskState().hasTasks)
|
||||
if (target.HasKillButton() || target.GetPlayerTaskState().hasTasks || UsePets.GetBool())
|
||||
{
|
||||
ManipulateDelays.TryAdd(target.PlayerId, GetTimeStamp());
|
||||
NotifyRoles(SpecifySeer: killer, SpecifyTarget: target);
|
||||
@@ -85,13 +86,13 @@ namespace TOHE.Roles.Impostor
|
||||
ManipulateDelays.Remove(x.Key);
|
||||
ManipulatedPlayers.TryAdd(x.Key, GetTimeStamp());
|
||||
|
||||
if (!pc.GetPlayerTaskState().hasTasks)
|
||||
if (!pc.GetPlayerTaskState().hasTasks || UsePets.GetBool())
|
||||
{
|
||||
TempKCDs.TryAdd(pc.PlayerId, Main.KillTimers[pc.PlayerId]);
|
||||
pc.SetKillCooldown(time: 1f);
|
||||
}
|
||||
|
||||
NotifyRoles(SpecifySeer: Mastermind_, SpecifyTarget: Mastermind_);
|
||||
NotifyRoles(SpecifySeer: Mastermind_, SpecifyTarget: pc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +116,7 @@ namespace TOHE.Roles.Impostor
|
||||
|
||||
var time = TimeLimit.GetInt() - (GetTimeStamp() - x.Value);
|
||||
|
||||
player.Notify(string.Format(GetString(player.GetPlayerTaskState().hasTasks ? "ManipulateTaskNotify" : "ManipulateNotify"), time), 1.1f);
|
||||
player.Notify(string.Format(GetString(UsePets.GetBool() ? "ManipulatePetNotify" : player.GetPlayerTaskState().hasTasks ? "ManipulateTaskNotify" : "ManipulateNotify"), time), 1.1f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +158,9 @@ namespace TOHE.Roles.Impostor
|
||||
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
killer.SetKillCooldown(time: TempKCDs.TryGetValue(killer.PlayerId, out var cd) ? cd : 0f + Main.AllPlayerKillCooldown[killer.PlayerId]);
|
||||
var kcd = TempKCDs.TryGetValue(killer.PlayerId, out var cd) ? cd : Main.AllPlayerKillCooldown.TryGetValue(killer.PlayerId, out var baseKCD) ? baseKCD : DefaultKillCooldown;
|
||||
killer.SetKillCooldown(time: kcd);
|
||||
if (killer.GetCustomRole().PetActivatedAbility()) killer.AddAbilityCD((int)Math.Round(kcd));
|
||||
TempKCDs.Remove(killer.PlayerId);
|
||||
}, 0.1f, "Set KCD for Manipulated Kill");
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace TOHE.Roles.Impostor
|
||||
public static bool OnCheckMurder(PlayerControl killer, PlayerControl target)
|
||||
{
|
||||
if (!IsEnable) return false;
|
||||
if (killer == null || target == null) return false;
|
||||
if (killer == null || target == null || !killer.Is(CustomRoles.YinYanger)) return false;
|
||||
|
||||
if (YinYangedPlayers.Count == 2)
|
||||
{
|
||||
|
||||
+58
-11
@@ -1,6 +1,9 @@
|
||||
using AmongUs.GameOptions;
|
||||
using HarmonyLib;
|
||||
using Hazel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Utils;
|
||||
|
||||
@@ -61,10 +64,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()
|
||||
@@ -72,27 +94,52 @@ namespace TOHE.Roles.Neutral
|
||||
if (!IsEnable || !GameStates.IsInTask || EncasedPlayers.Count == 0) return;
|
||||
|
||||
long now = GetTimeStamp();
|
||||
foreach (var id in EncasedPlayers.Where(item => item.Value + ExplodeDelay.GetInt() < now).Select(item => item.Key).ToArray())
|
||||
foreach (var kvp in EncasedPlayers)
|
||||
{
|
||||
var players = GetPlayersInRadius(ExplosionRadius.GetFloat(), GetPlayerById(id).Pos());
|
||||
foreach (var pc in players)
|
||||
var id = kvp.Key;
|
||||
var encasedPc = GetPlayerById(id);
|
||||
|
||||
if (kvp.Value + ExplodeDelay.GetInt() < now)
|
||||
{
|
||||
if (pc == null) continue;
|
||||
if (pc.PlayerId == BubbleId)
|
||||
if (!encasedPc.IsAlive())
|
||||
{
|
||||
if (BubbleDiesIfInRange.GetBool()) _ = new LateTask(() => { if (GameStates.IsInTask) pc.Suicide(); }, 0.2f, log: false);
|
||||
else continue;
|
||||
EncasedPlayers.Remove(id);
|
||||
SendRPC(id, remove: true);
|
||||
continue;
|
||||
}
|
||||
pc.Suicide(realKiller: Bubble_);
|
||||
var players = GetPlayersInRadius(ExplosionRadius.GetFloat(), encasedPc.Pos());
|
||||
foreach (var pc in players)
|
||||
{
|
||||
if (pc == null) continue;
|
||||
if (pc.PlayerId == BubbleId)
|
||||
{
|
||||
if (BubbleDiesIfInRange.GetBool()) _ = new LateTask(() => { if (GameStates.IsInTask) pc.Suicide(PlayerState.DeathReason.Bombed); }, 0.5f, log: false);
|
||||
continue;
|
||||
}
|
||||
pc.Suicide(PlayerState.DeathReason.Bombed, Bubble_);
|
||||
}
|
||||
EncasedPlayers.Remove(id);
|
||||
SendRPC(id, remove: true);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kvp.Value + NotifyDelay.GetInt() < now)
|
||||
{
|
||||
Main.AllAlivePlayerControls.Where(x => Vector2.Distance(x.Pos(), encasedPc.Pos()) < 5f).Do(x => NotifyRoles(SpecifySeer: x, SpecifyTarget: encasedPc));
|
||||
}
|
||||
EncasedPlayers.Remove(id);
|
||||
}
|
||||
}
|
||||
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_);
|
||||
if (!IsEnable) return;
|
||||
foreach (var pc in EncasedPlayers.Keys.Select(x => GetPlayerById(x)).Where(x => x != null && x.IsAlive())) pc.Suicide(PlayerState.DeathReason.Bombed, Bubble_);
|
||||
EncasedPlayers.Clear();
|
||||
SendRPC(clear: true);
|
||||
}
|
||||
public static string GetEncasedPlayerSuffix(PlayerControl seer, PlayerControl target)
|
||||
{
|
||||
if (!IsEnable || target == null || !EncasedPlayers.TryGetValue(target.PlayerId, out var ts) || (ts + NotifyDelay.GetInt() >= GetTimeStamp())) return string.Empty;
|
||||
return ColorString(GetRoleColor(CustomRoles.Bubble), $"{ExplodeDelay.GetInt() - (GetTimeStamp() - ts) + 1}s");
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
-11
@@ -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>";
|
||||
}
|
||||
}
|
||||
@@ -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"));
|
||||
}
|
||||
|
||||
+31
-30
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using static TOHE.Options;
|
||||
using static TOHE.Translator;
|
||||
using static TOHE.Utils;
|
||||
|
||||
namespace TOHE.Roles.Neutral
|
||||
@@ -93,56 +94,56 @@ namespace TOHE.Roles.Neutral
|
||||
public static void ReceiveRPC(MessageReader reader) => UseLimit = reader.ReadInt32();
|
||||
public static void PlaceTrap()
|
||||
{
|
||||
if (!IsEnable || Sprayer_.HasAbilityCD() || UseLimit <= 0) return;
|
||||
if (!IsEnable || UseLimit <= 0 || Sprayer_.HasAbilityCD()) return;
|
||||
|
||||
Traps.Add(Sprayer_.Pos());
|
||||
UseLimit--;
|
||||
SendRPC();
|
||||
|
||||
if (UseLimit > 0) Sprayer_.AddAbilityCD(CD.GetInt());
|
||||
|
||||
Sprayer_.Notify(GetString("SprayerNotify"));
|
||||
}
|
||||
public static void OnFixedUpdate()
|
||||
public static void OnCheckPlayerPosition(PlayerControl pc)
|
||||
{
|
||||
if (!IsEnable || !GameStates.IsInTask || Traps.Count == 0) return;
|
||||
|
||||
long now = GetTimeStamp();
|
||||
|
||||
foreach (var pc in Main.AllAlivePlayerControls)
|
||||
if (pc.PlayerId == SprayerId) return;
|
||||
|
||||
if (!LastUpdate.ContainsKey(pc.PlayerId)) LastUpdate.Add(pc.PlayerId, now);
|
||||
if (LastUpdate[pc.PlayerId] + 3 > now) return;
|
||||
LastUpdate[pc.PlayerId] = now;
|
||||
|
||||
foreach (var trap in Traps.ToArray())
|
||||
{
|
||||
if (pc.PlayerId == SprayerId) continue;
|
||||
|
||||
if (!LastUpdate.ContainsKey(pc.PlayerId)) LastUpdate.Add(pc.PlayerId, now);
|
||||
if (LastUpdate[pc.PlayerId] + 3 > now) continue;
|
||||
LastUpdate[pc.PlayerId] = now;
|
||||
|
||||
foreach (var trap in Traps.ToArray())
|
||||
if (Vector2.Distance(pc.Pos(), trap) <= 2f)
|
||||
{
|
||||
if (Vector2.Distance(pc.Pos(), trap) <= 2f)
|
||||
byte playerId = pc.PlayerId;
|
||||
var tempSpeed = Main.AllPlayerSpeed[playerId];
|
||||
Main.AllPlayerSpeed[playerId] = LoweredSpeed.GetFloat();
|
||||
LowerVisionList.Add(playerId);
|
||||
TrappedCount[playerId]++;
|
||||
if (TrappedCount[playerId] > MaxTrappedTimes.GetInt())
|
||||
{
|
||||
byte playerId = pc.PlayerId;
|
||||
var tempSpeed = Main.AllPlayerSpeed[playerId];
|
||||
Main.AllPlayerSpeed[playerId] = LoweredSpeed.GetFloat();
|
||||
LowerVisionList.Add(playerId);
|
||||
TrappedCount[playerId]++;
|
||||
if (TrappedCount[playerId] > MaxTrappedTimes.GetInt())
|
||||
pc.Suicide(realKiller: Sprayer_);
|
||||
TrappedCount.Remove(playerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
pc.MarkDirtySettings();
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
pc.Suicide(realKiller: Sprayer_);
|
||||
TrappedCount.Remove(playerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
pc.MarkDirtySettings();
|
||||
_ = new LateTask(() =>
|
||||
{
|
||||
Main.AllPlayerSpeed[playerId] = tempSpeed;
|
||||
LowerVisionList.Remove(playerId);
|
||||
if (GameStates.IsInTask) pc.MarkDirtySettings();
|
||||
}, EffectDuration.GetFloat(), "Sprayer Revert Effects");
|
||||
}
|
||||
Main.AllPlayerSpeed[playerId] = tempSpeed;
|
||||
LowerVisionList.Remove(playerId);
|
||||
if (GameStates.IsInTask) pc.MarkDirtySettings();
|
||||
}, EffectDuration.GetFloat(), "Sprayer Revert Effects");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnReportDeadBody()
|
||||
{
|
||||
Traps.Clear();
|
||||
|
||||
@@ -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);
|
||||
|
||||
+3
-2
@@ -7,7 +7,7 @@
|
||||
<Description>TOHE+</Description>
|
||||
<Authors>Gurge44</Authors>
|
||||
<langVersion>preview</langVersion>
|
||||
<AmongUs>D:\Epic Games\AmongUs</AmongUs>
|
||||
<AmongUs>E:\Program Files\AmongUs</AmongUs>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>True</Optimize>
|
||||
<AssemblyName>$(MSBuildProjectName)+</AssemblyName>
|
||||
@@ -18,6 +18,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Modules\zqihthf4.eqf~" />
|
||||
<None Remove="resources\modnews\english\TOHE+.v1.2.0.txt" />
|
||||
<None Remove="resources\modnews\english\TOHE+.v1.3.0.txt" />
|
||||
<None Remove="resources\modnews\english\TOHE+.v1.4.0.txt" />
|
||||
@@ -35,7 +36,7 @@
|
||||
<PackageReference Include="AmongUs.GameLibs.Steam" Version="2023.11.28" PrivateAssets="all" />
|
||||
<PackageReference Include="BepInEx.IL2CPP.MSBuild" Version="2.1.0-rc.1" />
|
||||
<PackageReference Include="BepInEx.Unity.IL2CPP" Version="6.0.0-be.682" Private="false" ExcludeAssets="runtime;native" />
|
||||
<PackageReference Include="Samboy063.Cpp2IL.Core" Version="2022.1.0-development.898" />
|
||||
<PackageReference Include="Samboy063.Cpp2IL.Core" Version="2022.1.0-pre-release.13" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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.1";
|
||||
public const string PluginDisplayVersion = "2.2.1";
|
||||
public const string PluginVersion = "2.2.4";
|
||||
public const string PluginDisplayVersion = "2.2.4";
|
||||
public static readonly string SupportedAUVersion = "2023.10.24";
|
||||
public const int PluginCreate = 3;
|
||||
public const bool Canary = false;
|
||||
@@ -653,84 +653,80 @@ public enum CustomRoles
|
||||
|
||||
//Impostors
|
||||
|
||||
BountyHunter,
|
||||
FireWorks,
|
||||
Mafia,
|
||||
Godfather,
|
||||
SerialKiller,
|
||||
//ShapeMaster,
|
||||
Wildling,
|
||||
EvilGuesser,
|
||||
Minimalism,
|
||||
Zombie,
|
||||
Sniper,
|
||||
Vampire,
|
||||
Witch,
|
||||
Warlock,
|
||||
Assassin,
|
||||
Undertaker,
|
||||
Vindicator,
|
||||
Hacker,
|
||||
Miner,
|
||||
Escapee,
|
||||
Inhibitor,
|
||||
Librarian,
|
||||
Chronomancer,
|
||||
Nullifier,
|
||||
Stealth,
|
||||
Penguin,
|
||||
Sapper,
|
||||
Mastermind,
|
||||
Hitman,
|
||||
RiftMaker,
|
||||
Gambler,
|
||||
Puppeteer,
|
||||
TimeThief,
|
||||
EvilTracker,
|
||||
Hacker, // Anonymous
|
||||
AntiAdminer,
|
||||
Consort,
|
||||
Sans,
|
||||
Bomber,
|
||||
Nuker,
|
||||
BoobyTrap,
|
||||
Scavenger,
|
||||
Capitalism,
|
||||
Gangster,
|
||||
Cleaner,
|
||||
BallLightning,
|
||||
Greedier,
|
||||
CursedWolf,
|
||||
ImperiusCurse,
|
||||
QuickShooter,
|
||||
Eraser,
|
||||
OverKiller,
|
||||
Hangman,
|
||||
Sans, // Arrogance
|
||||
Bard,
|
||||
Mafioso,
|
||||
Trickster,
|
||||
Swooper,
|
||||
Cantankerous,
|
||||
Duellist,
|
||||
YinYanger,
|
||||
Crewpostor,
|
||||
Parasite,
|
||||
Disperser,
|
||||
Blackmailer,
|
||||
Bomber,
|
||||
BountyHunter,
|
||||
OverKiller, // Butcher
|
||||
Camouflager,
|
||||
Saboteur,
|
||||
Capitalism,
|
||||
Cantankerous,
|
||||
Chronomancer,
|
||||
EvilDiviner, // Consigliere
|
||||
Consort,
|
||||
Councillor,
|
||||
Dazzler,
|
||||
Crewpostor,
|
||||
CursedWolf,
|
||||
Deathpact,
|
||||
Devourer,
|
||||
EvilDiviner,
|
||||
Morphling,
|
||||
Twister,
|
||||
Blackmailer,
|
||||
Disperser,
|
||||
Duellist,
|
||||
Dazzler,
|
||||
Escapee,
|
||||
Eraser,
|
||||
EvilGuesser,
|
||||
EvilTracker,
|
||||
FireWorks,
|
||||
Gambler,
|
||||
Gangster,
|
||||
Godfather,
|
||||
Greedier,
|
||||
Hangman,
|
||||
Hitman,
|
||||
Inhibitor,
|
||||
Minimalism, // Killing Machine
|
||||
BallLightning, // Lightning
|
||||
Librarian,
|
||||
Lurker,
|
||||
Convict,
|
||||
Visionary,
|
||||
Mafia,
|
||||
Mafioso,
|
||||
Mastermind,
|
||||
SerialKiller, // Mercenary
|
||||
Miner,
|
||||
Morphling,
|
||||
Assassin, // Ninja
|
||||
Nuker,
|
||||
Nullifier,
|
||||
Parasite,
|
||||
Penguin,
|
||||
Puppeteer,
|
||||
QuickShooter,
|
||||
Refugee,
|
||||
RiftMaker,
|
||||
Saboteur,
|
||||
Sapper,
|
||||
Scavenger,
|
||||
Sniper,
|
||||
ImperiusCurse, // Soul Catcher
|
||||
Swooper,
|
||||
Stealth,
|
||||
TimeThief,
|
||||
BoobyTrap, // Trapster
|
||||
Trickster,
|
||||
Twister,
|
||||
Underdog,
|
||||
// Flashbang,
|
||||
Undertaker,
|
||||
Vampire,
|
||||
Vindicator,
|
||||
Visionary,
|
||||
Warlock,
|
||||
Wildling,
|
||||
Witch,
|
||||
YinYanger,
|
||||
Zombie,
|
||||
|
||||
//Crewmates (Vanilla)
|
||||
Engineer,
|
||||
@@ -744,178 +740,169 @@ public enum CustomRoles
|
||||
|
||||
// Crewmate
|
||||
|
||||
Luckey,
|
||||
Needy,
|
||||
SuperStar,
|
||||
CyberStar,
|
||||
Demolitionist,
|
||||
Ventguard,
|
||||
Express,
|
||||
NiceEraser,
|
||||
TaskManager,
|
||||
Shiftguard,
|
||||
Mole,
|
||||
Sentinel,
|
||||
Electric,
|
||||
Philantropist,
|
||||
Tornado,
|
||||
Insight,
|
||||
Tunneler,
|
||||
Detour,
|
||||
Gaulois,
|
||||
Druid,
|
||||
Drainer,
|
||||
CameraMan,
|
||||
NiceHacker,
|
||||
Spy,
|
||||
Ricochet,
|
||||
Doormaster,
|
||||
Tether,
|
||||
Admirer,
|
||||
Addict,
|
||||
Aid,
|
||||
Benefactor,
|
||||
GuessManager,
|
||||
Escort,
|
||||
DonutDelivery,
|
||||
Alchemist,
|
||||
Altruist,
|
||||
Analyzer,
|
||||
Mayor,
|
||||
Jailor,
|
||||
Paranoia,
|
||||
Psychic,
|
||||
SabotageMaster,
|
||||
Sheriff,
|
||||
Snitch,
|
||||
Enigma,
|
||||
Marshall,
|
||||
SpeedBooster,
|
||||
Lookout,
|
||||
Autocrat,
|
||||
Benefactor,
|
||||
Bodyguard,
|
||||
CameraMan,
|
||||
CyberStar, // Celebrity
|
||||
Chameleon,
|
||||
Cleaner,
|
||||
Cleanser,
|
||||
CopyCat,
|
||||
Bloodhound, // Coroner
|
||||
Crusader,
|
||||
Demolitionist,
|
||||
Deputy,
|
||||
Detective,
|
||||
Detour,
|
||||
Dictator,
|
||||
Doctor,
|
||||
Detective,
|
||||
SwordsMan,
|
||||
NiceGuesser,
|
||||
Transporter,
|
||||
NiceSwapper,
|
||||
Altruist,
|
||||
Transmitter,
|
||||
Autocrat,
|
||||
Nightmare,
|
||||
TimeManager,
|
||||
Veteran,
|
||||
Bodyguard,
|
||||
//Counterfeiter,
|
||||
Witness,
|
||||
Grenadier,
|
||||
Lighter,
|
||||
SecurityGuard,
|
||||
Medic,
|
||||
Divinator,
|
||||
Glitch,
|
||||
Judge,
|
||||
Mortician,
|
||||
Mediumshiper,
|
||||
Observer,
|
||||
DonutDelivery,
|
||||
Doormaster,
|
||||
DovesOfNeace,
|
||||
Monarch,
|
||||
CopyCat,
|
||||
Drainer,
|
||||
Druid,
|
||||
Electric,
|
||||
Enigma,
|
||||
Escort,
|
||||
Express,
|
||||
Farseer,
|
||||
Bloodhound,
|
||||
Tracker,
|
||||
Merchant,
|
||||
//Retributionist,
|
||||
Deputy,
|
||||
Divinator, // Fortune Teller
|
||||
Gaulois,
|
||||
Glitch,
|
||||
Grenadier,
|
||||
GuessManager,
|
||||
Guardian,
|
||||
Addict,
|
||||
Alchemist,
|
||||
Tracefinder,
|
||||
Ignitor,
|
||||
Oracle,
|
||||
Spiritualist,
|
||||
Chameleon,
|
||||
ParityCop,
|
||||
Admirer,
|
||||
TimeMaster,
|
||||
Insight,
|
||||
ParityCop, // Inspector
|
||||
Jailor,
|
||||
Judge,
|
||||
Needy, // Lazy Guy
|
||||
Lighter,
|
||||
Lookout,
|
||||
Luckey,
|
||||
Marshall,
|
||||
Mayor,
|
||||
SabotageMaster, // Mechanic
|
||||
Medic,
|
||||
Mediumshiper,
|
||||
Merchant,
|
||||
Monitor,
|
||||
Crusader,
|
||||
Cleanser,
|
||||
//Reverie,
|
||||
Mole,
|
||||
Monarch,
|
||||
Mortician,
|
||||
NiceEraser,
|
||||
NiceGuesser,
|
||||
NiceHacker,
|
||||
NiceSwapper,
|
||||
Nightmare,
|
||||
Observer,
|
||||
Oracle,
|
||||
Paranoia,
|
||||
Philantropist,
|
||||
Psychic,
|
||||
Ricochet,
|
||||
Sentinel,
|
||||
SecurityGuard,
|
||||
Sheriff,
|
||||
Shiftguard,
|
||||
Snitch,
|
||||
Spiritualist,
|
||||
Speedrunner,
|
||||
SpeedBooster,
|
||||
Spy,
|
||||
SuperStar,
|
||||
TaskManager,
|
||||
Tether,
|
||||
TimeManager,
|
||||
TimeMaster,
|
||||
Tornado,
|
||||
Tracker,
|
||||
Transmitter,
|
||||
Transporter,
|
||||
Tracefinder,
|
||||
Tunneler,
|
||||
Ventguard,
|
||||
Veteran,
|
||||
SwordsMan, // Vigilante
|
||||
Witness,
|
||||
|
||||
//Neutrals
|
||||
|
||||
Arsonist,
|
||||
HexMaster,
|
||||
Jester,
|
||||
God,
|
||||
Opportunist,
|
||||
Mario,
|
||||
Terrorist,
|
||||
Executioner,
|
||||
Bandit,
|
||||
Lawyer,
|
||||
Jackal,
|
||||
Poisoner,
|
||||
//NWitch,
|
||||
Innocent,
|
||||
Pelican,
|
||||
Revolutionist,
|
||||
NSerialKiller,
|
||||
Enderman,
|
||||
Mycologist,
|
||||
Bubble,
|
||||
Hookshot,
|
||||
Sprayer,
|
||||
PlagueDoctor,
|
||||
Postman,
|
||||
Reckless,
|
||||
Magician,
|
||||
WeaponMaster,
|
||||
Eclipse,
|
||||
Pyromaniac,
|
||||
Vengeance,
|
||||
HeadHunter,
|
||||
Imitator,
|
||||
Werewolf,
|
||||
Juggernaut,
|
||||
Infectious,
|
||||
FFF,
|
||||
Konan,
|
||||
Gamer,
|
||||
DarkHide,
|
||||
Workaholic,
|
||||
Speedrunner,
|
||||
Collector,
|
||||
Agitater,
|
||||
Provocateur,
|
||||
Sunnyboy,
|
||||
BloodKnight,
|
||||
Wraith,
|
||||
Totocalcio,
|
||||
Romantic,
|
||||
VengefulRomantic,
|
||||
RuthlessRomantic,
|
||||
Succubus,
|
||||
Virus,
|
||||
Pursuer,
|
||||
Phantom,
|
||||
Jinx,
|
||||
Maverick,
|
||||
//CursedSoul,
|
||||
//Pirate,
|
||||
Ritualist,
|
||||
Doppelganger,
|
||||
Pickpocket,
|
||||
Traitor,
|
||||
Vulture,
|
||||
PlagueBearer,
|
||||
Pestilence,
|
||||
Medusa,
|
||||
Sidekick,
|
||||
//Baker,
|
||||
//Famine,
|
||||
Spiritcaller,
|
||||
Amnesiac,
|
||||
Arsonist,
|
||||
Bandit,
|
||||
BloodKnight,
|
||||
Bubble,
|
||||
Collector,
|
||||
Gamer, // Demon
|
||||
Doppelganger,
|
||||
Doomsayer,
|
||||
//Masochist,
|
||||
// Flux,
|
||||
Eclipse,
|
||||
Enderman,
|
||||
Executioner,
|
||||
Totocalcio, // Follower
|
||||
God,
|
||||
FFF, // Hater
|
||||
HeadHunter,
|
||||
HexMaster,
|
||||
Hookshot,
|
||||
Imitator,
|
||||
Infectious,
|
||||
Innocent,
|
||||
Jackal,
|
||||
Jester,
|
||||
Jinx,
|
||||
Juggernaut,
|
||||
Konan,
|
||||
Lawyer,
|
||||
Magician,
|
||||
Mario,
|
||||
Maverick,
|
||||
Medusa,
|
||||
Mycologist,
|
||||
Opportunist,
|
||||
Pelican,
|
||||
Pestilence,
|
||||
Phantom,
|
||||
Pickpocket,
|
||||
PlagueBearer,
|
||||
PlagueDoctor,
|
||||
Poisoner,
|
||||
Postman,
|
||||
Provocateur,
|
||||
Pursuer,
|
||||
Pyromaniac,
|
||||
Reckless,
|
||||
Revolutionist,
|
||||
Ritualist,
|
||||
Romantic,
|
||||
RuthlessRomantic,
|
||||
NSerialKiller, // Serial Killer
|
||||
Sidekick,
|
||||
Spiritcaller,
|
||||
Sprayer,
|
||||
DarkHide, // Stalker
|
||||
Succubus,
|
||||
Sunnyboy,
|
||||
Terrorist,
|
||||
Traitor,
|
||||
Vengeance,
|
||||
VengefulRomantic,
|
||||
Virus,
|
||||
Vulture,
|
||||
Wraith,
|
||||
Werewolf,
|
||||
WeaponMaster,
|
||||
Workaholic,
|
||||
|
||||
//SoloKombat
|
||||
KB_Normal,
|
||||
@@ -926,66 +913,67 @@ public enum CustomRoles
|
||||
//GM
|
||||
GM,
|
||||
|
||||
// ????
|
||||
Convict,
|
||||
|
||||
// Sub-role after 500
|
||||
NotAssigned = 500,
|
||||
LastImpostor,
|
||||
Lovers,
|
||||
Ntr,
|
||||
Madmate,
|
||||
Watcher,
|
||||
Flashman,
|
||||
Torch,
|
||||
Seer,
|
||||
Brakar,
|
||||
Oblivious,
|
||||
Bewilder,
|
||||
Sunglasses,
|
||||
Workhorse,
|
||||
Fool,
|
||||
Avanger,
|
||||
Youtuber,
|
||||
Egoist,
|
||||
TicketsStealer,
|
||||
DualPersonality,
|
||||
Mimic,
|
||||
Guesser,
|
||||
Necroview,
|
||||
Reach,
|
||||
Charmed,
|
||||
Bait,
|
||||
Trapper,
|
||||
Infected,
|
||||
Onbound,
|
||||
Knighted,
|
||||
Contagious,
|
||||
Cleansed,
|
||||
Unreportable,
|
||||
DeadlyQuota,
|
||||
Damocles,
|
||||
Stressed,
|
||||
Rogue,
|
||||
Lucky,
|
||||
Unlucky,
|
||||
DoubleShot,
|
||||
// Reflective,
|
||||
Rascal,
|
||||
Soulless,
|
||||
Gravestone,
|
||||
Lazy,
|
||||
Autopsy,
|
||||
Loyal,
|
||||
EvilSpirit,
|
||||
Recruit,
|
||||
Admired,
|
||||
Glow,
|
||||
Diseased,
|
||||
Antidote,
|
||||
Swift,
|
||||
Autopsy,
|
||||
Avanger,
|
||||
Bait,
|
||||
Trapper, // Beartrap
|
||||
Bewilder,
|
||||
Charmed,
|
||||
Cleansed,
|
||||
Contagious,
|
||||
Damocles,
|
||||
DeadlyQuota,
|
||||
Diseased,
|
||||
Unreportable, // Disregarded
|
||||
DoubleShot,
|
||||
Egoist,
|
||||
EvilSpirit,
|
||||
Flashman,
|
||||
Fool,
|
||||
Ghoul,
|
||||
Glow,
|
||||
Gravestone,
|
||||
Guesser,
|
||||
Infected,
|
||||
Knighted,
|
||||
LastImpostor,
|
||||
Lazy,
|
||||
Lovers,
|
||||
Loyal,
|
||||
Lucky,
|
||||
Madmate,
|
||||
Mare,
|
||||
Mimic,
|
||||
Necroview,
|
||||
Ntr, // Neptune
|
||||
Nimble,
|
||||
Oblivious,
|
||||
Onbound,
|
||||
Physicist,
|
||||
// QuickFix
|
||||
Rascal,
|
||||
Reach,
|
||||
Recruit,
|
||||
Rogue,
|
||||
DualPersonality, // Schizophrenic
|
||||
Seer,
|
||||
Soulless,
|
||||
TicketsStealer, // Stealer
|
||||
Stressed,
|
||||
Swift,
|
||||
Sunglasses,
|
||||
Brakar, // Tiebreaker
|
||||
Torch,
|
||||
Unlucky,
|
||||
Watcher,
|
||||
Workhorse,
|
||||
Youtuber
|
||||
}
|
||||
//WinData
|
||||
public enum CustomWinner
|
||||
|
||||
Reference in new issue
Block a user