Compare commits

...
12 Commits
Author SHA1 Message Date
Gurge44 730ea9afeb Fix EAC, Improve Damocles, Fix Vote Cancelling 2024-01-03 21:46:46 +01:00
Gurge44 dde672ecfc Add strings 2024-01-03 20:23:13 +01:00
Gurge44 badbc4e59a Utilize Vote Cancelling - Without any additional RPC calls 2024-01-02 21:45:36 +01:00
Gurge44 fe2e2b29af Make remaining killers text translatable 2024-01-02 20:01:10 +01:00
Gurge44 f2ccc0b5c7 Final touches 2023-12-31 19:08:01 +01:00
Gurge44 9a4d085d88 Finish 2023-12-31 17:45:56 +01:00
Gurge44 a58997385c Code Cleanup 2023-12-31 14:54:19 +01:00
Gurge44 5062355a37 Merge branch 'main' of https://github.com/Gurge44/TOHE_PLUS 2023-12-31 14:52:50 +01:00
Gurge44 4f946a8f08 Finish Pet Use as Kill Button 2023-12-31 14:52:46 +01:00
PHGaming121 0a23a35bfb Add strings to Weapon Master (#12)
* add strings

* Update WeaponMaster.cs
2023-12-31 14:51:07 +01:00
Gurge44 3a46be462a Start using pet button to kill as imp based crew roles 2023-12-30 20:17:55 +01:00
Gurge44 970281d3b1 just dont do this 2023-12-29 21:20:12 +01:00
59 changed files with 756 additions and 443 deletions

No files matched your search

+6 -2
View File
@@ -35,6 +35,7 @@ internal static class FFAManager
public static OptionItem FFA_EnableRandomAbilities;
public static OptionItem FFA_EnableRandomTwists;
public static OptionItem FFA_ShieldIsOneTimeUse;
public static OptionItem FFA_ChatDuringGame;
public static void SetupCustomOption()
{
@@ -80,6 +81,9 @@ internal static class FFAManager
FFA_ShieldIsOneTimeUse = BooleanOptionItem.Create(67_223_013, "FFA_ShieldIsOneTimeUse", true, TabGroup.GameSettings, false)
.SetGameMode(CustomGameMode.FFA)
.SetColor(new Color32(0, 255, 165, byte.MaxValue));
FFA_ChatDuringGame = BooleanOptionItem.Create(67_223_014, "FFA_ChatDuringGame", false, TabGroup.GameSettings, false)
.SetGameMode(CustomGameMode.FFA)
.SetColor(new Color32(0, 255, 165, byte.MaxValue));
}
public static void Init()
@@ -97,10 +101,10 @@ internal static class FFAManager
foreach (PlayerControl pc in Main.AllAlivePlayerControls)
{
KillCount.TryAdd(pc.PlayerId, 0);
KillCount[pc.PlayerId] = 0;
}
_ = new LateTask(Utils.SetChatVisible, 7f, "Set Chat Visible for Everyone");
if (FFA_ChatDuringGame.GetBool()) _ = new LateTask(Utils.SetChatVisible, 7f, "Set Chat Visible for Everyone");
}
private static void SendRPCSyncFFAPlayer(byte playerId)
{
+93 -129
View File
@@ -10,11 +10,12 @@ internal static class CustomRolesHelper
{
public static CustomRoles GetVNRole(this CustomRoles role)
{
bool UsePets = Options.UsePets.GetBool();
return role.IsVanilla()
? role
: role switch
{
CustomRoles.Sniper => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Sniper => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Jester => Options.JesterCanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate,
CustomRoles.Mayor => Options.MayorHasPortableButton.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate,
CustomRoles.Monitor => Monitor.CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate,
@@ -44,7 +45,7 @@ internal static class CustomRolesHelper
CustomRoles.EvilDiviner => CustomRoles.Impostor,
CustomRoles.Wildling => Wildling.CanShapeshift.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor,
CustomRoles.Morphling => CustomRoles.Shapeshifter,
CustomRoles.Warlock => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Warlock => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.SerialKiller => CustomRoles.Impostor,
CustomRoles.FireWorks => CustomRoles.Shapeshifter,
CustomRoles.SpeedBooster => CustomRoles.Crewmate,
@@ -60,9 +61,9 @@ internal static class CustomRolesHelper
CustomRoles.Nullifier => CustomRoles.Impostor,
CustomRoles.Stealth => CustomRoles.Impostor,
CustomRoles.Penguin => CustomRoles.Shapeshifter,
CustomRoles.Sapper => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Sapper => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Mastermind => CustomRoles.Impostor,
CustomRoles.RiftMaker => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.RiftMaker => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Gambler => CustomRoles.Impostor,
CustomRoles.Hitman => CustomRoles.Shapeshifter,
CustomRoles.Saboteur => CustomRoles.Impostor,
@@ -77,15 +78,15 @@ internal static class CustomRolesHelper
CustomRoles.TimeMaster => CustomRoles.Engineer,
CustomRoles.CrewmateTOHE => CustomRoles.Crewmate,
CustomRoles.Cleanser => CustomRoles.Crewmate,
CustomRoles.Miner => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Miner => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Psychic => CustomRoles.Crewmate,
CustomRoles.Needy => CustomRoles.Crewmate,
CustomRoles.Twister => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Twister => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.SuperStar => CustomRoles.Crewmate,
CustomRoles.Hacker => CustomRoles.Shapeshifter,
CustomRoles.Visionary => CustomRoles.Impostor,
CustomRoles.Assassin => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Undertaker => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Assassin => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Undertaker => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Luckey => CustomRoles.Crewmate,
CustomRoles.CyberStar => CustomRoles.Crewmate,
CustomRoles.Demolitionist => CustomRoles.Crewmate,
@@ -95,11 +96,11 @@ internal static class CustomRolesHelper
CustomRoles.TaskManager => CustomRoles.Crewmate,
CustomRoles.Shiftguard => CustomRoles.Crewmate,
CustomRoles.Mole => CustomRoles.Engineer,
CustomRoles.Sentinel => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Sentinel => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Electric => CustomRoles.Crewmate,
CustomRoles.Philantropist => CustomRoles.Crewmate,
CustomRoles.Tornado => CustomRoles.Crewmate,
CustomRoles.Druid => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Druid => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Insight => CustomRoles.Crewmate,
CustomRoles.Tunneler => CustomRoles.Crewmate,
CustomRoles.Detour => CustomRoles.Crewmate,
@@ -110,17 +111,17 @@ internal static class CustomRolesHelper
CustomRoles.Transmitter => CustomRoles.Crewmate,
CustomRoles.Autocrat => CustomRoles.Crewmate,
CustomRoles.Nightmare => CustomRoles.Crewmate,
CustomRoles.CameraMan => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.CameraMan => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Spy => CustomRoles.Crewmate,
CustomRoles.Ricochet => CustomRoles.Crewmate,
CustomRoles.Tether => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Doormaster => Options.UsePets.GetBool() ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Aid => CustomRoles.Impostor,
CustomRoles.Escort => CustomRoles.Impostor,
CustomRoles.DonutDelivery => CustomRoles.Impostor,
CustomRoles.Gaulois => CustomRoles.Impostor,
CustomRoles.Analyzer => CustomRoles.Impostor,
CustomRoles.Escapee => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Tether => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Doormaster => UsePets ? CustomRoles.Crewmate : CustomRoles.Engineer,
CustomRoles.Aid => UsePets && Aid.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
CustomRoles.Escort => UsePets && Escort.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
CustomRoles.DonutDelivery => UsePets && DonutDelivery.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
CustomRoles.Gaulois => UsePets && Gaulois.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
CustomRoles.Analyzer => UsePets && Analyzer.UsePet.GetBool() ? CustomRoles.Crewmate : CustomRoles.Impostor,
CustomRoles.Escapee => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.NiceGuesser => CustomRoles.Crewmate,
CustomRoles.EvilGuesser => CustomRoles.Impostor,
CustomRoles.Detective => CustomRoles.Crewmate,
@@ -130,8 +131,8 @@ internal static class CustomRolesHelper
CustomRoles.Mario => CustomRoles.Engineer,
CustomRoles.AntiAdminer => CustomRoles.Impostor,
CustomRoles.Sans => CustomRoles.Impostor,
CustomRoles.Bomber => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Nuker => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Bomber => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Nuker => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.BoobyTrap => CustomRoles.Impostor,
CustomRoles.Scavenger => CustomRoles.Impostor,
CustomRoles.Transporter => CustomRoles.Crewmate,
@@ -153,7 +154,7 @@ internal static class CustomRolesHelper
CustomRoles.CursedWolf => CustomRoles.Impostor,
CustomRoles.Collector => CustomRoles.Crewmate,
CustomRoles.ImperiusCurse => CustomRoles.Shapeshifter,
CustomRoles.QuickShooter => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.QuickShooter => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Eraser => CustomRoles.Impostor,
CustomRoles.OverKiller => CustomRoles.Impostor,
CustomRoles.Hangman => CustomRoles.Shapeshifter,
@@ -168,7 +169,7 @@ internal static class CustomRolesHelper
CustomRoles.Crewpostor => CustomRoles.Engineer,
CustomRoles.Observer => CustomRoles.Crewmate,
CustomRoles.DovesOfNeace => CustomRoles.Engineer,
CustomRoles.Disperser => Options.UsePets.GetBool() ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Disperser => UsePets ? CustomRoles.Impostor : CustomRoles.Shapeshifter,
CustomRoles.Camouflager => CustomRoles.Shapeshifter,
CustomRoles.Dazzler => CustomRoles.Shapeshifter,
CustomRoles.Devourer => CustomRoles.Shapeshifter,
@@ -285,6 +286,7 @@ internal static class CustomRolesHelper
public static RoleTypes GetDYRole(this CustomRoles role)
{
bool UsePets = Options.UsePets.GetBool();
return role switch
{
//SoloKombat
@@ -294,40 +296,40 @@ internal static class CustomRolesHelper
//Move And Stop
CustomRoles.Tasker => RoleTypes.Crewmate,
//Standard
CustomRoles.Sheriff => RoleTypes.Impostor,
CustomRoles.Crusader => RoleTypes.Impostor,
CustomRoles.CopyCat => RoleTypes.Impostor,
CustomRoles.Sheriff => UsePets && Sheriff.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Crusader => UsePets && Crusader.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.CopyCat => UsePets && CopyCat.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
//CustomRoles.CursedSoul => RoleTypes.Impostor,
CustomRoles.Admirer => RoleTypes.Impostor,
CustomRoles.Admirer => UsePets && Gaulois.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Refugee => RoleTypes.Impostor,
CustomRoles.Amnesiac => RoleTypes.Impostor,
CustomRoles.Agitater => RoleTypes.Impostor,
CustomRoles.Monarch => RoleTypes.Impostor,
CustomRoles.Deputy => RoleTypes.Impostor,
CustomRoles.Monarch => UsePets && Monarch.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Deputy => UsePets && Deputy.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Arsonist => RoleTypes.Impostor,
CustomRoles.Jackal => RoleTypes.Impostor,
CustomRoles.Medusa => RoleTypes.Impostor,
CustomRoles.Sidekick => RoleTypes.Impostor,
CustomRoles.SwordsMan => RoleTypes.Impostor,
CustomRoles.SwordsMan => UsePets && SwordsMan.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
//CustomRoles.Reverie => RoleTypes.Impostor,
CustomRoles.Innocent => RoleTypes.Impostor,
CustomRoles.Pelican => RoleTypes.Impostor,
//CustomRoles.Counterfeiter => RoleTypes.Impostor,
CustomRoles.Aid => RoleTypes.Impostor,
CustomRoles.Escort => RoleTypes.Impostor,
CustomRoles.DonutDelivery => RoleTypes.Impostor,
CustomRoles.Gaulois => RoleTypes.Impostor,
CustomRoles.Analyzer => RoleTypes.Impostor,
CustomRoles.Witness => RoleTypes.Impostor,
CustomRoles.Aid => UsePets && Aid.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Escort => UsePets && Escort.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.DonutDelivery => UsePets && DonutDelivery.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Gaulois => UsePets && Gaulois.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Analyzer => UsePets && Analyzer.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Witness => UsePets && Options.WitnessUsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Pursuer => RoleTypes.Impostor,
CustomRoles.Revolutionist => RoleTypes.Impostor,
CustomRoles.FFF => RoleTypes.Impostor,
CustomRoles.Medic => RoleTypes.Impostor,
CustomRoles.Medic => UsePets && Medic.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Gamer => RoleTypes.Impostor,
CustomRoles.HexMaster => RoleTypes.Impostor,
CustomRoles.Wraith => RoleTypes.Impostor,
CustomRoles.Glitch => RoleTypes.Impostor,
CustomRoles.Jailor => RoleTypes.Impostor,
CustomRoles.Jailor => UsePets && Jailor.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Juggernaut => RoleTypes.Impostor,
CustomRoles.Jinx => RoleTypes.Impostor,
CustomRoles.DarkHide => RoleTypes.Impostor,
@@ -362,7 +364,7 @@ internal static class CustomRolesHelper
CustomRoles.Succubus => RoleTypes.Impostor,
CustomRoles.Infectious => RoleTypes.Impostor,
CustomRoles.Virus => RoleTypes.Impostor,
CustomRoles.Farseer => RoleTypes.Impostor,
CustomRoles.Farseer => UsePets && Farseer.UsePet.GetBool() ? RoleTypes.GuardianAngel : RoleTypes.Impostor,
CustomRoles.Ritualist => RoleTypes.Impostor,
CustomRoles.Pickpocket => RoleTypes.Impostor,
CustomRoles.Traitor => RoleTypes.Impostor,
@@ -1000,86 +1002,6 @@ internal static class CustomRolesHelper
}
public static bool IsNeutralWithGuessAccess(this CustomRoles role)
{
return role is
//SoloKombat
CustomRoles.KB_Normal or
//FFA
CustomRoles.Killer or
//Move And Stop
CustomRoles.Tasker or
//Standard
CustomRoles.Jester or
CustomRoles.Agitater or
CustomRoles.Doppelganger or
CustomRoles.Opportunist or
CustomRoles.Bandit or
CustomRoles.Mario or
CustomRoles.HexMaster or
CustomRoles.Crewpostor or
//CustomRoles.NWitch or
CustomRoles.Wraith or
CustomRoles.Parasite or
CustomRoles.Terrorist or
CustomRoles.Executioner or
CustomRoles.Medusa or
CustomRoles.Juggernaut or
CustomRoles.Vulture or
CustomRoles.Jinx or
CustomRoles.Lawyer or
CustomRoles.Arsonist or
CustomRoles.Jackal or
CustomRoles.Sidekick or
CustomRoles.God or
CustomRoles.Innocent or
CustomRoles.Pursuer or
// CustomRoles.Sidekick or
CustomRoles.Poisoner or
CustomRoles.NSerialKiller or
CustomRoles.Enderman or
CustomRoles.Mycologist or
CustomRoles.Bubble or
CustomRoles.Hookshot or
CustomRoles.Sprayer or
CustomRoles.PlagueDoctor or
CustomRoles.Magician or
CustomRoles.WeaponMaster or
CustomRoles.Reckless or
CustomRoles.Postman or
CustomRoles.Eclipse or
CustomRoles.Pyromaniac or
CustomRoles.Vengeance or
CustomRoles.HeadHunter or
CustomRoles.Imitator or
CustomRoles.Werewolf or
CustomRoles.Pelican or
CustomRoles.Revolutionist or
CustomRoles.FFF or
CustomRoles.Traitor or
CustomRoles.Konan or
CustomRoles.Gamer or
CustomRoles.DarkHide or
CustomRoles.Infectious or
CustomRoles.Workaholic or
CustomRoles.Collector or
CustomRoles.Provocateur or
CustomRoles.Sunnyboy or
CustomRoles.Phantom or
CustomRoles.BloodKnight or
CustomRoles.Romantic or
CustomRoles.Totocalcio or
CustomRoles.VengefulRomantic or
CustomRoles.RuthlessRomantic or
CustomRoles.Virus or
CustomRoles.Succubus or
CustomRoles.Spiritcaller or
CustomRoles.Doomsayer or
CustomRoles.PlagueBearer or
//CustomRoles.Pirate or
CustomRoles.Pestilence;
}
public static bool IsEvilAddons(this CustomRoles role)
{
return role is
@@ -1104,7 +1026,7 @@ internal static class CustomRolesHelper
}
public static bool IsTasklessCrewmate(this CustomRoles role)
{
return role is
return !role.UsesPetInsteadOfKill() && role is
CustomRoles.Sheriff or
CustomRoles.Admirer or
CustomRoles.Medic or
@@ -1126,7 +1048,8 @@ internal static class CustomRolesHelper
}
public static bool PetActivatedAbility(this CustomRoles role)
{
return role is
return Options.UsePets.GetBool() && role switch
{
CustomRoles.Doormaster or
CustomRoles.Tether or
CustomRoles.Mayor or
@@ -1164,11 +1087,56 @@ internal static class CustomRolesHelper
CustomRoles.Enderman or
CustomRoles.Mycologist or
CustomRoles.Hookshot or
CustomRoles.Sprayer;
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,
_ => false,
};
}
public static bool UsesPetInsteadOfKill(this CustomRoles role)
{
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,
_ => false,
};
}
public static bool NeedUpdateOnLights(this CustomRoles role)
{
return role.IsNK() || role is
return (!role.UsesPetInsteadOfKill()) && (role.GetDYRole() != RoleTypes.GuardianAngel || role is
CustomRoles.Sheriff or
CustomRoles.Medic or
CustomRoles.CopyCat or
@@ -1252,7 +1220,7 @@ internal static class CustomRolesHelper
CustomRoles.Mare or
CustomRoles.Bandit or
CustomRoles.Agitater or
CustomRoles.Deputy;
CustomRoles.Deputy);
}
public static bool IsBetrayalAddon(this CustomRoles role)
@@ -1306,11 +1274,7 @@ internal static class CustomRolesHelper
}
public static bool CheckAddonConflictV2(CustomRoles addon, CustomRoles mainRole)
{
if (!addon.IsAdditionRole()) return false;
if (mainRole is CustomRoles.GuardianAngelTOHE or CustomRoles.God) return false;
if (mainRole is CustomRoles.GM || addon is CustomRoles.Lovers) return false;
return addon switch
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,
+87 -69
View File
@@ -1,5 +1,6 @@
using AmongUs.GameOptions;
using Hazel;
using InnerNet;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -26,43 +27,43 @@ internal class EAC
public static bool ReceiveRpc(PlayerControl pc, byte callId, MessageReader reader)
{
if (!AmongUsClient.Instance.AmHost) return false;
if (pc == null || reader == null || pc.AmOwner) return false;
if (pc == null || reader == null) return false;
try
{
MessageReader sr = MessageReader.Get(reader);
var rpc = (RpcCalls)callId;
switch (rpc)
{
case RpcCalls.SetName:
string name = sr.ReadString();
if (sr.BytesRemaining > 0 && sr.ReadBoolean()) return false;
if (
((name.Contains("<size") || name.Contains("size>")) && name.Contains('?') && !name.Contains("color")) ||
name.Length > 160 ||
name.Count(f => f.Equals("\"\\n\"")) > 3 ||
name.Count(f => f.Equals("\n")) > 3 ||
name.Count(f => f.Equals("\r")) > 3 ||
name.Contains('░') ||
name.Contains('▄') ||
name.Contains('█') ||
name.Contains('▌') ||
name.Contains('▒') ||
name.Contains("习近平")
)
{
WarnHost();
Report(pc, "非法设置游戏名称");
Logger.Fatal($"非法修改玩家【{pc.GetClientId()}:{pc.GetRealName()}】的游戏名称,已驳回", "EAC");
return true;
}
break;
//case RpcCalls.SetName:
// string name = sr.ReadString();
// if (sr.BytesRemaining > 0 && sr.ReadBoolean()) return false;
// if (
// ((name.Contains("<size") || name.Contains("size>")) && name.Contains('?') && !name.Contains("color")) ||
// name.Length > 160 ||
// name.Count(f => f.Equals("\"\\n\"")) > 3 ||
// name.Count(f => f.Equals("\n")) > 3 ||
// name.Count(f => f.Equals("\r")) > 3 ||
// name.Contains('░') ||
// name.Contains('▄') ||
// name.Contains('█') ||
// name.Contains('▌') ||
// name.Contains('▒') ||
// name.Contains("Xi Jinping")
// )
// {
// WarnHost();
// Report(pc, "Illegal setting of game name");
// Logger.Fatal($"Illegal modification of the game name of player [{pc.GetClientId()}:{pc.GetRealName()}] has been rejected", "EAC");
// return true;
// }
// break;
case RpcCalls.SetRole:
var role = (RoleTypes)sr.ReadUInt16();
if (GameStates.IsLobby && (role is RoleTypes.CrewmateGhost or RoleTypes.ImpostorGhost))
{
WarnHost();
Report(pc, "非法设置状态为幽灵");
Logger.Fatal($"非法设置玩家【{pc.GetClientId()}:{pc.GetRealName()}】的状态为幽灵,已驳回", "EAC");
Report(pc, "Illegal setting status to ghost");
Logger.Fatal($"Illegal setting of the status of player [{pc.GetClientId()}:{pc.GetRealName()}] to ghost, has been rejected", "EAC");
return true;
}
break;
@@ -75,11 +76,11 @@ internal class EAC
text.Contains('█') ||
text.Contains('▌') ||
text.Contains('▒') ||
text.Contains("习近平")
text.Contains("Xi Jinping")
)
{
Report(pc, "非法消息");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送非法消息,已驳回", "EAC");
Report(pc, "Illegal message");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] sent an illegal message, which has been rejected", "EAC");
return true;
}
break;
@@ -88,7 +89,7 @@ internal class EAC
WarnHost();
Report(pc, "Bad StartMeeting");
HandleCheat(pc, "Bad StartMeeting");
Logger.Fatal($"非法设置玩家【{pc.GetClientId()}:{pc.GetRealName()}】的游戏名称,已驳回", "EAC");
Logger.Fatal($"Illegal setting of the game name of the player [{pc.GetClientId()}:{pc.GetRealName()}] has been rejected", "EAC");
return true;
case RpcCalls.ReportDeadBody:
if (!GameStates.IsInGame)
@@ -96,7 +97,7 @@ internal class EAC
WarnHost();
Report(pc, "Report body out of game A");
HandleCheat(pc, "Report body out of game A");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非游戏内开会,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] has a non-in-game meeting and has been rejected", "EAC");
return true;
}
if (ReportTimes.TryGetValue(pc.PlayerId, out int rtimes))
@@ -106,7 +107,7 @@ internal class EAC
WarnHost();
Report(pc, "Spam report bodies A");
HandleCheat(pc, "Spam report bodies A");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】刷报告尸体满14次,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] reported corpses 14 times and has been rejected", "EAC");
return true;
}
}
@@ -119,7 +120,7 @@ internal class EAC
WarnHost();
Report(pc, "Set color in game");
HandleCheat(pc, "Set color in game");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】游戏内设置颜色,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] sets the color in the game and has been rejected", "EAC");
return true;
}
if (pc.Data.DefaultOutfit.ColorId != -1 &&
@@ -127,9 +128,9 @@ internal class EAC
|| color < 0 || color > 18))
{
WarnHost();
Report(pc, "非法设置颜色");
Report(pc, "Illegal color setting");
AmongUsClient.Instance.KickPlayer(pc.GetClientId(), false);
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置颜色,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the color and has been rejected", "EAC");
return true;
}
break;
@@ -139,7 +140,7 @@ internal class EAC
WarnHost();
Report(pc, "CheckMurder in Lobby");
HandleCheat(pc, "CheckMurder in Lobby");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法检查击杀,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally checked for kill and has been rejected", "EAC");
return true;
}
break;
@@ -147,8 +148,25 @@ internal class EAC
//If using version protocol, client should never directly send Murder player rpc
Report(pc, "Directly Murder Player");
HandleCheat(pc, "Directly Murder Player");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】直接击杀,已驳回", "EAC");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] killed directly, rejected", "EAC");
return true;
case RpcCalls.Shapeshift:
if (GameStates.IsLobby)
{
Report(pc, "ShapeShift in lobby");
HandleCheat(pc, "ShapeShift in lobby");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] lobby is deformed and has been rejected", "EAC");
return true;
}
var target = sr.ReadNetObject<PlayerControl>();
if (target == null)
{
Report(pc, "ShapeShift to null player!");
//HandleCheat(pc, "ShapeShift to null player!");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally transformed into an empty player and has been rejected", "EAC");
return true;
}
break;
}
switch (callId)
{
@@ -162,8 +180,8 @@ internal class EAC
if (!GameStates.IsLobby)
{
WarnHost();
Report(pc, "非法设置颜色");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置颜色,已驳回", "EAC");
Report(pc, "Illegal color setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the color and has been rejected", "EAC");
return true;
}
break;
@@ -172,8 +190,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置游戏名称");
Logger.Fatal($"非法修改玩家【{pc.GetClientId()}:{pc.GetRealName()}】的游戏名称,已驳回", "EAC");
Report(pc, "Illegal setting of game name");
Logger.Fatal($"Illegal modification of the game name of player [{pc.GetClientId()}:{pc.GetRealName()}] has been rejected", "EAC");
return true;
}
break;
@@ -181,8 +199,8 @@ internal class EAC
if (GameStates.IsLobby)
{
WarnHost();
Report(pc, "非法击杀");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法击杀,已驳回", "EAC");
Report(pc, "illegal kill");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally killed and has been rejected", "EAC");
return true;
}
break;
@@ -190,8 +208,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置宠物");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置宠物,已驳回", "EAC");
Report(pc, "Illegal pet setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set a pet and has been rejected", "EAC");
return true;
}
break;
@@ -199,8 +217,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置皮肤");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置皮肤,已驳回", "EAC");
Report(pc, "Illegal skin setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the skin and has been rejected", "EAC");
return true;
}
break;
@@ -208,8 +226,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置面部装扮");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置面部装扮,已驳回", "EAC");
Report(pc, "Illegal facial decoration");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set facial decoration and has been rejected", "EAC");
return true;
}
break;
@@ -217,8 +235,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置帽子");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置帽子,已驳回", "EAC");
Report(pc, "Illegal hat setting");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set a hat and has been rejected", "EAC");
return true;
}
break;
@@ -227,8 +245,8 @@ internal class EAC
if (GameStates.IsInGame)
{
WarnHost();
Report(pc, "非法设置游戏名称");
Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置名称,已驳回", "EAC");
Report(pc, "Illegal setting of game name");
Logger.Fatal($"Player [{pc.GetClientId()}:{pc.GetRealName()}] illegally set the name and has been rejected", "EAC");
return true;
}
break;
@@ -271,22 +289,22 @@ internal class EAC
WarnHost();
Report(player, "Bad Sabotage A : Non Imp");
HandleCheat(player, "Bad Sabotage A : Non Imp");
Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage A,已驳回", "EAC");
Logger.Fatal($"Player【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage A, rejected", "EAC");
return true;
}
break;
case SystemTypes.LifeSupp:
if (Mapid != 0 && Mapid != 1 && Mapid != 3) goto YesCheat;
else if (amount != 64 && amount != 65) goto YesCheat;
if (Mapid is not 0 and not 1 and not 3) goto YesCheat;
else if (amount is not 64 and not 65) goto YesCheat;
break;
case SystemTypes.Comms:
if (amount == 0)
{
if (Mapid == 1 || Mapid == 5) goto YesCheat;
if (Mapid is 1 or 5) goto YesCheat;
}
else if (amount == 64 || amount == 65 || amount == 32 || amount == 33 || amount == 16 || amount == 17)
else if (amount is 64 or 65 or 32 or 33 or 16 or 17)
{
if (!(Mapid == 1 || Mapid == 5)) goto YesCheat;
if (!(Mapid is 1 or 5)) goto YesCheat;
}
else goto YesCheat;
break;
@@ -299,16 +317,16 @@ internal class EAC
break;
case SystemTypes.Laboratory:
if (Mapid != 2) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat;
else if (!(amount is 64 or 65 or 32 or 33)) goto YesCheat;
break;
case SystemTypes.Reactor:
if (Mapid == 2 || Mapid == 4) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 32 || amount == 33)) goto YesCheat;
if (Mapid is 2 or 4) goto YesCheat;
else if (!(amount is 64 or 65 or 32 or 33)) goto YesCheat;
//Airship use heli sabotage /Other use 64,65 | 32,33
break;
case SystemTypes.HeliSabotage:
if (Mapid != 4) goto YesCheat;
else if (!(amount == 64 || amount == 65 || amount == 16 || amount == 17 || amount == 32 || amount == 33)) goto YesCheat;
else if (!(amount is 64 or 65 or 16 or 17 or 32 or 33)) goto YesCheat;
break;
case SystemTypes.MushroomMixupSabotage:
goto YesCheat;
@@ -318,7 +336,7 @@ internal class EAC
{
WarnHost();
Report(player, "Bad Sabotage D : In Meeting");
Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage D,已驳回", "EAC");
Logger.Fatal($"Player【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage D, rejected", "EAC");
return true;
}
//There may be cases where a player is fixing reactor and a meeting start, triggering EAC check in meeting
@@ -330,7 +348,7 @@ internal class EAC
WarnHost();
Report(player, "Bad Sabotage C : Hack send RPC");
HandleCheat(player, "Bad Sabotage C");
Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage C,已驳回", "EAC");
Logger.Fatal($"Player【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage C, rejected", "EAC");
return true;
}
}
@@ -353,7 +371,7 @@ internal class EAC
WarnHost();
Report(player, "Report body out of game");
HandleCheat(player, "Report body out of game");
Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】非游戏内开会,已驳回", "EAC");
Logger.Fatal($"Player [{player.GetClientId()}:{player.GetRealName()}] is not meeting in the game and has been rejected", "EAC");
return true;
}
@@ -364,13 +382,13 @@ internal class EAC
WarnHost();
Report(player, "Spam report bodies");
HandleCheat(player, "Spam report bodies");
Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】刷报告尸体满14次,已驳回", "EAC");
Logger.Fatal($"Player [{player.GetClientId()}:{player.GetRealName()}] reported corpses 14 times and has been rejected", "EAC");
return true;
}
if (GameStates.IsMeeting)
{
//Cancel rpc report body if a meeting is already held
Logger.Info($"玩家【{player.GetClientId()}:{player.GetRealName()}】在会议期间开会,已驳回", "EAC");
Logger.Info($"Player [{player.GetClientId()}:{player.GetRealName()}] held a meeting during the meeting and it has been rejected", "EAC");
return true;
}
@@ -383,7 +401,7 @@ internal class EAC
{
string msg = $"{pc.GetClientId()}|{pc.FriendCode}|{pc.Data.PlayerName}|{pc.GetClient().GetHashedPuid()}|{reason}";
//Cloud.SendData(msg);
Logger.Fatal($"EAC报告:{msg}", "EAC Cloud");
Logger.Fatal($"EAC report: {msg}", "EAC Cloud");
Logger.SendInGame(string.Format(GetString("Message.NoticeByEAC"), $"{pc?.Data?.PlayerName} | {pc.GetClient().GetHashedPuid()}", reason));
}
public static bool ReceiveInvalidRpc(PlayerControl pc, byte callId)
+19 -3
View File
@@ -202,6 +202,7 @@ static class ExtendedPlayerControl
// player.ResetKillCooldown();
//}
public static void AddKCDAsAbilityCD(this PlayerControl pc) => AddAbilityCD(pc, (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var KCD) ? KCD : Options.DefaultKillCooldown));
public static void AddAbilityCD(this PlayerControl pc, bool includeDuration = true) => Utils.AddAbilityCD(pc.GetCustomRole(), pc.PlayerId, includeDuration);
public static void AddAbilityCD(this PlayerControl pc, int CD) => Main.AbilityCD[pc.PlayerId] = (GetTimeStamp(), CD);
public static bool HasAbilityCD(this PlayerControl pc) => Main.AbilityCD.ContainsKey(pc.PlayerId);
@@ -218,6 +219,12 @@ static class ExtendedPlayerControl
public static void SetKillCooldown(this PlayerControl player, float time = -1f, PlayerControl target = null, bool forceAnime = false)
{
if (player == null) return;
if (player.GetCustomRole().PetActivatedAbility())
{
if (time == -1f) player.AddKCDAsAbilityCD();
else player.AddAbilityCD((int)Math.Round(time));
return;
}
if (!player.CanUseKillButton()) return;
player.AddKillTimerToDict(CD: time);
if (target == null) target = player;
@@ -616,8 +623,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 => !IsActive(SystemTypes.Electrical) && !IsActive(SystemTypes.Laboratory) && !IsActive(SystemTypes.Comms) && !IsActive(SystemTypes.LifeSupp) && !IsActive(SystemTypes.Reactor),
CustomRoles.Saboteur => IsActive(SystemTypes.Electrical) || IsActive(SystemTypes.Laboratory) || IsActive(SystemTypes.Comms) || IsActive(SystemTypes.LifeSupp) || IsActive(SystemTypes.Reactor),
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.Sniper => Sniper.CanUseKillButton(pc),
CustomRoles.Sheriff => Sheriff.CanUseKillButton(pc.PlayerId),
CustomRoles.Crusader => Crusader.CanUseKillButton(pc.PlayerId),
@@ -889,14 +896,23 @@ static class ExtendedPlayerControl
{
if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var kcd)) resultKCD = kcd;
else resultKCD = 0f;
if (half)
{
resultKCD /= 2f;
}
}
else
{
resultKCD = CD;
}
if (Main.KillTimers.TryGetValue(pc.PlayerId, out var timer) && timer > resultKCD) return;
if (pc.GetCustomRole().UsesPetInsteadOfKill() && resultKCD > 0f)
{
pc.AddAbilityCD((int)Math.Round(resultKCD));
}
if (Main.KillTimers.TryGetValue(pc.PlayerId, out var timer) && timer > resultKCD) return;
Main.KillTimers[pc.PlayerId] = resultKCD;
}
+12 -12
View File
@@ -39,7 +39,7 @@ static class LocateArrow
LocateArrows.Clear();
}
/// <summary>
/// 新たにターゲット矢印対象を登録
/// Register a new target arrow object
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
@@ -51,7 +51,7 @@ static class LocateArrow
LocateArrows[arrowInfo] = "・";
}
/// <summary>
/// ターゲットの削除
/// Delete target
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
@@ -65,7 +65,7 @@ static class LocateArrow
}
}
/// <summary>
/// タイプの同じターゲットの全削除
/// Delete all targets for the specified seer
/// </summary>
/// <param name="seer"></param>
public static void RemoveAllTarget(byte seer)
@@ -77,7 +77,7 @@ static class LocateArrow
}
}
/// <summary>
/// 見ることのできるすべてのターゲット矢印を取得
/// Get all visible target arrows
/// </summary>
/// <param name="seer"></param>
/// <returns></returns>
@@ -91,8 +91,8 @@ static class LocateArrow
return arrows;
}
/// <summary>
/// FixedUpdate毎にターゲット矢印を確認
/// 更新があったらNotifyRolesを発行
/// Check target arrow every FixedUpdate
/// Issue NotifyRoles when there are updates
/// </summary>
/// <param name="seer"></param>
public static void OnFixedUpdate(PlayerControl seer)
@@ -115,20 +115,20 @@ static class LocateArrow
update = true;
continue;
}
//対象の方角ベクトルを取る
// Take the direction vector of the target
var dir = loc - seer.transform.position;
int index;
if (dir.magnitude < 2)
{
//近い時はドット表示
// Display a dot when close
index = 8;
}
else
{
//-22.5~22.5度を0とするindexに変換
// 下が0度、左側が+180まで右側が-180まで
// 180度足すことで上が0度の時計回り
// 45度単位のindexにするため45/2を加算
// Convert to index with -22.5 to 22.5 degrees as 0
// Bottom is 0 degrees, left side is +180, right side is -180
// Adding 180 degrees clockwise with top being 0 degrees
// Add 45/2 to make index in 45 degree units
var angle = Vector3.SignedAngle(Vector3.down, dir, Vector3.back) + 180 + 22.5;
index = ((int)(angle / 45)) % 8;
}
+17 -2
View File
@@ -331,6 +331,7 @@ public static class Options
public static OptionItem BodyguardKillsKiller;
public static OptionItem WitnessCD;
public static OptionItem WitnessTime;
public static OptionItem WitnessUsePet;
public static OptionItem DQNumOfKillsNeeded;
public static OptionItem ParanoiaNumOfUseButton;
public static OptionItem ParanoiaVentCooldown;
@@ -370,6 +371,8 @@ public static class Options
public static OptionItem UnderdogCanKillWithMorePlayersAlive;
public static OptionItem UnderdogKillCooldownWithMorePlayersAlive;
public static OptionItem GodfatherCancelVote;
public static OptionItem NimbleCD;
public static OptionItem NimbleInVentTime;
public static OptionItem PhysicistCD;
@@ -1315,6 +1318,7 @@ public static class Options
RoleLoadingText = "Impostor roles\nGodfather";
SetupRoleOptions(555420, TabGroup.ImpostorRoles, CustomRoles.Godfather);
GodfatherCancelVote = CreateVoteCancellingUseSetting(555422, CustomRoles.Godfather, TabGroup.ImpostorRoles);
RoleLoadingText = "Impostor roles\nMorphling";
Morphling.SetupCustomOption();
RoleLoadingText = "Impostor roles\nNemesis";
@@ -1790,6 +1794,7 @@ public static class Options
WitnessTime = IntegerOptionItem.Create(8553, "WitnessTime", new(0, 90, 1), 10, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Witness])
.SetValueFormat(OptionFormat.Seconds);
WitnessUsePet = CreatePetUseSetting(8554, CustomRoles.Witness);
RoleLoadingText = "Crewmate roles\nVigilante";
SwordsMan.SetupCustomOption();
//Reverie.SetupCustomOption();
@@ -2737,7 +2742,7 @@ public static class Options
RemovePetsAtDeadPlayers = BooleanOptionItem.Create(60294, "RemovePetsAtDeadPlayers", false, TabGroup.SystemSettings, false)
.SetColor(Color.magenta);
CheatResponses = StringOptionItem.Create(19319, "CheatResponses", CheatResponsesName, 0, TabGroup.SystemSettings, false)
CheatResponses = StringOptionItem.Create(19319, "CheatResponses", CheatResponsesName, 2, TabGroup.SystemSettings, false)
.SetHeader(true);
//HighLevelAntiCheat = StringOptionItem.Create(19320, "HighLevelAntiCheat", CheatResponsesName, 0, TabGroup.SystemSettings, false)
@@ -3735,6 +3740,16 @@ public static class Options
.SetParent(CustomRoleSpawnChances[role])
.SetValueFormat(OptionFormat.Seconds);
public static OptionItem CreatePetUseSetting(int id, CustomRoles role) =>
BooleanOptionItem.Create(id, "UsePetInsteadOfKillButton", false, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[role])
.SetColor(Color.magenta);
public static OptionItem CreateVoteCancellingUseSetting(int id, CustomRoles role, TabGroup tab) =>
BooleanOptionItem.Create(id, "UseVoteCancellingAfterVote", false, tab, false)
.SetParent(CustomRoleSpawnChances[role])
.SetColor(Color.yellow);
public class OverrideTasksData
{
public static Dictionary<CustomRoles, OverrideTasksData> AllData = [];
@@ -3768,7 +3783,7 @@ public static class Options
numShortTasks.ReplacementDictionary = replacementDic;
if (!AllData.ContainsKey(role)) AllData.Add(role, this);
else Logger.Warn("重複したCustomRolesを対象とするOverrideTasksDataが作成されました", "OverrideTasksData");
else Logger.Warn("OverrideTasksData created for duplicate CustomRoles", "OverrideTasksData");
}
public static OverrideTasksData Create(int idStart, TabGroup tab, CustomRoles role) => new(idStart, tab, role);
}
+12 -12
View File
@@ -40,7 +40,7 @@ static class TargetArrow
TargetArrows.Clear();
}
/// <summary>
/// 新たにターゲット矢印対象を登録
/// Register a new target arrow object
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
@@ -52,7 +52,7 @@ static class TargetArrow
TargetArrows[arrowInfo] = "・";
}
/// <summary>
/// ターゲットの削除
/// Delete target
/// </summary>
/// <param name="seer"></param>
/// <param name="target"></param>
@@ -66,7 +66,7 @@ static class TargetArrow
}
}
/// <summary>
/// タイプの同じターゲットの全削除
/// Delete all targets for the specified seer
/// </summary>
/// <param name="seer"></param>
public static void RemoveAllTarget(byte seer)
@@ -78,7 +78,7 @@ static class TargetArrow
}
}
/// <summary>
/// 見ることのできるすべてのターゲット矢印を取得
/// Get all visible target arrows
/// </summary>
/// <param name="seer"></param>
/// <returns></returns>
@@ -92,8 +92,8 @@ static class TargetArrow
return arrows;
}
/// <summary>
/// FixedUpdate毎にターゲット矢印を確認
/// 更新があったらNotifyRolesを発行
/// Check target arrow every FixedUpdate
/// Issue NotifyRoles when there are updates
/// </summary>
/// <param name="seer"></param>
public static void OnFixedUpdate(PlayerControl seer)
@@ -117,20 +117,20 @@ static class TargetArrow
update = true;
continue;
}
//対象の方角ベクトルを取る
// Take the direction vector of the target
var dir = target.transform.position - seer.transform.position;
int index;
if (dir.magnitude < 2)
{
//近い時はドット表示
// Display a dot when close
index = 8;
}
else
{
//-22.5~22.5度を0とするindexに変換
// 下が0度、左側が+180まで右側が-180まで
// 180度足すことで上が0度の時計回り
// 45度単位のindexにするため45/2を加算
// Convert to index with -22.5 to 22.5 degrees as 0
// Bottom is 0 degrees, left side is +180, right side is -180
// Adding 180 degrees clockwise with top being 0 degrees
// Add 45/2 to make index in 45 degree units
var angle = Vector3.SignedAngle(Vector3.down, dir, Vector3.back) + 180 + 22.5;
index = ((int)(angle / 45)) % 8;
}
+40 -17
View File
@@ -490,7 +490,7 @@ public static class Utils
switch (role)
{
case CustomRoles.GM:
case CustomRoles.Sheriff:
case CustomRoles.Sheriff when !Options.UsePets.GetBool() || !Sheriff.UsePet.GetBool():
case CustomRoles.Arsonist:
case CustomRoles.Jackal:
case CustomRoles.Sidekick:
@@ -514,7 +514,7 @@ public static class Utils
case CustomRoles.Imitator:
case CustomRoles.Werewolf:
case CustomRoles.Bandit:
case CustomRoles.Jailor:
case CustomRoles.Jailor when !Options.UsePets.GetBool() || !Jailor.UsePet.GetBool():
case CustomRoles.Traitor:
case CustomRoles.Glitch:
case CustomRoles.Pickpocket:
@@ -522,7 +522,7 @@ public static class Utils
case CustomRoles.Jinx:
case CustomRoles.Parasite:
case CustomRoles.Agitater:
case CustomRoles.Crusader:
case CustomRoles.Crusader when !Options.UsePets.GetBool() || !Crusader.UsePet.GetBool():
case CustomRoles.Refugee:
case CustomRoles.Jester:
//case CustomRoles.Pirate:
@@ -532,7 +532,7 @@ public static class Utils
case CustomRoles.Mario:
case CustomRoles.Vulture:
case CustomRoles.God:
case CustomRoles.SwordsMan:
case CustomRoles.SwordsMan when !Options.UsePets.GetBool() || !SwordsMan.UsePet.GetBool():
case CustomRoles.Innocent:
case CustomRoles.Pelican:
case CustomRoles.Medusa:
@@ -549,7 +549,7 @@ public static class Utils
case CustomRoles.Collector:
case CustomRoles.ImperiusCurse:
case CustomRoles.Provocateur:
case CustomRoles.Medic:
case CustomRoles.Medic when !Options.UsePets.GetBool() || !Medic.UsePet.GetBool():
case CustomRoles.BloodKnight:
case CustomRoles.Camouflager:
case CustomRoles.Totocalcio:
@@ -558,20 +558,20 @@ public static class Utils
case CustomRoles.RuthlessRomantic:
case CustomRoles.Succubus:
//case CustomRoles.CursedSoul:
case CustomRoles.Admirer:
case CustomRoles.Admirer when !Options.UsePets.GetBool() || !Admirer.UsePet.GetBool():
case CustomRoles.Amnesiac:
case CustomRoles.Infectious:
case CustomRoles.Monarch:
case CustomRoles.Deputy:
case CustomRoles.Monarch when !Options.UsePets.GetBool() || !Monarch.UsePet.GetBool():
case CustomRoles.Deputy when !Options.UsePets.GetBool() || !Deputy.UsePet.GetBool():
case CustomRoles.Virus:
case CustomRoles.Farseer:
case CustomRoles.Farseer when !Options.UsePets.GetBool() || !Farseer.UsePet.GetBool():
//case CustomRoles.Counterfeiter:
case CustomRoles.Aid:
case CustomRoles.Escort:
case CustomRoles.DonutDelivery:
case CustomRoles.Gaulois:
case CustomRoles.Analyzer:
case CustomRoles.Witness:
case CustomRoles.Aid when !Options.UsePets.GetBool() || !Aid.UsePet.GetBool():
case CustomRoles.Escort when !Options.UsePets.GetBool() || !Escort.UsePet.GetBool():
case CustomRoles.DonutDelivery when !Options.UsePets.GetBool() || !DonutDelivery.UsePet.GetBool():
case CustomRoles.Gaulois when !Options.UsePets.GetBool() || !Gaulois.UsePet.GetBool():
case CustomRoles.Analyzer when !Options.UsePets.GetBool() || !Analyzer.UsePet.GetBool():
case CustomRoles.Witness when !Options.UsePets.GetBool() || !Options.WitnessUsePet.GetBool():
case CustomRoles.Pursuer:
case CustomRoles.Spiritcaller:
case CustomRoles.PlagueBearer:
@@ -623,7 +623,7 @@ public static class Utils
}
}
if (CopyCat.playerIdList.Contains(p.PlayerId) && ForRecompute) hasTasks = false;
if (CopyCat.playerIdList.Contains(p.PlayerId) && ForRecompute && (!Options.UsePets.GetBool() || CopyCat.UsePet.GetBool())) hasTasks = false;
return hasTasks;
}
@@ -2549,6 +2549,11 @@ public static class Utils
}
public static void AddAbilityCD(CustomRoles role, byte playerId, bool includeDuration = true)
{
if (role.UsesPetInsteadOfKill())
{
Main.AbilityCD[playerId] = (GetTimeStamp(), (int)Math.Round(Main.AllPlayerKillCooldown.TryGetValue(playerId, out var KCD) ? KCD : Options.DefaultKillCooldown));
return;
}
int CD = role switch
{
CustomRoles.Doormaster => Doormaster.VentCooldown.GetInt(),
@@ -2650,6 +2655,8 @@ public static class Utils
if (Options.AirshipVariableElectrical.GetBool())
AirshipElectricalDoors.Initialize();
Main.DontCancelVoteList.Clear();
DoorsReset.ResetDoors();
KeepProtection.ProtectEveryone();
@@ -2891,7 +2898,23 @@ public static class Utils
neutralnum++;
}
}
return $"{(notify ? "<color=#777777>" : string.Empty)}There {(impnum == 1 ? "is" : "are")}{(notify ? ' ' : '\n')}{(notify ? "<#ffffff>" : "<b>")}{impnum}{(notify ? "</color>" : "</b>")} <color=#ff1919>{(impnum == 1 ? "Impostor" : "Impostors")}</color> and {(notify ? "<#ffffff>" : "<b>")}{neutralnum}{(notify ? "</color>" : "</b>")} <color=#ffab1b>{(neutralnum == 1 ? "Neutral Killer" : "Neutral Killers")}</color> left.{(notify ? "</color>" : string.Empty)}";
return (notify ? "<#777777>" : string.Empty) +
(impnum == 1 ? GetString("RemainingText.Prefix.SingleImp") : GetString("RemainingText.Prefix.PluralImp")) +
(notify ? " " : "\n") +
(notify ? "<#ffffff>" : "<b>") +
impnum +
(notify ? "</color>" : "</b>") +
" " +
$"<#ff1919>{(impnum == 1 ? GetString("RemainingText.ImpSingle") : GetString("RemainingText.ImpPlural"))}</color>" +
" & " +
(notify ? "<#ffffff>" : "<b>") +
neutralnum +
(notify ? "</color>" : "</b>") +
" " +
$"<#ffab1b>{(neutralnum == 1 ? GetString("RemainingText.NKSingle") : GetString("RemainingText.NKPlural"))}</color>" +
GetString("RemainingText.Suffix") +
"." +
(notify ? "</color>" : string.Empty);
}
public static string RemoveHtmlTagsTemplate(this string str) => Regex.Replace(str, string.Empty, string.Empty);
public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", string.Empty);
+2 -1
View File
@@ -11,7 +11,6 @@ using TOHE.Modules;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Impostor;
using UnityEngine;
using UnityEngine.UI;
using static TOHE.Translator;
@@ -33,7 +32,9 @@ internal class ChatCommands
public static bool Prefix(ChatController __instance)
{
if (__instance.quickChatField.visible) return true;
if (__instance.freeChatField.textArea.text == string.Empty) return false;
if (!GameStates.IsModHost && !AmongUsClient.Instance.AmHost) return true;
__instance.timeSinceLastMessage = 3f;
var text = __instance.freeChatField.textArea.text;
+2 -1
View File
@@ -47,7 +47,7 @@ class ChatControllerUpdatePatch
}
}
public class ChatManager
public static class ChatManager
{
public static bool cancel;
private static readonly List<string> chatHistory = [];
@@ -152,6 +152,7 @@ public class ChatManager
public static void SendPreviousMessagesToAll(bool realMessagesOnly = false)
{
if (!AmongUsClient.Instance.AmHost || !GameStates.IsModHost) return;
ChatUpdatePatch.DoBlockChat = true;
string msg = Utils.EmptyMessage();
List<CustomRoles> roles = Enum.GetValues(typeof(CustomRoles)).Cast<CustomRoles>().Where(x => x is not CustomRoles.KB_Normal and not CustomRoles.Killer and not CustomRoles.Tasker).ToList();
+3 -1
View File
@@ -40,7 +40,9 @@ class GameEndChecker
//ゲーム終了時
if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default)
{
//カモフラージュ強制解除
NameNotifyManager.Reset();
NotifyRoles(ForceLoop: true);
Main.AllPlayerControls.Do(pc => Camouflage.RpcSetSkin(pc, ForceRevert: true, RevertToDefault: true));
if (reason == GameOverReason.ImpostorBySabotage && (CustomRoles.Jackal.RoleExist() || CustomRoles.Sidekick.RoleExist()) && Jackal.CanWinBySabotageWhenNoImpAlive.GetBool() && !Main.AllAlivePlayerControls.Any(x => x.GetCustomRole().IsImpostorTeam()))
+12 -2
View File
@@ -101,10 +101,20 @@ internal class InnerNetClientCanBanPatch
[HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.KickPlayer))]
internal class KickPlayerPatch
{
public static void Prefix(InnerNetClient __instance, int clientId, bool ban)
public static bool Prefix(InnerNetClient __instance, int clientId, bool ban)
{
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost) return true;
if (AmongUsClient.Instance.ClientId == clientId)
{
Logger.SendInGame(string.Format("Game Attempting to {0} Host, Blocked the attempt.", ban ? "Ban" : "Kick"));
Logger.Info("Game attempted to kick/ban host....", "KickPlayerPatch");
return false;
}
if (ban) BanManager.AddBanPlayer(AmongUsClient.Instance.GetRecentClient(clientId));
return true;
}
}
[HarmonyPatch(typeof(ResolutionManager), nameof(ResolutionManager.SetResolution))]
+1 -1
View File
@@ -580,7 +580,7 @@ class HudManagerPatch
LowerInfoText.enabled = false;
}
if (player.CanUseKillButton())
if (player.CanUseKillButton() && !player.GetCustomRole().UsesPetInsteadOfKill())
{
__instance.KillButton?.ToggleVisible(player.IsAlive() && GameStates.IsInTask);
player.Data.Role.CanUseKillButton = true;
+6 -2
View File
@@ -512,8 +512,12 @@ class IntroCutsceneDestroyPatch
{
if (Main.NormalOptions.MapId != 4)
{
Main.AllPlayerControls.Do(pc => pc.RpcResetAbilityCooldown());
Main.AllPlayerControls.Do(pc => pc.AddAbilityCD());
foreach (var pc in Main.AllAlivePlayerControls)
{
pc.RpcResetAbilityCooldown();
if (pc.GetCustomRole().UsesPetInsteadOfKill()) pc.AddAbilityCD(10);
else pc.AddAbilityCD();
}
if (Options.StartingKillCooldown.GetInt() != 10 && Options.StartingKillCooldown.GetInt() > 0)
{
_ = new LateTask(() =>
+93 -44
View File
@@ -87,40 +87,36 @@ class CheckForEndVotingPatch
{
switch (pc.GetCustomRole())
{
case CustomRoles.Divinator:
case CustomRoles.Divinator when !Divinator.CancelVote.GetBool():
Divinator.OnVote(pc, voteTarget);
break;
case CustomRoles.Oracle:
case CustomRoles.Oracle when !Oracle.CancelVote.GetBool():
Oracle.OnVote(pc, voteTarget);
break;
case CustomRoles.Eraser:
case CustomRoles.Eraser when !Eraser.CancelVote.GetBool():
Eraser.OnVote(pc, voteTarget);
break;
case CustomRoles.Tether:
case CustomRoles.Tether when !Tether.CancelVote.GetBool():
Tether.OnVote(pc, voteTarget);
break;
case CustomRoles.Ricochet:
case CustomRoles.Ricochet when !Ricochet.CancelVote.GetBool():
Ricochet.OnVote(pc, voteTarget);
break;
case CustomRoles.Cleanser:
case CustomRoles.Cleanser when !Cleanser.CancelVote.GetBool():
Cleanser.OnVote(pc, voteTarget);
break;
//case CustomRoles.Jailor:
// Jailor.OnVote(pc, voteTarget);
// break;
case CustomRoles.NiceEraser:
case CustomRoles.NiceEraser when !NiceEraser.CancelVote.GetBool():
NiceEraser.OnVote(pc, voteTarget);
break;
case CustomRoles.Tracker:
case CustomRoles.Tracker when !Tracker.CancelVote.GetBool():
Tracker.OnVote(pc, voteTarget);
break;
case CustomRoles.Godfather:
if (pc == null || voteTarget == null) break;
case CustomRoles.Godfather when !Options.GodfatherCancelVote.GetBool():
Main.GodfatherTarget = voteTarget.PlayerId;
break;
}
}
else if (pc.GetCustomRole() == CustomRoles.Godfather) Main.GodfatherTarget = byte.MaxValue;
else if (pc.Is(CustomRoles.Godfather)) Main.GodfatherTarget = byte.MaxValue;
}
}
for (int i = 0; i < __instance.playerStates.Count; i++)
@@ -408,19 +404,16 @@ class CheckForEndVotingPatch
var role = GetString(exiledPlayer.GetCustomRole().ToString());
var crole = exiledPlayer.GetCustomRole();
var coloredRole = Utils.GetDisplayRoleName(exileId, true);
if (Options.ConfirmEgoistOnEject.GetBool() && player.Is(CustomRoles.Egoist))
coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Egoist), GetRoleString("Temp.Blank") + coloredRole.RemoveHtmlTags());
// if (Options.ConfirmSidekickOnEject.GetBool() && player.Is(CustomRoles.Sidekick))
// coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Sidekick), GetRoleString("Temp.Blank") + coloredRole.RemoveHtmlTags());
if (Options.ConfirmLoversOnEject.GetBool() && player.Is(CustomRoles.Lovers))
coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lovers), GetRoleString("Temp.Blank") + coloredRole.RemoveHtmlTags());
if (Options.RascalAppearAsMadmate.GetBool() && player.Is(CustomRoles.Rascal))
coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Madmate), GetRoleString("Mad-") + coloredRole.RemoveHtmlTags());
if (Options.ConfirmEgoistOnEject.GetBool() && player.Is(CustomRoles.Egoist)) coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Egoist), GetRoleString("Temp.Blank") + coloredRole.RemoveHtmlTags());
if (Options.ConfirmLoversOnEject.GetBool() && player.Is(CustomRoles.Lovers)) coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Lovers), GetRoleString("Temp.Blank") + coloredRole.RemoveHtmlTags());
if (Options.RascalAppearAsMadmate.GetBool() && player.Is(CustomRoles.Rascal)) coloredRole = Utils.ColorString(Utils.GetRoleColor(CustomRoles.Madmate), GetRoleString("Mad-") + coloredRole.RemoveHtmlTags());
var name = string.Empty;
int impnum = 0;
int neutralnum = 0;
if (CustomRolesHelper.RoleExist(CustomRoles.Bard))
if (CustomRoles.Bard.RoleExist())
{
Main.BardCreations++;
try { name = ModUpdater.Get("https://v1.hitokoto.cn/?encode=text"); }
@@ -500,18 +493,18 @@ class CheckForEndVotingPatch
case (0, 0): // Crewmates win
name += GetString("GG");
break;
case ( > 0, > 0): // Both imps and neutrals remain
case (> 0, > 0): // Both imps and neutrals remain
name += impnum switch
{
1 => "1 <color=#ff1919>Impostor</color> <color=#777777>&</color> ",
2 => "2 <color=#ff1919>Impostors</color> <color=#777777>&</color> ",
3 => "3 <color=#ff1919>Impostors</color> <color=#777777>&</color> ",
1 => $"1 <color=#ff1919>{GetString("RemainingText.ImpSingle")}</color> <color=#777777>&</color> ",
2 => $"2 <color=#ff1919>{GetString("RemainingText.ImpPlural")}</color> <color=#777777>&</color> ",
3 => $"3 <color=#ff1919>{GetString("RemainingText.ImpPlural")}</color> <color=#777777>&</color> ",
_ => string.Empty,
};
if (neutralnum == 1) name += "1 <color=#ffab1b>Neutral</color> <color=#777777>remains.</color>";
else name += $"{neutralnum} <color=#ffab1b>Neutrals</color> <color=#777777>remain.</color>";
if (neutralnum == 1) name += $"1 <color=#ffab1b>{GetString("RemainingText.NKSingle")}</color> <color=#777777>{GetString("RemainingText.EjectionSuffix.NKSingle")}</color>";
else name += $"{neutralnum} <color=#ffab1b>{GetString("RemainingText.NKPlural")}</color> <color=#777777>{GetString("RemainingText.EjectionSuffix.NKPlural")}</color>";
break;
case ( > 0, 0): // Only imps remain
case (> 0, 0): // Only imps remain
name += impnum switch
{
1 => GetString("OneImpRemain"),
@@ -1336,11 +1329,9 @@ class MeetingHudOnDestroyPatch
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.CastVote))]
class MeetingHudCastVotePatch
{
public static bool Prefix()
{
return true; // return false to use the vote as a trigger
}
public static void Postfix(MeetingHud __instance, [HarmonyArgument(0)] byte srcPlayerId, [HarmonyArgument(1)] byte suspectPlayerId)
private static readonly Dictionary<byte, (MeetingHud MEETING_HUD, PlayerVoteArea SOURCE_PLAYER_VOTE_AREA, PlayerControl SOURCE_PLAYER)> ShouldCancelVoteList = [];
public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)] byte srcPlayerId, [HarmonyArgument(1)] byte suspectPlayerId)
{
PlayerVoteArea pva_src = null;
PlayerVoteArea pva_target = null;
@@ -1353,7 +1344,7 @@ class MeetingHudCastVotePatch
if (pva_src == null)
{
Logger.Error("Src PlayerVoteArea not found", "MeetingHudCastVotePatch.Prefix");
return;
return true;
}
if (pva_target == null)
{
@@ -1365,7 +1356,7 @@ class MeetingHudCastVotePatch
if (pc_src == null)
{
Logger.Error("Src PlayerControl is null", "MeetingHudCastVotePatch.Prefix");
return;
return true;
}
if (pc_target == null)
{
@@ -1373,21 +1364,79 @@ class MeetingHudCastVotePatch
isSkip = true;
}
Logger.Info($"{pc_src.GetNameWithRole().RemoveHtmlTags()} => {(isSkip ? "Skip" : pc_target.GetNameWithRole().RemoveHtmlTags())}", "Vote");
bool isVoteCanceled = false;
//pva_src.UnsetVote(); // Uncomment to use the vote as a trigger
//__instance.RpcClearVote(pc_src.GetClientId()); // Uncomment to use the vote as a trigger
if (!Main.DontCancelVoteList.Contains(srcPlayerId))
{
if (!isSkip)
{
switch (pc_src.GetCustomRole())
{
case CustomRoles.Divinator when Divinator.CancelVote.GetBool():
if (Divinator.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Oracle when Oracle.CancelVote.GetBool():
if (Oracle.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Eraser when Eraser.CancelVote.GetBool():
if (Eraser.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Tether when Tether.CancelVote.GetBool():
if (Tether.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Ricochet when Ricochet.CancelVote.GetBool():
if (Ricochet.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Cleanser when Cleanser.CancelVote.GetBool():
if (Cleanser.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.NiceEraser when NiceEraser.CancelVote.GetBool():
if (NiceEraser.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Tracker when Tracker.CancelVote.GetBool():
if (Tracker.OnVote(pc_src, pc_target)) CancelVote();
break;
case CustomRoles.Godfather when Options.GodfatherCancelVote.GetBool():
Main.GodfatherTarget = pc_target.PlayerId;
CancelVote();
break;
}
}
}
void CancelVote()
{
ShouldCancelVoteList.TryAdd(srcPlayerId, (__instance, pva_src, pc_src));
isVoteCanceled = true;
}
Logger.Info($"{pc_src.GetNameWithRole().RemoveHtmlTags()} => {(isSkip ? "Skip" : pc_target.GetNameWithRole().RemoveHtmlTags())}{(isVoteCanceled ? " (Canceled)" : string.Empty)}", "Vote");
return isSkip || !isVoteCanceled; // return false to use the vote as a trigger; skips and invalid votes are never canceled
}
public static void Postfix([HarmonyArgument(0)] byte srcPlayerId)
{
if (!ShouldCancelVoteList.TryGetValue(srcPlayerId, out var info)) return;
MeetingHud __instance = info.MEETING_HUD;
PlayerVoteArea pva_src = info.SOURCE_PLAYER_VOTE_AREA;
PlayerControl pc_src = info.SOURCE_PLAYER;
try { pva_src.UnsetVote(); } catch { }
__instance.RpcClearVote(pc_src.GetClientId());
ShouldCancelVoteList.Remove(srcPlayerId);
}
}
[HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.CmdCastVote))]
class MeetingHudCmdCastVotePatch
{
public static bool Prefix()
public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)] byte srcPlayerId, [HarmonyArgument(1)] byte suspectPlayerId)
{
return MeetingHudCastVotePatch.Prefix();
return MeetingHudCastVotePatch.Prefix(__instance, srcPlayerId, suspectPlayerId);
}
public static void Postfix(MeetingHud __instance, [HarmonyArgument(0)] byte srcPlayerId, [HarmonyArgument(1)] byte suspectPlayerId)
public static void Postfix([HarmonyArgument(0)] byte srcPlayerId)
{
MeetingHudCastVotePatch.Postfix(__instance, srcPlayerId, suspectPlayerId);
MeetingHudCastVotePatch.Postfix(srcPlayerId);
}
}
+87 -4
View File
@@ -1,3 +1,4 @@
using AmongUs.GameOptions;
using HarmonyLib;
using System;
using System.Collections.Generic;
@@ -7,6 +8,7 @@ using TOHE.Modules;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Impostor;
using TOHE.Roles.Neutral;
using UnityEngine;
using static TOHE.Translator;
namespace TOHE;
@@ -98,6 +100,11 @@ class ExternalRpcPetPatch
PlayerControl[] AllAlivePlayers = Main.AllAlivePlayerControls;
bool hasKillTarget = false;
PlayerControl target = SelectKillButtonTarget(pc);
if (target != null) hasKillTarget = true;
if (!pc.CanUseKillButton()) hasKillTarget = false;
switch (pc.GetCustomRole())
{
// Crewmates
@@ -304,6 +311,75 @@ class ExternalRpcPetPatch
pc.Notify(sb.ToString());
break;
case CustomRoles.Gaulois when hasKillTarget:
Gaulois.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Aid when hasKillTarget:
Aid.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Escort when hasKillTarget:
Escort.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.DonutDelivery when hasKillTarget:
DonutDelivery.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Analyzer when hasKillTarget:
Analyzer.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Jailor when hasKillTarget:
Jailor.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Sheriff when hasKillTarget:
if (Sheriff.OnCheckMurder(pc, target)) pc.RpcCheckAndMurder(target);
else pc.AddKCDAsAbilityCD();
break;
case CustomRoles.SwordsMan when hasKillTarget:
if (SwordsMan.OnCheckMurder(pc)) if (!pc.RpcCheckAndMurder(target)) pc.AddKCDAsAbilityCD();
else pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Witness when hasKillTarget:
if (Main.AllKillers.ContainsKey(target.PlayerId))
pc.Notify(GetString("WitnessFoundKiller"));
else pc.Notify(GetString("WitnessFoundInnocent"));
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Medic when hasKillTarget:
Medic.OnCheckMurderFormedicaler(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Monarch when hasKillTarget:
Monarch.OnCheckMurder(pc, target);
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.CopyCat when hasKillTarget:
if (CopyCat.OnCheckMurder(pc, target)) if (!pc.RpcCheckAndMurder(target)) pc.AddKCDAsAbilityCD();
pc.AddKCDAsAbilityCD();
break;
case CustomRoles.Farseer when hasKillTarget:
pc.AddAbilityCD(Farseer.FarseerRevealTime.GetInt());
if (!Main.isRevealed[(pc.PlayerId, target.PlayerId)] && !Main.FarseerTimer.ContainsKey(pc.PlayerId))
{
Main.FarseerTimer.TryAdd(pc.PlayerId, (target, 0f));
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: target, ForceLoop: true);
RPC.SetCurrentRevealTarget(pc.PlayerId, target.PlayerId);
}
break;
case CustomRoles.Deputy when hasKillTarget:
Deputy.OnCheckMurder(pc, target);
break;
case CustomRoles.Admirer when hasKillTarget:
Admirer.OnCheckMurder(pc, target);
break;
case CustomRoles.Crusader when hasKillTarget:
Crusader.OnCheckMurder(pc, target);
break;
// Impostors
case CustomRoles.Sniper:
@@ -326,7 +402,7 @@ class ExternalRpcPetPatch
if (!Options.WarlockCanKillAllies.GetBool() && p.GetCustomRole().IsImpostor()) continue;
if (p.Is(CustomRoles.Pestilence)) continue;
if (Pelican.IsEaten(p.PlayerId) || Medic.ProtectList.Contains(p.PlayerId)) continue;
dis = UnityEngine.Vector2.Distance(cppos, p.Pos());
dis = Vector2.Distance(cppos, p.Pos());
cpdistance.Add(p, dis);
Logger.Info($"{p?.Data?.PlayerName}'s distance: {dis}", "Warlock");
}
@@ -391,7 +467,7 @@ class ExternalRpcPetPatch
{
if (!tg.IsModClient()) tg.KillFlash();
var pos = pc.Pos();
var dis = UnityEngine.Vector2.Distance(pos, tg.Pos());
var dis = Vector2.Distance(pos, tg.Pos());
if (!tg.IsAlive() || Pelican.IsEaten(tg.PlayerId) || Medic.ProtectList.Contains(tg.PlayerId) || (tg.Is(CustomRoleTypes.Impostor) && Options.ImpostorsSurviveBombs.GetBool()) || tg.inVent || tg.Is(CustomRoles.Pestilence)) continue;
if (dis > Options.BomberRadius.GetFloat()) continue;
@@ -416,7 +492,7 @@ class ExternalRpcPetPatch
{
if (!tg.IsModClient()) tg.KillFlash();
var pos = pc.Pos();
var dis = UnityEngine.Vector2.Distance(pos, tg.Pos());
var dis = Vector2.Distance(pos, tg.Pos());
if (!tg.IsAlive() || Pelican.IsEaten(tg.PlayerId) || Medic.ProtectList.Contains(tg.PlayerId) || tg.inVent || tg.Is(CustomRoles.Pestilence)) continue;
if (dis > Options.NukeRadius.GetFloat()) continue;
@@ -469,8 +545,15 @@ class ExternalRpcPetPatch
break;
}
if (pc.Is(CustomRoles.Sniper) && Sniper.IsAim[pc.PlayerId]) return;
if (pc.HasAbilityCD() || (pc.Is(CustomRoles.Sniper) && Sniper.IsAim[pc.PlayerId])) return;
pc.AddAbilityCD();
}
public static PlayerControl SelectKillButtonTarget(PlayerControl pc)
{
var players = pc.GetPlayersInAbilityRangeSorted();
var target = players.Count == 0 ? null : players[0];
return target;
}
}
+31 -8
View File
@@ -1947,6 +1947,7 @@ class ReportDeadBodyPatch
{
Damocles.OnReport();
}
Damocles.OnMeetingStart();
if (player.Is(CustomRoles.Stressed))
{
@@ -2239,21 +2240,19 @@ class FixedUpdatePatch
{
if (Main.AbilityCD.TryGetValue(playerId, out var timer))
{
if (timer.START_TIMESTAMP + timer.TOTALCD < GetTimeStamp())
if (timer.START_TIMESTAMP + timer.TOTALCD < GetTimeStamp() || !player.IsAlive())
{
Main.AbilityCD.Remove(playerId);
}
if (!player.IsModClient()) NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
}
if (Main.AbilityCD.ContainsKey(playerId) && !player.IsModClient()) NotifyRoles(SpecifySeer: player, SpecifyTarget: player);
}
}
if (!lowLoad)
{
YinYanger.OnFixedUpdate();
Duellist.OnFixedUpdate();
if (!lowLoad)
{
YinYanger.OnFixedUpdate();
Duellist.OnFixedUpdate();
}
}
if (GameStates.IsInTask && Agitater.IsEnable && Agitater.AgitaterHasBombed && Agitater.CurrentBombedPlayer == playerId)
@@ -3781,3 +3780,27 @@ class PlayerControlSetRolePatch
return true;
}
}
[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.SetRole))]
class PlayerControlLocalSetRolePatch
{
public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] RoleTypes role)
{
if (!AmongUsClient.Instance.AmHost && !GameStates.IsModHost)
{
var moddedRole = role switch
{
RoleTypes.Impostor => CustomRoles.ImpostorTOHE,
RoleTypes.Shapeshifter => CustomRoles.ShapeshifterTOHE,
RoleTypes.Crewmate => CustomRoles.CrewmateTOHE,
RoleTypes.Engineer => CustomRoles.EngineerTOHE,
RoleTypes.Scientist => CustomRoles.ScientistTOHE,
_ => CustomRoles.NotAssigned,
};
if (moddedRole != CustomRoles.NotAssigned)
{
Main.PlayerStates[__instance.PlayerId].SetMainRole(moddedRole);
}
}
}
}
+1 -1
View File
@@ -3,7 +3,6 @@ using AmongUs.GameOptions;
using HarmonyLib;
using Hazel;
using InnerNet;
using System.Linq;
using System.Text.RegularExpressions;
using TOHE.Modules;
using TOHE.Roles.Crewmate;
@@ -147,6 +146,7 @@ class OnPlayerLeftPatch
Main.PlayerStates[data.Character.PlayerId].deathReason = PlayerState.DeathReason.Disconnected;
Main.PlayerStates[data.Character.PlayerId].SetDead();
}
NameNotifyManager.Notice.Remove(data.Character.PlayerId);
AntiBlackout.OnDisconnect(data.Character.Data);
PlayerGameOptionsSender.RemoveSender(data.Character);
}
-1
View File
@@ -1,5 +1,4 @@
using HarmonyLib;
using UnityEngine;
namespace TOHE.Patches;
+2 -1
View File
@@ -78,6 +78,7 @@ internal class ChangeRoleSettings
Main.InfectedBodies = [];
Main.VirusNotify = [];
Main.CrewpostorTasksDone = [];
Main.DontCancelVoteList = [];
Main.LastEnteredVent = [];
Main.LastEnteredVentLocation = [];
@@ -1185,7 +1186,7 @@ internal class SelectRolesPatch
}
// Added players with unclassified roles to the list of players who require ResetCam.
Main.ResetCamPlayerList.AddRange(Main.AllPlayerControls.Where(p => p.GetCustomRole() is CustomRoles.Arsonist or CustomRoles.Revolutionist or CustomRoles.Sidekick or CustomRoles.KB_Normal or CustomRoles.Killer or CustomRoles.Tasker or CustomRoles.Witness or CustomRoles.Innocent).Select(p => p.PlayerId));
Main.ResetCamPlayerList.AddRange(Main.AllPlayerControls.Where(p => p.GetCustomRole() is CustomRoles.Arsonist or CustomRoles.Revolutionist or CustomRoles.Sidekick or CustomRoles.KB_Normal or CustomRoles.Killer or CustomRoles.Tasker or CustomRoles.Innocent || (p.Is(CustomRoles.Witness) && (!Options.UsePets.GetBool() || Options.WitnessUsePet.GetBool()))).Select(p => p.PlayerId));
Utils.CountAlivePlayers(true);
Utils.SyncAllSettings();
SetColorPatch.IsAntiGlitchDisabled = false;
+2
View File
@@ -75,6 +75,8 @@ curtsyboth#4114,1f9bbee79,龙傲天》//MalumMenu
shyfortune#7692,526f950da,B站日常无语的无语君 //AUM
0a4f7e294,Melani //no friendcode hacker
sprysign#5596,064c15bb6,Onion
musksolid#9543,troutdusky#6471,a9b3569f5,c40cfe547,caf7d691c,covid20 //Spoofed MalumMenu
errantlug#6514,79f0cbe07,Kerbpoetic //AUM
## Griefer
setmolar#4374,藏族顶针
+21 -3
View File
@@ -1223,6 +1223,17 @@
"ArsonistMinPlayersToIgnite","","Minimum Doused Players required to Ignite","","",""
"ArsonistMaxPlayersToIgnite","","Maximum Amount of Doused Players at once","","",""
"## Remaining Killers Text / Confirm Ejections Text"
"RemainingText.Prefix.SingleImp","","There is","","",""
"RemainingText.Prefix.PluralImp","","There are","","",""
"RemainingText.ImpSingle","","Impostor","","",""
"RemainingText.ImpPlural","","Impostors","","",""
"RemainingText.NKSingle","","Neutral Killer","","",""
"RemainingText.NKPlural","","Neutral Killers","","",""
"RemainingText.Suffix","","left","","",""
"RemainingText.EjectionSuffix.NKSingle","","remains.","","",""
"RemainingText.EjectionSuffix.NKPlural","","remain.","","",""
"## 详细设定 / Advanced Settings"
"Cooldown","冷却时间","Cooldown","Откат","冷卻時間","冷却时间"
"KillCooldown","击杀冷却时间","Kill Cooldown","Откат убийства","殺人冷卻時間","击杀冷却时间"
@@ -1439,9 +1450,11 @@
"NotifyGodAlive","如果神存活则在会议上通知所有人","Inform players at meetings that God is still alive","Сообщать игрокам на встрече что Дьявол ещё жив","若神存活則在會議上通知所有人","如果神存活则在会议上通知所有人"
"TransporterTeleportMax","传送次数上限","Max number of teleports","Максимальное колличество телепортов","傳送次數上限","传送次数上限"
"TriggerKill","击杀","Kill","Убийство","殺死","击杀"
"UsePetInsteadOfKillButton","","Use Pet Button As Kill Button","","",""
"UsePets","","Use Pet button instead of Vent / Shapeshift","","",""
"PetToAssign","","Pet to Assign to Everyone","","",""
"UseVoteCancelling","","Use Vote Cancelling Method instead of Commands","","",""
"UseVoteCancellingAfterVote","","Can Vote Normally After Using Ability (Vote)","","",""
"AbilityOnCooldown","","<color=#ffff00>Ability on cooldown!</color>","","",""
"KillCooldownOnStrangle","","Kill Cooldown after Strangling","","",""
"CDPT","","<color=#00ffa5>CD:</color> <color=#ffffff><b>{0}</b>s</color>","","",""
@@ -2859,19 +2872,19 @@
"EnigmaClueLevel2","","The Killer's Level is below 50!","","",""
"EnigmaClueLevel3","","The Killer's Level is between {0} and {1}!","","",""
"EnigmaClueLevel4","","The Killer's Level is {0}!","","",""
"EnigmaClueFriendCode","","The Killer's Friendcode is {0}!","","",""
"EnigmaClueFriendCode","","The Killer's Friend Code is {0}!","","",""
"EnigmaClueHatTitle","","Enigma Hat Clue!","","",""
"EnigmaClueVisorTitle","","Enigma Visor Clue!","","",""
"EnigmaClueSkinTitle","","Enigma Skin Clue!","","",""
"EnigmaCluePetTitle","","Enigma Pet Clue!","","",""
"EnigmaClueNameTitle","","Enigma Name Clue!","","",""
"EnigmaClueNameLengthTitle","","Enigma Name lenght Clue!","","",""
"EnigmaClueNameLengthTitle","","Enigma Name Length Clue!","","",""
"EnigmaClueColorTitle","","Enigma Color Clue!","","",""
"EnigmaClueLocationTitle","","Enigma Location Clue!","","",""
"EnigmaClueStatusTitle","","Enigma Status Clue!","","",""
"EnigmaClueRoleTitle","","Enigma Role Clue!","","",""
"EnigmaClueLevelTitle","","Enigma Level Clue!","","",""
"EnigmaClueFriendCodeTitle","","Enigma Friendcode Clue!","","",""
"EnigmaClueFriendCodeTitle","","Enigma Friend Code Clue!","","",""
"EnigmaClueTitle","","Enigma Clue!","","",""
"## Plague Doctor"
@@ -3033,6 +3046,10 @@
"WeaponMasterInfoLong","","(Neutral):\nAs the Weapon Master, you can cycle between your weapons by petting your pet/calling a sabotage.\n\nThe Sword weapon is a normal kill method.\n\nThe Axe weapon kills everyone in a certain radius when you make a kill. You have a higher kill cooldown while using this weapon.\n\nThe Lance weapon sets your kill range to the maximum, and you don't lunge toward your kills. You can't vent while using this weapon.\n\nWhile using your Shield, you can survive an attack once. You can't kill while using your shield.","","",""
"WMRadius","","Axe Mode Death Radius","","",""
"WMShieldAlreadyUsed","","Your shield was already used","","",""
"Sword","","Sword","","",""
"Axe","","Axe","","",""
"Lance","","Lance","","",""
"Shield","","Shield","","",""
"## Eclipse"
"Eclipse","","Eclipse","","",""
@@ -3316,6 +3333,7 @@
"FFA_TargetIsShielded","","<color=#ffff00>The player you tried to kill is shielded!</color>","","",""
"FFA_ShieldIsOneTimeUse","","Shields break after 1 kill attempt","","",""
"FFA_ShieldBroken","","<color=#ffff00>Someone tried to kill you, your shield is now broken!</color>","","",""
"FFA_ChatDuringGame","","Chat During Game","","",""
"FFAChatMessageNotify","","[<color=#00ffff>Chat</color>] <color=#00ffa5>{0}:</color> {1}","","",""
"Killer","","FREE FOR ALL","","",""
"KillerInfo","","Kill Everyone to Win","","",""
Can't render this file because it is too large.
+13 -4
View File
@@ -54,7 +54,12 @@ namespace TOHE.Roles.AddOns.Impostor
public static void Update(PlayerControl pc)
{
if (lastUpdate >= GetTimeStamp() || !GameStates.IsInTask || !pc.IsAlive()) return;
if (lastUpdate >= GetTimeStamp() || !GameStates.IsInTask || pc == null) return;
if (!pc.IsAlive())
{
Main.PlayerStates[pc.PlayerId].RemoveSubRole(CustomRoles.Damocles);
return;
}
lastUpdate = GetTimeStamp();
Timer--;
@@ -65,7 +70,7 @@ namespace TOHE.Roles.AddOns.Impostor
pc.Suicide();
}
if (pc.IsModClient() && pc.PlayerId != 0) SendRPC();
if (pc.IsNonHostModClient()) SendRPC();
NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
}
@@ -111,10 +116,14 @@ namespace TOHE.Roles.AddOns.Impostor
PreviouslyEnteredVents.Clear();
Timer += TimeAfterMeeting;
Timer += 9;
countRepairSabotage = true;
}
public static void OnMeetingStart()
{
Timer += 9;
}
public static void OnCrewmateEjected()
{
Timer = (int)Math.Round(Timer * 1.3);
@@ -142,4 +151,4 @@ namespace TOHE.Roles.AddOns.Impostor
public static string GetProgressText() => string.Format(GetString("DamoclesTimeLeft"), Timer);
}
}
}
+8 -3
View File
@@ -13,14 +13,19 @@ public static class Admirer
public static OptionItem AdmireCooldown;
public static OptionItem KnowTargetRole;
public static OptionItem UsePet;
public static int AdmireLimit;
public static void SetupCustomOption()
{
SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Admirer, 1);
AdmireCooldown = FloatOptionItem.Create(Id + 10, "AdmireCooldown", new(1f, 180f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Admirer])
AdmireCooldown = FloatOptionItem.Create(Id + 10, "AdmireCooldown", new(1f, 180f, 1f), 15f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Admirer])
.SetValueFormat(OptionFormat.Seconds);
KnowTargetRole = BooleanOptionItem.Create(Id + 13, "AdmirerKnowTargetRole", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Admirer]);
KnowTargetRole = BooleanOptionItem.Create(Id + 13, "AdmirerKnowTargetRole", true, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Admirer]);
UsePet = CreatePetUseSetting(Id + 11, CustomRoles.Admirer);
}
public static void Init()
{
@@ -32,7 +37,7 @@ public static class Admirer
playerIdList.Add(playerId);
AdmireLimit = 1;
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+10 -6
View File
@@ -2,7 +2,6 @@ namespace TOHE.Roles.Crewmate
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using static TOHE.Options;
@@ -18,16 +17,21 @@ namespace TOHE.Roles.Crewmate
public static OptionItem AidDur;
public static OptionItem AidCD;
public static OptionItem UseLimitOpt;
public static OptionItem UsePet;
public static void SetupCustomOption()
{
SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Aid);
AidCD = FloatOptionItem.Create(Id + 10, "AidCD", new(0f, 60f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
AidCD = FloatOptionItem.Create(Id + 10, "AidCD", new(0f, 60f, 1f), 15f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
.SetValueFormat(OptionFormat.Seconds);
AidDur = FloatOptionItem.Create(Id + 11, "AidDur", new(0f, 60f, 1f), 10f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
AidDur = FloatOptionItem.Create(Id + 11, "AidDur", new(0f, 60f, 1f), 10f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
.SetValueFormat(OptionFormat.Seconds);
UseLimitOpt = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 5, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
.SetValueFormat(OptionFormat.Times);
UseLimitOpt = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 5, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Aid])
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 13, CustomRoles.Aid);
}
public static void Init()
{
@@ -40,7 +44,7 @@ namespace TOHE.Roles.Crewmate
playerIdList.Add(playerId);
UseLimit.Add(playerId, UseLimitOpt.GetInt());
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+3 -1
View File
@@ -19,6 +19,7 @@ namespace TOHE.Roles.Crewmate
private static OptionItem SeeKillCount;
private static OptionItem SeeVentCount;
private static OptionItem SeeRoleBasis;
public static OptionItem UsePet;
private static readonly Dictionary<string, string> replacementDict = new() { { "Analyze", ColorString(GetRoleColor(CustomRoles.Analyzer), "Analyze") } };
@@ -45,6 +46,7 @@ namespace TOHE.Roles.Crewmate
.SetParent(CustomRoleSpawnChances[CustomRoles.Analyzer]);
SeeRoleBasis = BooleanOptionItem.Create(Id + 15, "AnalyzerSeeRoleBasis", true, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Analyzer]);
UsePet = CreatePetUseSetting(Id + 16, CustomRoles.Analyzer);
}
public static bool CanUseKillButton => CurrentTarget.ID == byte.MaxValue && UseLimit > 0;
@@ -85,7 +87,7 @@ namespace TOHE.Roles.Crewmate
playerId = id;
UseLimit = UseLimitOpt.GetInt();
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(id))
Main.ResetCamPlayerList.Add(id);
}
-1
View File
@@ -2,7 +2,6 @@
{
using Hazel;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static TOHE.Options;
using static TOHE.Translator;
+11 -7
View File
@@ -16,6 +16,7 @@ public static class Cleanser
public static OptionItem CleanserUsesOpt;
public static OptionItem CleansedCanGetAddon;
public static OptionItem CancelVote;
public static void SetupCustomOption()
{
@@ -23,7 +24,7 @@ public static class Cleanser
CleanserUsesOpt = IntegerOptionItem.Create(Id + 10, "MaxCleanserUses", new(1, 14, 1), 3, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Cleanser])
.SetValueFormat(OptionFormat.Times);
CleansedCanGetAddon = BooleanOptionItem.Create(Id + 11, "CleansedCanGetAddon", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Cleanser]);
CancelVote = CreateVoteCancellingUseSetting(Id + 12, CustomRoles.Cleanser, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -73,18 +74,18 @@ public static class Cleanser
CleanserUses.Add(CleanserId, 0);
}
public static void OnVote(PlayerControl voter, PlayerControl target)
public static bool OnVote(PlayerControl voter, PlayerControl target)
{
if (!voter.Is(CustomRoles.Cleanser)) return;
if (DidVote[voter.PlayerId]) return;
if (!voter.Is(CustomRoles.Cleanser)) return false;
if (DidVote[voter.PlayerId] || Main.DontCancelVoteList.Contains(voter.PlayerId)) return false;
DidVote[voter.PlayerId] = true;
if (CleanserUses[voter.PlayerId] >= CleanserUsesOpt.GetInt()) return;
if (CleanserUses[voter.PlayerId] >= CleanserUsesOpt.GetInt()) return false;
if (target.PlayerId == voter.PlayerId)
{
Utils.SendMessage(GetString("CleanserRemoveSelf"), voter.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cleanser), GetString("CleanserTitle")));
return;
return false;
}
if (CleanserTarget[voter.PlayerId] != byte.MaxValue) return;
if (CleanserTarget[voter.PlayerId] != byte.MaxValue) return false;
CleanserUses[voter.PlayerId]++;
CleanserTarget[voter.PlayerId] = target.PlayerId;
@@ -92,6 +93,9 @@ public static class Cleanser
CleansedPlayers.Add(target.PlayerId);
Utils.SendMessage(string.Format(GetString("CleanserRemovedRole"), target.GetRealName()), voter.PlayerId, title: Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cleanser), GetString("CleanserTitle")));
SendRPC(voter.PlayerId);
Main.DontCancelVoteList.Add(voter.PlayerId);
return true;
}
public static void AfterMeetingTasks()
+4 -1
View File
@@ -17,6 +17,7 @@ public static class CopyCat
public static OptionItem CanKill;
public static OptionItem CopyCrewVar;
public static OptionItem MiscopyLimitOpt;
public static OptionItem UsePet;
public static void SetupCustomOption()
{
@@ -27,6 +28,7 @@ public static class CopyCat
CopyCrewVar = BooleanOptionItem.Create(Id + 13, "CopyCrewVar", true, TabGroup.OtherRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.CopyCat]);
MiscopyLimitOpt = IntegerOptionItem.Create(Id + 12, "CopyCatMiscopyLimit", new(0, 14, 1), 2, TabGroup.OtherRoles, false).SetParent(CanKill)
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 14, CustomRoles.CopyCat);
}
public static void Init()
@@ -41,7 +43,8 @@ public static class CopyCat
playerIdList.Add(playerId);
CurrentKillCooldown.Add(playerId, KillCooldown.GetFloat());
MiscopyLimit.TryAdd(playerId, MiscopyLimitOpt.GetInt());
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+6 -3
View File
@@ -7,10 +7,13 @@ public static class Crusader
{
private static readonly int Id = 20050;
private static List<byte> playerIdList = [];
public static Dictionary<byte, int> CrusaderLimit = [];
public static OptionItem SkillLimitOpt;
public static OptionItem SkillCooldown;
public static OptionItem UsePet;
public static Dictionary<byte, float> CurrentKillCooldown = [];
public static Dictionary<byte, int> CrusaderLimit = [];
public static void SetupCustomOption()
{
@@ -19,6 +22,7 @@ public static class Crusader
.SetValueFormat(OptionFormat.Seconds);
SkillLimitOpt = IntegerOptionItem.Create(Id + 11, "CrusaderSkillLimit", new(1, 10, 1), 2, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crusader])
.SetValueFormat(OptionFormat.Times);
UsePet = Options.CreatePetUseSetting(Id + 12, CustomRoles.Crusader);
}
public static void Init()
{
@@ -31,8 +35,7 @@ public static class Crusader
CrusaderLimit.TryAdd(playerId, SkillLimitOpt.GetInt());
CurrentKillCooldown.Add(playerId, SkillCooldown.GetFloat());
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (Options.UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+3 -1
View File
@@ -15,6 +15,7 @@ public static class Deputy
public static OptionItem HandcuffMax;
public static OptionItem DeputyHandcuffCDForTarget;
private static OptionItem DeputyHandcuffDelay;
public static OptionItem UsePet;
public static int HandcuffLimit;
@@ -29,6 +30,7 @@ public static class Deputy
.SetValueFormat(OptionFormat.Times);
DeputyHandcuffDelay = IntegerOptionItem.Create(Id + 11, "DeputyHandcuffDelay", new(0, 20, 1), 5, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Deputy])
.SetValueFormat(OptionFormat.Seconds);
UsePet = CreatePetUseSetting(Id + 13, CustomRoles.Deputy);
}
public static void Init()
{
@@ -40,7 +42,7 @@ public static class Deputy
playerIdList.Add(playerId);
HandcuffLimit = HandcuffMax.GetInt();
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+10 -5
View File
@@ -15,6 +15,7 @@ public static class Divinator
public static OptionItem HideVote;
public static OptionItem ShowSpecificRole;
public static OptionItem AbilityUseGainWithEachTaskCompleted;
public static OptionItem CancelVote;
public static List<byte> didVote = [];
public static Dictionary<byte, float> CheckLimit = [];
@@ -29,6 +30,7 @@ public static class Divinator
HideVote = BooleanOptionItem.Create(Id + 14, "DivinatorHideVote", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Divinator]);
AbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 15, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Divinator])
.SetValueFormat(OptionFormat.Times);
CancelVote = CreateVoteCancellingUseSetting(Id + 11, CustomRoles.Divinator, TabGroup.CrewmateRoles);
OverrideTasksData.Create(Id + 21, TabGroup.CrewmateRoles, CustomRoles.Divinator);
}
public static void Init()
@@ -58,16 +60,16 @@ public static class Divinator
float uses = reader.ReadSingle();
CheckLimit[playerId] = uses;
}
public static void OnVote(PlayerControl player, PlayerControl target)
public static bool OnVote(PlayerControl player, PlayerControl target)
{
if (player == null || target == null) return;
if (didVote.Contains(player.PlayerId)) return;
if (player == null || target == null) return false;
if (didVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
didVote.Add(player.PlayerId);
if (CheckLimit[player.PlayerId] < 1)
{
Utils.SendMessage(GetString("DivinatorCheckReachLimit"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Divinator), GetString("DivinatorCheckMsgTitle")));
return;
return false;
}
CheckLimit[player.PlayerId] -= 1;
@@ -76,7 +78,7 @@ public static class Divinator
if (player.PlayerId == target.PlayerId)
{
Utils.SendMessage(GetString("DivinatorCheckSelfMsg") + "\n\n" + string.Format(GetString("DivinatorCheckLimit"), CheckLimit[player.PlayerId]), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Divinator), GetString("DivinatorCheckMsgTitle")));
return;
return false;
}
string msg;
@@ -548,5 +550,8 @@ public static class Divinator
}*/
Utils.SendMessage(GetString("DivinatorCheck") + "\n" + msg + "\n\n" + string.Format(GetString("DivinatorCheckLimit"), CheckLimit[player.PlayerId]), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Divinator), GetString("DivinatorCheckMsgTitle")));
Main.DontCancelVoteList.Add(player.PlayerId);
return true;
}
}
+3 -1
View File
@@ -12,6 +12,7 @@ namespace TOHE.Roles.Crewmate
private static OptionItem CD;
private static OptionItem UseLimit;
public static OptionItem UsePet;
public static int DeliverLimit;
@@ -24,6 +25,7 @@ namespace TOHE.Roles.Crewmate
UseLimit = IntegerOptionItem.Create(Id + 12, "AbilityUseLimit", new(1, 20, 1), 5, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.DonutDelivery])
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 13, CustomRoles.DonutDelivery);
}
public static void Init()
@@ -39,7 +41,7 @@ namespace TOHE.Roles.Crewmate
DeliverLimit = UseLimit.GetInt();
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+3 -1
View File
@@ -14,6 +14,7 @@ namespace TOHE.Roles.Crewmate
private static OptionItem CD;
private static OptionItem UseLimit;
public static OptionItem UsePet;
public static int BlockLimit;
@@ -26,6 +27,7 @@ namespace TOHE.Roles.Crewmate
UseLimit = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(1, 20, 1), 3, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Escort])
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 12, CustomRoles.Escort);
}
public static void Init()
@@ -39,7 +41,7 @@ namespace TOHE.Roles.Crewmate
BlockLimit = UseLimit.GetInt();
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+6 -2
View File
@@ -18,6 +18,7 @@ namespace TOHE.Roles.Crewmate
public static OptionItem FarseerCooldown;
public static OptionItem FarseerRevealTime;
public static OptionItem Vision;
public static OptionItem UsePet;
private static readonly System.Collections.Generic.List<CustomRoles> randomRolesForTrickster =
[
@@ -109,6 +110,7 @@ namespace TOHE.Roles.Crewmate
.SetValueFormat(OptionFormat.Seconds);
Vision = FloatOptionItem.Create(Id + 12, "FarseerVision", new(0f, 1f, 0.05f), 0.25f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Farseer])
.SetValueFormat(OptionFormat.Multiplier);
UsePet = CreatePetUseSetting(Id + 13, CustomRoles.Farseer);
}
public static void Init()
{
@@ -117,7 +119,8 @@ namespace TOHE.Roles.Crewmate
public static void Add(byte playerId)
{
isEnable = true;
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
@@ -145,7 +148,8 @@ namespace TOHE.Roles.Crewmate
}
else if (ar_time >= FarseerRevealTime.GetFloat())//時間以上一緒にいて塗れた時
{
player.SetKillCooldown();
if (UsePets.GetBool()) player.AddKCDAsAbilityCD();
else player.SetKillCooldown();
Main.FarseerTimer.Remove(player.PlayerId);//塗が完了したのでDictionaryから削除
Main.isRevealed[(player.PlayerId, ar_target.PlayerId)] = true;//塗り完了
player.RpcSetRevealtPlayer(ar_target, true);
+7
View File
@@ -13,6 +13,7 @@ namespace TOHE.Roles.Crewmate
private static OptionItem CD;
private static OptionItem AdditionalSpeed;
private static OptionItem UseLimitOpt;
public static OptionItem UsePet;
public static List<byte> IncreasedSpeedPlayerList = [];
@@ -28,6 +29,7 @@ namespace TOHE.Roles.Crewmate
UseLimitOpt = IntegerOptionItem.Create(Id + 7, "AbilityUseLimit", new(1, 14, 1), 3, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Gaulois])
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 8, CustomRoles.Gaulois);
}
public static void Init()
@@ -41,6 +43,10 @@ namespace TOHE.Roles.Crewmate
{
playerIdList.Add(playerId);
UseLimit.Add(playerId, UseLimitOpt.GetInt());
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
public static bool IsEnable => playerIdList.Count > 0;
@@ -91,6 +97,7 @@ namespace TOHE.Roles.Crewmate
IncreasedSpeedPlayerList.Add(target.PlayerId);
UseLimit[killer.PlayerId]--;
killer.SetKillCooldown();
SendRPC(killer.PlayerId);
SendRPCAddPlayerToList(target.PlayerId);
}
+3 -2
View File
@@ -16,7 +16,7 @@ public static class Jailor
public static OptionItem JailCooldown;
public static OptionItem notifyJailedOnMeeting;
public static OptionItem UsePet;
public static void SetupCustomOption()
{
@@ -24,6 +24,7 @@ public static class Jailor
JailCooldown = FloatOptionItem.Create(Id + 10, "JailorJailCooldown", new(0f, 60f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jailor])
.SetValueFormat(OptionFormat.Seconds);
notifyJailedOnMeeting = BooleanOptionItem.Create(Id + 18, "notifyJailedOnMeeting", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jailor]);
UsePet = CreatePetUseSetting(Id + 11, CustomRoles.Jailor);
}
public static void Init()
@@ -41,7 +42,7 @@ public static class Jailor
JailorHasExe.Add(playerId, false);
JailorDidVote.Add(playerId, false);
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+3 -1
View File
@@ -23,6 +23,7 @@ public static class Medic
private static OptionItem ResetCooldown;
public static OptionItem GuesserIgnoreShield;
private static OptionItem AmountOfShields;
public static OptionItem UsePet;
public static readonly string[] MedicWhoCanSeeProtectName =
[
@@ -65,6 +66,7 @@ public static class Medic
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.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);
}
public static void Init()
{
@@ -81,7 +83,7 @@ public static class Medic
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()} : {ProtectLimit[playerId]} shields left", "Medicaler");
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (Options.UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+3 -2
View File
@@ -13,7 +13,7 @@ public static class Monarch
public static OptionItem KnightCooldown;
public static OptionItem KnightMax;
public static OptionItem UsePet;
public static int KnightLimit;
@@ -24,6 +24,7 @@ public static class Monarch
.SetValueFormat(OptionFormat.Seconds);
KnightMax = IntegerOptionItem.Create(Id + 12, "MonarchKnightMax", new(1, 15, 1), 2, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Monarch])
.SetValueFormat(OptionFormat.Times);
UsePet = CreatePetUseSetting(Id + 11, CustomRoles.Monarch);
}
public static void Init()
{
@@ -35,7 +36,7 @@ public static class Monarch
playerIdList.Add(playerId);
KnightLimit = KnightMax.GetInt();
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+12 -7
View File
@@ -12,6 +12,7 @@ internal static class NiceEraser
private static OptionItem EraseLimitOpt;
public static OptionItem HideVote;
public static OptionItem CancelVote;
private static List<byte> didVote = [];
public static Dictionary<byte, int> EraseLimit = [];
@@ -23,6 +24,7 @@ internal static class NiceEraser
EraseLimitOpt = IntegerOptionItem.Create(Id + 2, "EraseLimit", new(1, 15, 1), 1, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceEraser])
.SetValueFormat(OptionFormat.Times);
HideVote = BooleanOptionItem.Create(Id + 3, "NiceEraserHideVote", false, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceEraser]);
CancelVote = Options.CreateVoteCancellingUseSetting(Id + 4, CustomRoles.NiceEraser, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -55,24 +57,24 @@ internal static class NiceEraser
}
public static string GetProgressText(byte playerId) => Utils.ColorString(EraseLimit[playerId] > 0 ? Utils.GetRoleColor(CustomRoles.NiceEraser) : Color.gray, EraseLimit.TryGetValue(playerId, out var x) ? $"({x})" : "Invalid");
public static void OnVote(PlayerControl player, PlayerControl target)
public static bool OnVote(PlayerControl player, PlayerControl target)
{
if (player == null || target == null) return;
if (didVote.Contains(player.PlayerId)) return;
if (player == null || target == null) return false;
if (didVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
didVote.Add(player.PlayerId);
if (EraseLimit.ContainsKey(player.PlayerId) && EraseLimit[player.PlayerId] < 1) return;
if (EraseLimit.ContainsKey(player.PlayerId) && EraseLimit[player.PlayerId] < 1) return false;
if (target.PlayerId == player.PlayerId)
{
Utils.SendMessage(GetString("EraserEraseSelf"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceEraser), GetString("EraserEraseMsgTitle")));
return;
return false;
}
if (target.GetCustomRole().IsNeutral())
{
Utils.SendMessage(string.Format(GetString("EraserEraseNeutralNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceEraser), GetString("EraserEraseMsgTitle")));
return;
return false;
}
if (EraseLimit.ContainsKey(player.PlayerId)) EraseLimit[player.PlayerId]--;
@@ -83,7 +85,10 @@ internal static class NiceEraser
Utils.SendMessage(string.Format(GetString("EraserEraseNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceEraser), GetString("EraserEraseMsgTitle")));
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target);
if (GameStates.IsInTask) Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target);
Main.DontCancelVoteList.Add(player.PlayerId);
return true;
}
public static void OnReportDeadBody()
{
+22 -18
View File
@@ -15,6 +15,7 @@ public static class Oracle
public static OptionItem HideVote;
public static OptionItem FailChance;
public static OptionItem OracleAbilityUseGainWithEachTaskCompleted;
public static OptionItem CancelVote;
public static List<byte> didVote = [];
public static Dictionary<byte, float> CheckLimit = [];
@@ -33,6 +34,7 @@ public static class Oracle
OracleAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 14, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.2f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Oracle])
.SetValueFormat(OptionFormat.Times);
CancelVote = CreateVoteCancellingUseSetting(Id + 11, CustomRoles.Oracle, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -61,16 +63,16 @@ public static class Oracle
float uses = reader.ReadSingle();
CheckLimit[playerId] = uses;
}
public static void OnVote(PlayerControl player, PlayerControl target)
public static bool OnVote(PlayerControl player, PlayerControl target)
{
if (player == null || target == null) return;
if (didVote.Contains(player.PlayerId)) return;
if (player == null || target == null) return false;
if (didVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
didVote.Add(player.PlayerId);
if (CheckLimit[player.PlayerId] < 1)
{
Utils.SendMessage(GetString("OracleCheckReachLimit"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Oracle), GetString("OracleCheckMsgTitle")));
return;
return false;
}
CheckLimit[player.PlayerId] -= 1;
@@ -79,7 +81,7 @@ public static class Oracle
if (player.PlayerId == target.PlayerId)
{
Utils.SendMessage(GetString("OracleCheckSelfMsg") + "\n\n" + string.Format(GetString("OracleCheckLimit"), CheckLimit[player.PlayerId]), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Oracle), GetString("OracleCheckMsgTitle")));
return;
return false;
}
string text;
@@ -94,20 +96,20 @@ public static class Oracle
if (random_number_1 <= FailChance.GetInt())
{
int random_number_2 = IRandom.Instance.Next(1, 3);
if (text == "Crew")
switch (text)
{
if (random_number_2 == 1) text = "Neut";
if (random_number_2 == 2) text = "Imp";
}
if (text == "Neut")
{
if (random_number_2 == 1) text = "Crew";
if (random_number_2 == 2) text = "Imp";
}
if (text == "Imp")
{
if (random_number_2 == 1) text = "Neut";
if (random_number_2 == 2) text = "Crew";
case "Crew":
if (random_number_2 == 1) text = "Neut";
else if (random_number_2 == 2) text = "Imp";
break;
case "Neut":
if (random_number_2 == 1) text = "Crew";
if (random_number_2 == 2) text = "Imp";
break;
case "Imp":
if (random_number_2 == 1) text = "Neut";
if (random_number_2 == 2) text = "Crew";
break;
}
}
}
@@ -116,5 +118,7 @@ public static class Oracle
Utils.SendMessage(GetString("OracleCheck") + "\n" + msg + "\n\n" + string.Format(GetString("OracleCheckLimit"), CheckLimit[player.PlayerId]), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Oracle), GetString("OracleCheckMsgTitle")));
Main.DontCancelVoteList.Add(player.PlayerId);
return true;
}
}
+10 -8
View File
@@ -17,15 +17,17 @@ namespace TOHE.Roles.Crewmate
public static OptionItem UseLimitOpt;
public static OptionItem RicochetAbilityUseGainWithEachTaskCompleted;
public static OptionItem CancelVote;
public static void SetupCustomOption()
{
SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Ricochet, 1);
UseLimitOpt = IntegerOptionItem.Create(Id + 10, "AbilityUseLimit", new(0, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
.SetValueFormat(OptionFormat.Times);
.SetValueFormat(OptionFormat.Times);
RicochetAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 11, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
.SetValueFormat(OptionFormat.Times);
.SetParent(CustomRoleSpawnChances[CustomRoles.Ricochet])
.SetValueFormat(OptionFormat.Times);
CancelVote = CreateVoteCancellingUseSetting(Id + 12, CustomRoles.Ricochet, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -82,12 +84,9 @@ namespace TOHE.Roles.Crewmate
return true;
}
public static void OnVote(PlayerControl pc, PlayerControl target)
public static bool OnVote(PlayerControl pc, PlayerControl target)
{
if (target == null) return;
if (pc == null) return;
if (pc.PlayerId == target.PlayerId) return;
if (!pc.Is(CustomRoles.Ricochet)) return;
if (target == null || pc == null || pc.PlayerId == target.PlayerId || !pc.Is(CustomRoles.Ricochet) || Main.DontCancelVoteList.Contains(pc.PlayerId)) return false;
if (UseLimit[pc.PlayerId] >= 1)
{
@@ -95,7 +94,10 @@ namespace TOHE.Roles.Crewmate
ProtectAgainst = target.PlayerId;
SendRPC(pc.PlayerId);
SendRPCSyncTarget(ProtectAgainst);
Main.DontCancelVoteList.Add(pc.PlayerId);
return true;
}
return false;
}
public static void OnReportDeadBody()
{
+3 -1
View File
@@ -30,6 +30,7 @@ public static class Sheriff
public static OptionItem NonCrewCanKillCrew;
public static OptionItem NonCrewCanKillImp;
public static OptionItem NonCrewCanKillNeutral;
public static OptionItem UsePet;
public static Dictionary<CustomRoles, OptionItem> KillTargetOptions = [];
public static Dictionary<byte, int> ShotLimit = [];
public static Dictionary<byte, float> CurrentKillCooldown = [];
@@ -63,6 +64,7 @@ public static class Sheriff
NonCrewCanKillImp = BooleanOptionItem.Create(Id + 19, "SheriffMadCanKillImp", true, TabGroup.CrewmateRoles, false).SetParent(SetNonCrewCanKill);
NonCrewCanKillCrew = BooleanOptionItem.Create(Id + 21, "SheriffMadCanKillCrew", true, TabGroup.CrewmateRoles, false).SetParent(SetNonCrewCanKill);
NonCrewCanKillNeutral = BooleanOptionItem.Create(Id + 20, "SheriffMadCanKillNeutral", true, TabGroup.CrewmateRoles, false).SetParent(SetNonCrewCanKill);
UsePet = Options.CreatePetUseSetting(Id + 29, CustomRoles.Sheriff);
}
public static void SetUpNeutralOptions(int Id)
{
@@ -94,7 +96,7 @@ public static class Sheriff
ShotLimit.TryAdd(playerId, ShotLimitOpt.GetInt());
Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole().RemoveHtmlTags()} : Shot Limit - {ShotLimit[playerId]}", "Sheriff");
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (Options.UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
-1
View File
@@ -3,7 +3,6 @@ namespace TOHE.Roles.Crewmate
using Hazel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using static TOHE.Options;
+5 -2
View File
@@ -11,11 +11,14 @@ public static class SwordsMan
//public static bool isKilled = false;
public static List<byte> killed = [];
public static OptionItem CanVent;
public static OptionItem UsePet;
public static void SetupCustomOption()
{
Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.SwordsMan);
CanVent = BooleanOptionItem.Create(Id + 11, "CanVent", false, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SwordsMan]);
CanVent = BooleanOptionItem.Create(Id + 11, "CanVent", false, TabGroup.CrewmateRoles, false)
.SetParent(Options.CustomRoleSpawnChances[CustomRoles.SwordsMan]);
UsePet = Options.CreatePetUseSetting(Id + 10, CustomRoles.SwordsMan);
}
public static void Init()
{
@@ -32,7 +35,7 @@ public static class SwordsMan
{
playerIdList.Add(playerId);
if (!AmongUsClient.Instance.AmHost) return;
if (!AmongUsClient.Instance.AmHost || (Options.UsePets.GetBool() && UsePet.GetBool())) return;
if (!Main.ResetCamPlayerList.Contains(playerId))
Main.ResetCamPlayerList.Add(playerId);
}
+10 -8
View File
@@ -18,6 +18,7 @@ namespace TOHE.Roles.Crewmate
public static OptionItem VentCooldown;
public static OptionItem UseLimitOpt;
public static OptionItem TetherAbilityUseGainWithEachTaskCompleted;
public static OptionItem CancelVote;
public static void SetupCustomOption()
{
@@ -25,10 +26,11 @@ namespace TOHE.Roles.Crewmate
VentCooldown = FloatOptionItem.Create(Id + 10, "VentCooldown", new(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
.SetValueFormat(OptionFormat.Seconds);
UseLimitOpt = IntegerOptionItem.Create(Id + 11, "AbilityUseLimit", new(0, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
.SetValueFormat(OptionFormat.Times);
.SetValueFormat(OptionFormat.Times);
TetherAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.4f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
.SetValueFormat(OptionFormat.Times);
.SetParent(CustomRoleSpawnChances[CustomRoles.Tether])
.SetValueFormat(OptionFormat.Times);
CancelVote = CreateVoteCancellingUseSetting(Id + 13, CustomRoles.Tether, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -94,12 +96,9 @@ namespace TOHE.Roles.Crewmate
}, 0.5f, "Tether No Target Boot From Vent");
}
}
public static void OnVote(PlayerControl pc, PlayerControl target)
public static bool OnVote(PlayerControl pc, PlayerControl target)
{
if (pc == null) return;
if (target == null) return;
if (!pc.Is(CustomRoles.Tether)) return;
if (pc.PlayerId == target.PlayerId) return;
if (pc == null || target == null || !pc.Is(CustomRoles.Tether) || pc.PlayerId == target.PlayerId || Main.DontCancelVoteList.Contains(pc.PlayerId)) return false;
if (UseLimit[pc.PlayerId] >= 1)
{
@@ -107,7 +106,10 @@ namespace TOHE.Roles.Crewmate
Target = target.PlayerId;
SendRPC(pc.PlayerId);
SendRPCSyncTarget(Target);
Main.DontCancelVoteList.Add(pc.PlayerId);
return true;
}
return false;
}
public static void OnReportDeadBody()
{
+7 -5
View File
@@ -17,6 +17,7 @@ namespace TOHE.Roles.Crewmate
private static OptionItem CanGetColoredArrow;
public static OptionItem HideVote;
public static OptionItem TrackerAbilityUseGainWithEachTaskCompleted;
public static OptionItem CancelVote;
public static bool CanSeeLastRoomInMeeting;
@@ -37,6 +38,7 @@ namespace TOHE.Roles.Crewmate
TrackerAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 9, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Tracker])
.SetValueFormat(OptionFormat.Times);
CancelVote = CreateVoteCancellingUseSetting(Id + 4, CustomRoles.Tracker, TabGroup.CrewmateRoles);
}
public static void Init()
{
@@ -74,12 +76,9 @@ namespace TOHE.Roles.Crewmate
}
public static string GetTargetMark(PlayerControl seer, PlayerControl target) => !(seer == null || target == null) && TrackerTarget.ContainsKey(seer.PlayerId) && TrackerTarget[seer.PlayerId].Contains(target.PlayerId) ? Utils.ColorString(seer.GetRoleColor(), "◀") : string.Empty;
public static void OnVote(PlayerControl player, PlayerControl target)
public static bool OnVote(PlayerControl player, PlayerControl target)
{
if (player == null || target == null) return;
if (TrackLimit[player.PlayerId] < 1) return;
if (player.PlayerId == target.PlayerId) return;
if (TrackerTarget[player.PlayerId].Contains(target.PlayerId)) return;
if (player == null || target == null || TrackLimit[player.PlayerId] < 1 || player.PlayerId == target.PlayerId || TrackerTarget[player.PlayerId].Contains(target.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
TrackLimit[player.PlayerId]--;
@@ -87,6 +86,9 @@ namespace TOHE.Roles.Crewmate
TargetArrow.Add(player.PlayerId, target.PlayerId);
SendRPC(player.PlayerId, target.PlayerId);
Main.DontCancelVoteList.Add(player.PlayerId);
return true;
}
public static void OnReportDeadBody()
-1
View File
@@ -1,6 +1,5 @@
using Hazel;
using System.Collections.Generic;
using System.Linq;
using TOHE.Roles.Neutral;
using static TOHE.Options;
using static TOHE.Translator;
+13 -9
View File
@@ -27,6 +27,7 @@ internal static class Eraser
private static OptionItem EraseMethod;
private static OptionItem WhenTargetIsNeutral;
public static OptionItem HideVote;
public static OptionItem CancelVote;
private static List<byte> didVote = [];
private static Dictionary<byte, int> EraseLimit = [];
@@ -40,6 +41,7 @@ internal static class Eraser
EraseLimitOpt = IntegerOptionItem.Create(Id + 12, "EraseLimit", new(1, 15, 1), 1, TabGroup.OtherRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser])
.SetValueFormat(OptionFormat.Times);
HideVote = BooleanOptionItem.Create(Id + 13, "EraserHideVote", false, TabGroup.OtherRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]);
CancelVote = Options.CreateVoteCancellingUseSetting(Id + 14, CustomRoles.Eraser, TabGroup.OtherRoles);
}
public static void Init()
{
@@ -103,24 +105,24 @@ internal static class Eraser
return false;
}
public static void OnVote(PlayerControl player, PlayerControl target)
public static bool OnVote(PlayerControl player, PlayerControl target)
{
if (player == null || target == null || EraseMethod.GetInt() == 0) return;
if (didVote.Contains(player.PlayerId)) return;
if (player == null || target == null || EraseMethod.GetInt() == 0) return false;
if (didVote.Contains(player.PlayerId) || Main.DontCancelVoteList.Contains(player.PlayerId)) return false;
didVote.Add(player.PlayerId);
if (EraseLimit.ContainsKey(player.PlayerId) && EraseLimit[player.PlayerId] < 1) return;
if (EraseLimit.ContainsKey(player.PlayerId) && EraseLimit[player.PlayerId] < 1) return false;
if (target.PlayerId == player.PlayerId)
{
Utils.SendMessage(GetString("EraserEraseSelf"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle")));
return;
return false;
}
if (target.GetCustomRole().IsNeutral())
{
Utils.SendMessage(string.Format(GetString("EraserEraseNeutralNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle")));
return;
return false;
}
if (EraseLimit.ContainsKey(player.PlayerId)) EraseLimit[player.PlayerId]--;
@@ -131,7 +133,10 @@ internal static class Eraser
Utils.SendMessage(string.Format(GetString("EraserEraseNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Eraser), GetString("EraserEraseMsgTitle")));
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target);
if (GameStates.IsInTask) Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: target);
Main.DontCancelVoteList.Add(player.PlayerId);
return true;
}
public static void OnReportDeadBody()
{
@@ -143,8 +148,7 @@ internal static class Eraser
foreach (byte pc in PlayerToErase.ToArray())
{
var player = Utils.GetPlayerById(pc);
if (player == null)
continue;
if (player == null) continue;
player.RpcSetCustomRole(CustomRolesHelper.GetErasedRole(player.GetCustomRole()));
player.Notify(GetString("LostRoleByEraser"));
Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()} 被擦除了", "Eraser");
-1
View File
@@ -2,7 +2,6 @@ using AmongUs.GameOptions;
using Hazel;
using Il2CppSystem.Text;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static TOHE.Options;
using static TOHE.Translator;
-1
View File
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using static TOHE.Options;
using static TOHE.Translator;
using static TOHE.Utils;
+1 -1
View File
@@ -53,7 +53,7 @@ internal static class QuickShooter
}
public static void OnShapeshift(PlayerControl pc, bool shapeshifting)
{
if (Main.KillTimers[pc.PlayerId] == 0 && shapeshifting)
if (Main.KillTimers[pc.PlayerId] <= 0 && shapeshifting)
{
ShotLimit[pc.PlayerId]++;
SendRPC(pc.PlayerId);
+2 -1
View File
@@ -64,6 +64,7 @@ namespace TOHE.Roles.Impostor
byte playerId = reader.ReadByte();
YinYangedPlayers.Add(playerId);
}
else YinYangedPlayers.Clear();
}
public static bool OnCheckMurder(PlayerControl killer, PlayerControl target)
@@ -100,8 +101,8 @@ namespace TOHE.Roles.Impostor
public static void OnReportDeadBody()
{
if (!IsEnable) return;
YinYanger_?.ResetKillCooldown();
YinYangedPlayers.Clear();
YinYanger_?.ResetKillCooldown();
SendRPC(true);
}
-1
View File
@@ -1,5 +1,4 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Neutral;
-1
View File
@@ -1,6 +1,5 @@
using Hazel;
using System.Collections.Generic;
using System.Linq;
using TOHE.Roles.Crewmate;
using UnityEngine;
namespace TOHE.Roles.Neutral;
-1
View File
@@ -2,7 +2,6 @@
using Hazel;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static TOHE.Options;
using static TOHE.Utils;
+9 -11
View File
@@ -3,6 +3,7 @@ using Hazel;
using System.Collections.Generic;
using UnityEngine;
using static TOHE.Options;
using static TOHE.Translator;
namespace TOHE.Roles.Neutral;
@@ -98,7 +99,7 @@ public static class WeaponMaster
Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat();
break;
case 3 when shieldUsed:
WM.Notify(Translator.GetString("WMShieldAlreadyUsed"));
WM.Notify(GetString("WMShieldAlreadyUsed"));
break;
}
@@ -119,13 +120,10 @@ public static class WeaponMaster
{
foreach (PlayerControl player in Main.AllAlivePlayerControls)
{
if (Pelican.IsEaten(player.PlayerId)) continue;
if (player == killer) continue;
if (player.Is(CustomRoles.Pestilence) || Main.VeteranInProtect.ContainsKey(target.PlayerId)) continue;
if (Pelican.IsEaten(player.PlayerId) || player == killer || player.Is(CustomRoles.Pestilence) || Main.VeteranInProtect.ContainsKey(target.PlayerId)) continue;
if (Vector2.Distance(killer.transform.position, player.transform.position) <= Radius.GetFloat())
{
player.SetRealKiller(killer);
player.Kill(player);
player.Suicide(PlayerState.DeathReason.Kill, killer);
}
}
killer.SetKillCooldown(time: HighKCD.GetFloat());
@@ -134,7 +132,7 @@ public static class WeaponMaster
case 2:
if (killer.RpcCheckAndMurder(target, true))
{
target.Kill(target);
target.Suicide(PlayerState.DeathReason.Kill, killer);
killer.SetKillCooldown();
}
return false;
@@ -173,10 +171,10 @@ public static class WeaponMaster
{
return mode switch
{
0 => "Sword",
1 => "Axe",
2 => "Lance",
3 => "Shield",
0 => GetString("Sword"),
1 => GetString("Axe"),
2 => GetString("lance"),
3 => GetString("Shield"),
_ => string.Empty,
};
}
+1 -1
View File
@@ -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>
+16 -7
View File
@@ -33,8 +33,8 @@ public class Main : BasePlugin
public static ConfigEntry<string> DebugKeyInput { get; private set; }
public static readonly string MainMenuText = " ";
public const string PluginGuid = "com.gurge44.toheplus";
public const string PluginVersion = "2.1.2";
public const string PluginDisplayVersion = "2.1.2";
public const string PluginVersion = "2.2.0";
public const string PluginDisplayVersion = "2.2.0";
public static readonly string SupportedAUVersion = "2023.10.24";
public const int PluginCreate = 3;
public const bool Canary = false;
@@ -95,6 +95,7 @@ public class Main : BasePlugin
public static float RefixCooldownDelay;
public static bool ProcessShapeshifts = true;
public static Dictionary<byte, (long START_TIMESTAMP, int TOTALCD)> AbilityCD = [];
public static List<byte> DontCancelVoteList = [];
private static GameData.PlayerInfo lastVotedPlayerInfo;
public static string LastVotedPlayer;
public static byte NimblePlayer = byte.MaxValue;
@@ -642,13 +643,16 @@ public enum CustomRoles
{
//Default
Crewmate = 0,
//Impostor(Vanilla)
//Impostors (Vanilla)
Impostor,
Shapeshifter,
// Vanilla Remakes
ImpostorTOHE,
ShapeshifterTOHE,
//Impostor
//Impostors
BountyHunter,
FireWorks,
Mafia,
@@ -727,7 +731,8 @@ public enum CustomRoles
Refugee,
Underdog,
// Flashbang,
//Crewmate(Vanilla)
//Crewmates (Vanilla)
Engineer,
GuardianAngel,
Scientist,
@@ -736,7 +741,9 @@ public enum CustomRoles
EngineerTOHE,
GuardianAngelTOHE,
ScientistTOHE,
//Crewmate
// Crewmate
Luckey,
Needy,
SuperStar,
@@ -831,7 +838,9 @@ public enum CustomRoles
Crusader,
Cleanser,
//Reverie,
//Neutral
//Neutrals
Arsonist,
HexMaster,
Jester,