Warlock rework

This commit is contained in:
Gurge44 committed 2024-03-09 20:27:36 +01:00
1 parent 89d566edb8
commit 42a7936340
46 files changed
+399 -344

No files matched your search

+1 -1
View File
@@ -68,7 +68,7 @@ internal static class CustomRolesHelper
CustomRoles.EvilDiviner => CustomRoles.Impostor,
CustomRoles.Wildling => Wildling.CanShapeshiftOpt.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor,
CustomRoles.Morphling => CustomRoles.Shapeshifter,
CustomRoles.Warlock => CustomRoles.Impostor,
CustomRoles.Warlock => CustomRoles.Shapeshifter,
CustomRoles.SerialKiller => CustomRoles.Impostor,
CustomRoles.FireWorks => CustomRoles.Shapeshifter,
CustomRoles.SpeedBooster => CustomRoles.Crewmate,
+6 -6
View File
@@ -619,20 +619,20 @@ static class ExtendedPlayerControl
public static bool IsDousedPlayer(this PlayerControl arsonist, PlayerControl target)
{
if (arsonist == null || target == null || Main.isDoused == null) return false;
Main.isDoused.TryGetValue((arsonist.PlayerId, target.PlayerId), out bool isDoused);
if (arsonist == null || target == null || Arsonist.isDoused == null) return false;
Arsonist.isDoused.TryGetValue((arsonist.PlayerId, target.PlayerId), out bool isDoused);
return isDoused;
}
public static bool IsDrawPlayer(this PlayerControl arsonist, PlayerControl target)
{
if (arsonist == null || target == null || Main.isDraw == null) return false;
Main.isDraw.TryGetValue((arsonist.PlayerId, target.PlayerId), out bool isDraw);
if (arsonist == null || target == null || Revolutionist.isDraw == null) return false;
Revolutionist.isDraw.TryGetValue((arsonist.PlayerId, target.PlayerId), out bool isDraw);
return isDraw;
}
public static bool IsRevealedPlayer(this PlayerControl player, PlayerControl target)
{
if (player == null || target == null || Main.isRevealed == null) return false;
Main.isRevealed.TryGetValue((player.PlayerId, target.PlayerId), out bool isDoused);
if (player == null || target == null || Farseer.isRevealed == null) return false;
Farseer.isRevealed.TryGetValue((player.PlayerId, target.PlayerId), out bool isDoused);
return isDoused;
}
public static void RpcSetDousedPlayer(this PlayerControl player, PlayerControl target, bool isDoused)
-3
View File
@@ -255,9 +255,6 @@ public static class Options
public static OptionItem EGCanGuessTaskDoneSnitch;
public static OptionItem EGCanGuessTime;
public static OptionItem EGTryHideMsg;
public static OptionItem WarlockCanKillAllies;
public static OptionItem WarlockCanKillSelf;
public static OptionItem WarlockShiftDuration;
public static OptionItem ScavengerKillCooldown;
public static OptionItem ScavengerKillDuration;
public static OptionItem ZombieKillCooldown;
+8 -21
View File
@@ -90,7 +90,6 @@ public enum CustomRPC
SetDarkHiderKillCount,
SetEvilDiviner,
SetGreedierOE,
SetJinxSpellCount,
SetCollectorVotes,
SetQuickShooterShotLimit,
GuessKill,
@@ -359,7 +358,7 @@ internal class RPCHandlerPatch
byte ArsonistId = reader.ReadByte();
byte dousedId = reader.ReadByte();
bool doused = reader.ReadBoolean();
Main.isDoused[(ArsonistId, dousedId)] = doused;
Arsonist.isDoused[(ArsonistId, dousedId)] = doused;
break;
case CustomRPC.SetPlaguedPlayer:
PlagueBearer.ReceiveRPC(reader);
@@ -374,13 +373,13 @@ internal class RPCHandlerPatch
byte RevolutionistId = reader.ReadByte();
byte DrawId = reader.ReadByte();
bool drawed = reader.ReadBoolean();
Main.isDraw[(RevolutionistId, DrawId)] = drawed;
Revolutionist.isDraw[(RevolutionistId, DrawId)] = drawed;
break;
case CustomRPC.SetRevealedPlayer:
byte FarseerId = reader.ReadByte();
byte RevealId = reader.ReadByte();
bool revealed = reader.ReadBoolean();
Main.isRevealed[(FarseerId, RevealId)] = revealed;
Farseer.isRevealed[(FarseerId, RevealId)] = revealed;
break;
case CustomRPC.SetNameColorData:
NameColorManager.ReceiveRPC(reader);
@@ -479,13 +478,13 @@ internal class RPCHandlerPatch
byte arsonistId = reader.ReadByte();
byte dousingTargetId = reader.ReadByte();
if (PlayerControl.LocalPlayer.PlayerId == arsonistId)
Main.currentDousingTarget = dousingTargetId;
Arsonist.currentDousingTarget = dousingTargetId;
break;
case CustomRPC.SetCurrentDrawTarget:
byte arsonistId1 = reader.ReadByte();
byte doTargetId = reader.ReadByte();
if (PlayerControl.LocalPlayer.PlayerId == arsonistId1)
Main.currentDrawTarget = doTargetId;
Revolutionist.currentDrawTarget = doTargetId;
break;
case CustomRPC.SetEvilTrackerTarget:
EvilTracker.ReceiveRPC(reader);
@@ -535,24 +534,12 @@ internal class RPCHandlerPatch
(Main.PlayerStates[id].Role as Greedier)?.ReceiveRPC(isOdd);
}
break;
case CustomRPC.SetJinxSpellCount:
byte JinxId = reader.ReadByte();
int JinxGuardNum = reader.ReadInt32();
if (Main.JinxSpellCount.ContainsKey(JinxId))
Main.JinxSpellCount[JinxId] = JinxGuardNum;
else
Main.JinxSpellCount.Add(JinxId, Jinx.JinxSpellTimes.GetInt());
break;
case CustomRPC.SetCollectorVotes:
Collector.ReceiveRPC(reader);
break;
case CustomRPC.SetQuickShooterShotLimit:
QuickShooter.ReceiveRPC(reader);
break;
//case CustomRPC.RestTOHESetting:
// OptionItem.AllOptions.ToArray().Where(x => x.Id > 0).Do(x => x.SetValueNoRpc(x.DefaultValue));
// OptionShower.GetText();
// break;
case CustomRPC.GuessKill:
GuessManager.RpcClientGuess(Utils.GetPlayerById(reader.ReadByte()));
break;
@@ -1013,7 +1000,7 @@ internal static class RPC
{
if (PlayerControl.LocalPlayer.PlayerId == arsonistId)
{
Main.currentDousingTarget = targetId;
Arsonist.currentDousingTarget = targetId;
}
else
{
@@ -1028,7 +1015,7 @@ internal static class RPC
{
if (PlayerControl.LocalPlayer.PlayerId == arsonistId)
{
Main.currentDrawTarget = targetId;
Revolutionist.currentDrawTarget = targetId;
}
else
{
@@ -1043,7 +1030,7 @@ internal static class RPC
{
if (PlayerControl.LocalPlayer.PlayerId == arsonistId)
{
Main.currentDrawTarget = targetId;
Revolutionist.currentDrawTarget = targetId;
}
else
{
+11 -13
View File
@@ -773,12 +773,6 @@ public static class Utils
return result;
}
public static void GetPetCDSuffix(PlayerControl pc, ref StringBuilder sb)
{
if (Options.UsePets.GetBool() && Main.AbilityCD.TryGetValue(pc.PlayerId, out var time) && !pc.IsModClient())
sb.Append(string.Format(GetString("CDPT"), time.TOTALCD - (TimeStamp - time.START_TIMESTAMP) + 1));
}
public static string GetFormattedRoomName(string roomName) => roomName == "Outside" ? "<#00ffa5>Outside</color>" : $"<#ffffff>In</color> <#00ffa5>{roomName}</color>";
public static string GetFormattedVectorText(Vector2 pos) => $"<#777777>(at {pos.ToString().Replace("(", string.Empty).Replace(")", string.Empty)})</color>";
@@ -1678,7 +1672,7 @@ public static class Utils
public static GameData.PlayerInfo GetPlayerInfoById(int PlayerId) => GameData.Instance.AllPlayers.ToArray().FirstOrDefault(info => info.PlayerId == PlayerId);
private static StringBuilder SelfSuffix = new();
private static readonly StringBuilder SelfSuffix = new();
private static readonly StringBuilder SelfMark = new(20);
private static readonly StringBuilder TargetSuffix = new();
private static readonly StringBuilder TargetMark = new(20);
@@ -1745,7 +1739,8 @@ public static class Utils
if (!isForMeeting)
{
GetPetCDSuffix(seer, ref SelfSuffix);
if (Options.UsePets.GetBool() && Main.AbilityCD.TryGetValue(seer.PlayerId, out var time) && !seer.IsModClient())
SelfSuffix.Append(string.Format(GetString("CDPT"), time.TOTALCD - (TimeStamp - time.START_TIMESTAMP) + 1));
if (seer.Is(CustomRoles.Asthmatic)) SelfSuffix.Append(Asthmatic.GetSuffixText(seer.PlayerId));
@@ -1846,6 +1841,9 @@ public static class Utils
case CustomRoles.Predator:
SelfSuffix.Append(Predator.GetSuffixAndHudText(seer));
break;
case CustomRoles.Warlock:
SelfSuffix.Append(Warlock.GetSuffixAndHudText(seer));
break;
}
}
else
@@ -1909,7 +1907,7 @@ public static class Utils
SelfName = seer.GetCustomRole() switch
{
CustomRoles.Arsonist when seer.IsDouseDone() => $"{ColorString(seer.GetRoleColor(), GetString("EnterVentToWin"))}",
CustomRoles.Revolutionist when seer.IsDrawDone() => $">{ColorString(seer.GetRoleColor(), string.Format(GetString("EnterVentWinCountDown"), Main.RevolutionistCountdown.GetValueOrDefault(seer.PlayerId, 10)))}",
CustomRoles.Revolutionist when seer.IsDrawDone() => $">{ColorString(seer.GetRoleColor(), string.Format(GetString("EnterVentWinCountDown"), Revolutionist.RevolutionistCountdown.GetValueOrDefault(seer.PlayerId, 10)))}",
_ => SelfName
};
@@ -2001,7 +1999,7 @@ public static class Utils
TargetMark.Append($"<color={GetRoleColorCode(CustomRoles.Arsonist)}>▲</color>");
}
else if (Main.ArsonistTimer.TryGetValue(seer.PlayerId, out var ar_kvp) && ar_kvp.PLAYER == target)
else if (Arsonist.ArsonistTimer.TryGetValue(seer.PlayerId, out var ar_kvp) && ar_kvp.PLAYER == target)
{
TargetMark.Append($"<color={GetRoleColorCode(CustomRoles.Arsonist)}>△</color>");
}
@@ -2013,7 +2011,7 @@ public static class Utils
TargetMark.Append($"<color={GetRoleColorCode(CustomRoles.Revolutionist)}>●</color>");
}
if (Main.RevolutionistTimer.TryGetValue(seer.PlayerId, out var ar_kvp1) && ar_kvp1.PLAYER == target)
if (Revolutionist.RevolutionistTimer.TryGetValue(seer.PlayerId, out var ar_kvp1) && ar_kvp1.PLAYER == target)
{
TargetMark.Append($"<color={GetRoleColorCode(CustomRoles.Revolutionist)}>○</color>");
}
@@ -2580,7 +2578,7 @@ public static class Utils
if (pc.PlayerId == playerId)
continue;
all++;
if (Main.isDoused.TryGetValue((playerId, pc.PlayerId), out var isDoused) && isDoused)
if (Arsonist.isDoused.TryGetValue((playerId, pc.PlayerId), out var isDoused) && isDoused)
doused++;
}
@@ -2595,7 +2593,7 @@ public static class Utils
if (!Main.PlayerStates[playerId].IsDead) max--;
winnerList = [];
if (all > max) all = max;
foreach (var pc in Main.AllPlayerControls.Where(pc => Main.isDraw.TryGetValue((playerId, pc.PlayerId), out var isDraw) && isDraw).ToArray())
foreach (var pc in Main.AllPlayerControls.Where(pc => Revolutionist.isDraw.TryGetValue((playerId, pc.PlayerId), out var isDraw) && isDraw).ToArray())
{
winnerList.Add(pc);
draw++;
+6 -6
View File
@@ -952,12 +952,12 @@ internal class ChatCommands
Utils.SendMessage(devMark == "▲" ? string.Format(GetString("Message.YTPlanSelected"), roleName) : string.Format(GetString("Message.YTPlanSelectFailed"), roleName), playerId);
}
if (devMark == "▲")
{
byte pid = playerId == 255 ? (byte)0 : playerId;
_ = Main.DevRole.Remove(pid);
Main.DevRole.Add(pid, rl);
}
//if (devMark == "▲")
//{
// byte pid = playerId == 255 ? (byte)0 : playerId;
// _ = Main.DevRole.Remove(pid);
// Main.DevRole.Add(pid, rl);
//}
if (isUp) return;
}
+1 -1
View File
@@ -135,7 +135,7 @@ class GameEndChecker
WinnerIds.Add(pc.PlayerId);
AdditionalWinnerTeams.Add(AdditionalWinners.Maverick);
break;
case CustomRoles.Provocateur when Main.Provoked.TryGetValue(pc.PlayerId, out var tar) && !WinnerIds.Contains(tar):
case CustomRoles.Provocateur when Provocateur.Provoked.TryGetValue(pc.PlayerId, out var tar) && !WinnerIds.Contains(tar):
WinnerIds.Add(pc.PlayerId);
AdditionalWinnerTeams.Add(AdditionalWinners.Provocateur);
break;
+2 -2
View File
@@ -139,8 +139,8 @@ class ExileControllerWrapUpPatch
{
if (pc.Is(CustomRoles.Warlock))
{
Main.CursedPlayers[pc.PlayerId] = null;
Main.isCurseAndKill[pc.PlayerId] = false;
Warlock.CursedPlayers[pc.PlayerId] = null;
Warlock.isCurseAndKill[pc.PlayerId] = false;
//RPC.RpcSyncCurseAndKill();
}
+2
View File
@@ -384,6 +384,8 @@ class HudManagerPatch
CustomRoles.Mafioso => Mafioso.GetHUDText(player),
CustomRoles.Druid => Druid.GetHUDText(player),
CustomRoles.Rabbit => Rabbit.GetSuffix(player),
CustomRoles.Predator => Predator.GetSuffixAndHudText(player, hud: true),
CustomRoles.Warlock => Warlock.GetSuffixAndHudText(player, hud: true),
CustomRoles.Librarian => Librarian.GetSelfSuffixAndHudText(player.PlayerId),
CustomRoles.PlagueDoctor => PlagueDoctor.GetLowerTextOthers(player, isForHud: true),
CustomRoles.Stealth => Stealth.GetSuffix(player, isHUD: true),
+2 -2
View File
@@ -281,13 +281,13 @@ public static class HudSpritePatch
if (Options.UsePets.GetBool())
{
newKillButton = CustomButton.Get("Curse");
if (Main.isCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse)
if (Warlock.isCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse)
newAbilityButton = CustomButton.Get("CurseKill");
}
else if (!shapeshifting)
{
newKillButton = CustomButton.Get("Curse");
if (Main.isCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse)
if (Warlock.isCurseAndKill.TryGetValue(player.PlayerId, out bool curse) && curse)
newAbilityButton = CustomButton.Get("CurseKill");
}
+6 -6
View File
@@ -644,9 +644,9 @@ class MeetingHudStartPatch
if (MeetingStates.FirstMeeting && CustomRoles.Workaholic.RoleExist() && Options.WorkaholicGiveAdviceAlive.GetBool() && !Options.WorkaholicCannotWinAtDeath.GetBool() /* && !Options.GhostIgnoreTasks.GetBool()*/)
{
foreach (var pc in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Workaholic)).ToArray())
Main.WorkaholicAlive.Add(pc.PlayerId);
Workaholic.WorkaholicAlive.Add(pc.PlayerId);
List<string> workaholicAliveList = [];
workaholicAliveList.AddRange(Main.WorkaholicAlive.Select(whId => Main.AllPlayerNames[whId]));
workaholicAliveList.AddRange(Workaholic.WorkaholicAlive.Select(whId => Main.AllPlayerNames[whId]));
string separator = TranslationController.Instance.currentLanguage.languageID is SupportedLangs.English or SupportedLangs.Russian ? "], [" : "】, 【";
AddMsg(string.Format(GetString("WorkaholicAdviceAlive"), string.Join(separator, workaholicAliveList)), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Workaholic), GetString("WorkaholicAliveTitle")));
@@ -684,7 +684,7 @@ class MeetingHudStartPatch
AddMsg(string.Format(GetString("BlackmailerDead"), playername, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Blackmailer), GetString("BlackmaileKillTitle"))));
}
if (Main.DetectiveNotify.TryGetValue(pc.PlayerId, out string value1))
if (Detective.DetectiveNotify.TryGetValue(pc.PlayerId, out string value1))
AddMsg(value1, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Detective), GetString("DetectiveNoticeTitle")));
if (Main.SleuthMsgs.TryGetValue(pc.PlayerId, out string msg))
AddMsg(msg, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Sleuth), GetString("Sleuth")));
@@ -701,7 +701,7 @@ class MeetingHudStartPatch
AddMsg(string.Format(GetString("MediumshipNotifySelf"), Main.AllPlayerNames[Mediumshiper.ContactPlayer.FirstOrDefault(x => x.Value == pc.PlayerId).Key], pc.GetAbilityUseLimit()), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Mediumshiper), GetString("MediumshipTitle")));
if (Mediumshiper.ContactPlayer.ContainsKey(pc.PlayerId) && (!Mediumshiper.OnlyReceiveMsgFromCrew.GetBool() || pc.GetCustomRole().IsCrewmate()))
AddMsg(string.Format(GetString("MediumshipNotifyTarget"), Main.AllPlayerNames[Mediumshiper.ContactPlayer[pc.PlayerId]]), pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Mediumshiper), GetString("MediumshipTitle")));
if (Main.VirusNotify.TryGetValue(pc.PlayerId, out string value3))
if (Virus.VirusNotify.TryGetValue(pc.PlayerId, out string value3))
AddMsg(value3, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Virus), GetString("VirusNoticeTitle")));
if (Enigma.MsgToSend.TryGetValue(pc.PlayerId, out string value4))
AddMsg(value4, pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Enigma), Enigma.MsgToSendTitle[pc.PlayerId]));
@@ -717,9 +717,9 @@ class MeetingHudStartPatch
Main.CyberStarDead.Clear();
Express.SpeedNormal.Clear();
Express.SpeedUp.Clear();
Main.DetectiveNotify.Clear();
Detective.DetectiveNotify.Clear();
Main.SleuthMsgs.Clear();
Main.VirusNotify.Clear();
Virus.VirusNotify.Clear();
Mortician.msgToSend.Clear();
Enigma.MsgToSend.Clear();
return;
+4 -3
View File
@@ -5,6 +5,7 @@ using System.Linq;
using System.Text;
using TMPro;
using TOHE.Modules;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Neutral;
using UnityEngine;
using static TOHE.Translator;
@@ -97,9 +98,9 @@ class EndGamePatch
Main.winnerRolesList.Add(pc.GetCustomRole());
}
Main.isDoused = [];
Main.isDraw = [];
Main.isRevealed = [];
Arsonist.isDoused = [];
Revolutionist.isDraw = [];
Farseer.isRevealed = [];
Main.VisibleTasksCount = false;
if (AmongUsClient.Instance.AmHost)
+25 -24
View File
@@ -334,14 +334,14 @@ class CheckMurderPatch
}
}
if (Main.ForCrusade.Contains(target.PlayerId))
if (Crusader.ForCrusade.Contains(target.PlayerId))
{
foreach (PlayerControl player in Main.AllPlayerControls)
{
if (player.Is(CustomRoles.Crusader) && player.IsAlive() && !killer.Is(CustomRoles.Pestilence) && !killer.Is(CustomRoles.Minimalism))
{
player.Kill(killer);
Main.ForCrusade.Remove(target.PlayerId);
Crusader.ForCrusade.Remove(target.PlayerId);
killer.RpcGuardAndKill(target);
return false;
}
@@ -349,7 +349,7 @@ class CheckMurderPatch
if (player.Is(CustomRoles.Crusader) && player.IsAlive() && killer.Is(CustomRoles.Pestilence))
{
killer.Kill(player);
Main.ForCrusade.Remove(target.PlayerId);
Crusader.ForCrusade.Remove(target.PlayerId);
target.RpcGuardAndKill(killer);
Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.PissedOff;
return false;
@@ -433,7 +433,7 @@ class MurderPlayerPatch
if (target.AmOwner) RemoveDisableDevicesPatch.UpdateDisableDevices();
if (!target.Data.IsDead || !AmongUsClient.Instance.AmHost) return;
if (Main.OverDeadPlayerList.Contains(target.PlayerId)) return;
if (OverKiller.OverDeadPlayerList.Contains(target.PlayerId)) return;
PlayerControl killer = __instance; // Alternative variable
if (target.PlayerId == Godfather.GodfatherTarget) killer.RpcSetCustomRole(CustomRoles.Refugee);
@@ -741,8 +741,7 @@ class ReportDeadBodyPatch
if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Gambled
|| killerRole == CustomRoles.Scavenger
|| Main.CleanerBodies.Contains(target.PlayerId)
|| Main.MedusaBodies.Contains(target.PlayerId)) return false;
|| Cleaner.CleanerBodies.Contains(target.PlayerId)) return false;
var tpc = GetPlayerById(target.PlayerId);
@@ -828,7 +827,7 @@ class ReportDeadBodyPatch
{
if (player.Is(CustomRoles.Mayor))
{
Main.MayorUsedButtonCount[player.PlayerId] += 1;
Mayor.MayorUsedButtonCount[player.PlayerId] += 1;
}
}
else
@@ -847,7 +846,7 @@ class ReportDeadBodyPatch
}
}
if (Main.InfectedBodies.Contains(target.PlayerId)) Virus.OnKilledBodyReport(player);
if (Virus.InfectedBodies.Contains(target.PlayerId)) Virus.OnKilledBodyReport(player);
}
Enigma.OnReportDeadBody(player, target);
@@ -857,16 +856,15 @@ class ReportDeadBodyPatch
Main.LastVotedPlayerInfo = null;
Witness.AllKillers.Clear();
Main.ArsonistTimer.Clear();
Arsonist.ArsonistTimer.Clear();
Farseer.FarseerTimer.Clear();
Puppeteer.PuppeteerList.Clear();
Puppeteer.PuppeteerDelayList.Clear();
Main.TaglockedList.Clear();
Main.GuesserGuessed.Clear();
Main.VeteranInProtect.Clear();
Veteran.VeteranInProtect.Clear();
Grenadier.GrenadierBlinding.Clear();
Main.BlockSabo.Clear();
Main.BlockedVents.Clear();
SecurityGuard.BlockSabo.Clear();
Ventguard.BlockedVents.Clear();
Grenadier.MadGrenadierBlinding.Clear();
Divinator.didVote.Clear();
Oracle.didVote.Clear();
@@ -1247,7 +1245,7 @@ class FixedUpdatePatch
if (target.Is(CustomRoles.Arsonist) && target.IsDouseDone())
RealName = ColorString(GetRoleColor(CustomRoles.Arsonist), GetString("EnterVentToWin"));
else if (target.Is(CustomRoles.Revolutionist) && target.IsDrawDone())
RealName = ColorString(GetRoleColor(CustomRoles.Revolutionist), string.Format(GetString("EnterVentWinCountDown"), Main.RevolutionistCountdown.GetValueOrDefault(seer.PlayerId, 10)));
RealName = ColorString(GetRoleColor(CustomRoles.Revolutionist), string.Format(GetString("EnterVentWinCountDown"), Revolutionist.RevolutionistCountdown.GetValueOrDefault(seer.PlayerId, 10)));
if (Pelican.IsEaten(seer.PlayerId))
RealName = ColorString(GetRoleColor(CustomRoles.Pelican), GetString("EatenByPelican"));
@@ -1314,8 +1312,8 @@ class FixedUpdatePatch
Mark.Append($"<color={GetRoleColorCode(CustomRoles.Arsonist)}>▲</color>");
}
else if (
Main.currentDousingTarget != byte.MaxValue &&
Main.currentDousingTarget == target.PlayerId
Arsonist.currentDousingTarget != byte.MaxValue &&
Arsonist.currentDousingTarget == target.PlayerId
)
{
Mark.Append($"<color={GetRoleColorCode(CustomRoles.Arsonist)}>△</color>");
@@ -1328,8 +1326,8 @@ class FixedUpdatePatch
Mark.Append($"<color={GetRoleColorCode(CustomRoles.Revolutionist)}>●</color>");
}
else if (
Main.currentDrawTarget != byte.MaxValue &&
Main.currentDrawTarget == target.PlayerId
Revolutionist.currentDrawTarget != byte.MaxValue &&
Revolutionist.currentDrawTarget == target.PlayerId
)
{
Mark.Append($"<color={GetRoleColorCode(CustomRoles.Revolutionist)}>○</color>");
@@ -1337,8 +1335,8 @@ class FixedUpdatePatch
break;
case CustomRoles.Farseer:
if (Main.currentDrawTarget != byte.MaxValue &&
Main.currentDrawTarget == target.PlayerId)
if (Revolutionist.currentDrawTarget != byte.MaxValue &&
Revolutionist.currentDrawTarget == target.PlayerId)
{
Mark.Append($"<color={GetRoleColorCode(CustomRoles.Farseer)}>○</color>");
}
@@ -1421,6 +1419,9 @@ class FixedUpdatePatch
case CustomRoles.Predator when seer.PlayerId == target.PlayerId:
Suffix.Append(Predator.GetSuffixAndHudText(seer));
break;
case CustomRoles.Warlock when seer.PlayerId == target.PlayerId:
Suffix.Append(Warlock.GetSuffixAndHudText(seer));
break;
}
Mark.Append(Totocalcio.TargetMark(seer, target));
@@ -1663,7 +1664,7 @@ class EnterVentPatch
switch (pc.GetCustomRole())
{
case CustomRoles.Mayor when !Options.UsePets.GetBool() && Main.MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var count2) && count2 < Options.MayorNumOfUseButton.GetInt():
case CustomRoles.Mayor when !Options.UsePets.GetBool() && Mayor.MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var count2) && count2 < Options.MayorNumOfUseButton.GetInt():
pc.MyPhysics?.RpcBootFromVent(__instance.Id);
pc.ReportDeadBody(null);
break;
@@ -1761,7 +1762,7 @@ class CoEnterVentPatch
return true;
}
if (Main.BlockedVents.Contains(id))
if (Ventguard.BlockedVents.Contains(id))
{
var pc = __instance.myPlayer;
if (Options.VentguardBlockDoesNotAffectCrew.GetBool() && pc.GetCustomRole().IsCrewmate())
@@ -1790,8 +1791,8 @@ class CoEnterVentPatch
if (Main.NormalOptions.MapId == (int)MapNames.Dleks || ((__instance.myPlayer.Data.Role.Role != RoleTypes.Engineer &&
!__instance.myPlayer.CanUseImpostorVentButton()) ||
(__instance.myPlayer.Is(CustomRoles.Mayor) && Main.MayorUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out var count) && count >= Options.MayorNumOfUseButton.GetInt()) ||
(__instance.myPlayer.Is(CustomRoles.Paranoia) && Main.ParaUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out var count2) && count2 >= Options.ParanoiaNumOfUseButton.GetInt()))
(__instance.myPlayer.Is(CustomRoles.Mayor) && Mayor.MayorUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out var count) && count >= Options.MayorNumOfUseButton.GetInt()) ||
(__instance.myPlayer.Is(CustomRoles.Paranoia) && Paranoia.ParaUsedButtonCount.TryGetValue(__instance.myPlayer.PlayerId, out var count2) && count2 >= Options.ParanoiaNumOfUseButton.GetInt()))
&& !__instance.myPlayer.Is(CustomRoles.Nimble))
{
try
-1
View File
@@ -35,7 +35,6 @@ class OnGameJoinedPatch
GameStartManagerPatch.GameStartManagerUpdatePatch.exitTimer = -1;
Main.DoBlockNameChange = false;
Main.newLobby = true;
Main.DevRole = [];
EAC.DeNum = new();
Main.AllPlayerNames = [];
+2 -1
View File
@@ -1,6 +1,7 @@
using HarmonyLib;
using Hazel;
using System.Linq;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Neutral;
namespace TOHE;
@@ -252,7 +253,7 @@ public static class SabotageSystemTypeRepairDamagePatch
public static bool Prefix([HarmonyArgument(0)] PlayerControl player)
{
if (Options.DisableSabotage.GetBool() || Options.CurrentGameMode is CustomGameMode.SoloKombat or CustomGameMode.FFA or CustomGameMode.MoveAndStop or CustomGameMode.HotPotato) return false;
if (Main.BlockSabo.Count > 0) return false;
if (SecurityGuard.BlockSabo.Count > 0) return false;
if (Glitch.hackedIdList.ContainsKey(player.PlayerId))
{
player.Notify(string.Format(Translator.GetString("HackedByGlitch"), "Sabotage"));
+2 -2
View File
@@ -118,7 +118,7 @@ class RepairSystemPatch
break;
case SystemTypes.Sabotage when AmongUsClient.Instance.NetworkMode != NetworkModes.FreePlay:
if (Options.CurrentGameMode is CustomGameMode.SoloKombat or CustomGameMode.FFA or CustomGameMode.MoveAndStop or CustomGameMode.HotPotato) return false;
if (Main.BlockSabo.Count > 0) return false;
if (SecurityGuard.BlockSabo.Count > 0) return false;
if (Glitch.hackedIdList.ContainsKey(player.PlayerId))
{
player.Notify(string.Format(Translator.GetString("HackedByGlitch"), "Sabotage"));
@@ -229,7 +229,7 @@ class CloseDoorsPatch
{
bool allow = !Options.DisableSabotage.GetBool() && Options.CurrentGameMode is not CustomGameMode.SoloKombat and not CustomGameMode.FFA and not CustomGameMode.MoveAndStop;
if (Main.BlockSabo.Count > 0) allow = false;
if (SecurityGuard.BlockSabo.Count > 0) allow = false;
if (Options.DisableCloseDoor.GetBool()) allow = false;
Logger.Info($"({room}) => {(allow ? "Allowed" : "Blocked")}", "DoorClose");
+32 -40
View File
@@ -10,6 +10,7 @@ using TOHE.Roles.AddOns.Crewmate;
using TOHE.Roles.AddOns.Impostor;
using TOHE.Roles.Crewmate;
using TOHE.Roles.Impostor;
using TOHE.Roles.Neutral;
using static TOHE.Modules.CustomRoleSelector;
using static TOHE.Translator;
@@ -23,7 +24,6 @@ internal class ChangeRoleSettings
Main.OverrideWelcomeMsg = string.Empty;
try
{
//注:この時点では役職は設定されていません。
Main.NormalOptions.roleOptions.SetRoleRate(RoleTypes.GuardianAngel, 0, 0);
if (Options.DisableVanillaRoles.GetBool())
{
@@ -50,39 +50,33 @@ internal class ChangeRoleSettings
Main.AllPlayerKillCooldown = [];
Main.AllPlayerSpeed = [];
Main.KillTimers = [];
Main.WarlockTimer = [];
Main.AssassinTimer = [];
Main.UndertakerTimer = [];
Main.isDoused = [];
Main.isDraw = [];
Main.isRevealed = [];
Main.ArsonistTimer = [];
Main.RevolutionistTimer = [];
Main.RevolutionistStart = [];
Main.RevolutionistLastTime = [];
Main.RevolutionistCountdown = [];
Main.TimeMasterBackTrack = [];
Main.TimeMasterNum = [];
Warlock.WarlockTimer = [];
Arsonist.isDoused = [];
Revolutionist.isDraw = [];
Farseer.isRevealed = [];
Arsonist.ArsonistTimer = [];
Revolutionist.RevolutionistTimer = [];
Revolutionist.RevolutionistStart = [];
Revolutionist.RevolutionistLastTime = [];
Revolutionist.RevolutionistCountdown = [];
TimeMaster.TimeMasterBackTrack = [];
TimeMaster.TimeMasterNum = [];
Farseer.FarseerTimer = [];
Main.CursedPlayers = [];
Main.MafiaRevenged = [];
Main.isCurseAndKill = [];
Main.isCursed = false;
Main.TaglockedList = [];
Main.DetectiveNotify = [];
Warlock.CursedPlayers = [];
Mafia.MafiaRevenged = [];
Warlock.isCurseAndKill = [];
Warlock.isCursed = false;
Detective.DetectiveNotify = [];
Main.SleuthMsgs = [];
Main.ForCrusade = [];
Main.KillGhoul = [];
Crusader.ForCrusade = [];
Main.CyberStarDead = [];
Main.KilledDiseased = [];
Main.KilledAntidote = [];
Main.WorkaholicAlive = [];
Main.SpeedrunnerAlive = [];
Workaholic.WorkaholicAlive = [];
Main.BaitAlive = [];
Main.CleanerBodies = [];
Main.MedusaBodies = [];
Main.InfectedBodies = [];
Main.VirusNotify = [];
Cleaner.CleanerBodies = [];
Virus.InfectedBodies = [];
Virus.VirusNotify = [];
Main.DontCancelVoteList = [];
Main.LastEnteredVent = [];
@@ -94,19 +88,17 @@ internal class ChangeRoleSettings
Main.CheckShapeshift = [];
Main.ShapeshiftTarget = [];
Main.SpeedBoostTarget = [];
Main.MayorUsedButtonCount = [];
Main.ParaUsedButtonCount = [];
Main.MarioVentCount = [];
Main.VeteranInProtect = [];
Mayor.MayorUsedButtonCount = [];
Paranoia.ParaUsedButtonCount = [];
Mario.MarioVentCount = [];
Veteran.VeteranInProtect = [];
Witness.AllKillers = [];
Grenadier.GrenadierBlinding = [];
Main.BlockSabo = [];
Main.BlockedVents = [];
SecurityGuard.BlockSabo = [];
Ventguard.BlockedVents = [];
Grenadier.MadGrenadierBlinding = [];
Main.JinxSpellCount = [];
Main.OverDeadPlayerList = [];
Main.Provoked = [];
OverKiller.OverDeadPlayerList = [];
Provocateur.Provoked = [];
Main.ShieldPlayer = Options.ShieldPersonDiedFirst.GetBool() ? Main.FirstDied : byte.MaxValue;
Main.FirstDied = byte.MaxValue;
Main.MadmateNum = 0;
@@ -131,8 +123,8 @@ internal class ChangeRoleSettings
Main.LastNotifyNames = [];
Main.currentDousingTarget = byte.MaxValue;
Main.currentDrawTarget = byte.MaxValue;
Arsonist.currentDousingTarget = byte.MaxValue;
Revolutionist.currentDrawTarget = byte.MaxValue;
Main.PlayerColors = [];
//名前の記録
+1
View File
@@ -1125,6 +1125,7 @@
"RemainingText.EjectionSuffix.NKSingle": "remains.",
"RemainingText.EjectionSuffix.NKPlural": "remain.",
"Cooldown": "Cooldown",
"CurseCooldown": "Curse Cooldown",
"KillCooldown": "Kill Cooldown",
"VentCooldown": "Vent Cooldown",
"MaxInVentTime": "Max In-Vent Time",
+2 -2
View File
@@ -72,14 +72,14 @@ public class CopyCat : RoleBase
Merchant.bribedKiller.Remove(player);
break;
case CustomRoles.Paranoia:
Main.ParaUsedButtonCount.Remove(player);
Paranoia.ParaUsedButtonCount.Remove(player);
break;
case CustomRoles.Snitch:
Snitch.IsExposed.Remove(player);
Snitch.IsComplete.Remove(player);
break;
case CustomRoles.Mayor:
Main.MayorUsedButtonCount.Remove(player);
Mayor.MayorUsedButtonCount.Remove(player);
break;
}
+4 -2
View File
@@ -8,6 +8,8 @@ public class Crusader : RoleBase
private const int Id = 20050;
private static List<byte> playerIdList = [];
public static List<byte> ForCrusade = [];
public static OptionItem SkillLimitOpt;
public static OptionItem SkillCooldown;
public static OptionItem UsePet;
@@ -54,8 +56,8 @@ public class Crusader : RoleBase
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
if (killer.GetAbilityUseLimit() <= 0) return false;
Main.ForCrusade.Remove(target.PlayerId);
Main.ForCrusade.Add(target.PlayerId);
ForCrusade.Remove(target.PlayerId);
ForCrusade.Add(target.PlayerId);
killer.RpcRemoveAbilityUse();
killer.ResetKillCooldown();
killer.SetKillCooldown();
+6 -2
View File
@@ -1,7 +1,11 @@
namespace TOHE.Roles.Crewmate
using System.Collections.Generic;
namespace TOHE.Roles.Crewmate
{
internal static class Detective
{
public static Dictionary<byte, string> DetectiveNotify = [];
public static void SetupCustomOption()
{
Options.SetupRoleOptions(6600, TabGroup.CrewmateRoles, CustomRoles.Detective);
@@ -19,7 +23,7 @@
else msg += ";" + string.Format(Translator.GetString("DetectiveNoticeKiller"), realKiller.GetDisplayRoleName());
}
Main.DetectiveNotify.Add(player.PlayerId, msg);
DetectiveNotify.Add(player.PlayerId, msg);
}
}
}
+4 -3
View File
@@ -14,6 +14,7 @@ namespace TOHE.Roles.Crewmate
public class Farseer : RoleBase
{
public static Dictionary<byte, (PlayerControl PLAYER, float TIMER)> FarseerTimer = [];
public static Dictionary<(byte, byte), bool> isRevealed = [];
private const int Id = 9700;
@@ -54,7 +55,7 @@ namespace TOHE.Roles.Crewmate
foreach (PlayerControl ar in Main.AllPlayerControls)
{
Main.isRevealed[(playerId, ar.PlayerId)] = false;
isRevealed[(playerId, ar.PlayerId)] = false;
}
RandomRole[playerId] = GetRandomCrewRoleString();
@@ -84,7 +85,7 @@ namespace TOHE.Roles.Crewmate
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
killer.SetKillCooldown(FarseerRevealTime.GetFloat());
if (!Main.isRevealed[(killer.PlayerId, target.PlayerId)] && !FarseerTimer.ContainsKey(killer.PlayerId))
if (!isRevealed[(killer.PlayerId, target.PlayerId)] && !FarseerTimer.ContainsKey(killer.PlayerId))
{
FarseerTimer.TryAdd(killer.PlayerId, (target, 0f));
NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true);
@@ -117,7 +118,7 @@ namespace TOHE.Roles.Crewmate
if (UsePets.GetBool()) player.AddKCDAsAbilityCD();
else player.SetKillCooldown();
FarseerTimer.Remove(player.PlayerId);
Main.isRevealed[(player.PlayerId, ar_target.PlayerId)] = true;
isRevealed[(player.PlayerId, ar_target.PlayerId)] = true;
player.RpcSetRevealtPlayer(ar_target, true);
NotifyRoles(SpecifySeer: player, SpecifyTarget: ar_target);
RPC.ResetCurrentRevealTarget(player.PlayerId);
+6 -3
View File
@@ -1,17 +1,20 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Crewmate
{
internal class Mayor : RoleBase
{
public static Dictionary<byte, int> MayorUsedButtonCount = [];
public static bool On;
public override bool IsEnable => On;
public override void Add(byte playerId)
{
On = true;
Main.MayorUsedButtonCount[playerId] = 0;
MayorUsedButtonCount[playerId] = 0;
}
public override void Init()
@@ -23,7 +26,7 @@ namespace TOHE.Roles.Crewmate
{
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown =
!Main.MayorUsedButtonCount.TryGetValue(playerId, out var count) || count < MayorNumOfUseButton.GetInt()
!MayorUsedButtonCount.TryGetValue(playerId, out var count) || count < MayorNumOfUseButton.GetInt()
? opt.GetInt(Int32OptionNames.EmergencyCooldown)
: 300f;
AURoleOptions.EngineerInVentMaxTime = 1f;
@@ -52,7 +55,7 @@ namespace TOHE.Roles.Crewmate
{
if (!MayorHasPortableButton.GetBool()) return;
if (Main.MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var count) && count < MayorNumOfUseButton.GetInt())
if (MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var count) && count < MayorNumOfUseButton.GetInt())
{
pc.ReportDeadBody(null);
}
+8 -5
View File
@@ -1,10 +1,13 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Crewmate
{
internal class Paranoia : RoleBase
{
public static Dictionary<byte, int> ParaUsedButtonCount = [];
public static bool On;
public override bool IsEnable => On;
@@ -22,7 +25,7 @@ namespace TOHE.Roles.Crewmate
public override void Add(byte playerId)
{
On = true;
Main.ParaUsedButtonCount[playerId] = 0;
ParaUsedButtonCount[playerId] = 0;
}
public override void Init()
@@ -34,7 +37,7 @@ namespace TOHE.Roles.Crewmate
{
if (UsePets.GetBool()) return;
AURoleOptions.EngineerCooldown =
!Main.ParaUsedButtonCount.TryGetValue(playerId, out var count2) || count2 < ParanoiaNumOfUseButton.GetInt()
!ParaUsedButtonCount.TryGetValue(playerId, out var count2) || count2 < ParanoiaNumOfUseButton.GetInt()
? ParanoiaVentCooldown.GetFloat()
: 300f;
AURoleOptions.EngineerInVentMaxTime = 1f;
@@ -61,12 +64,12 @@ namespace TOHE.Roles.Crewmate
static void Panic(PlayerControl pc)
{
if (Main.ParaUsedButtonCount.TryGetValue(pc.PlayerId, out var count2) && count2 < ParanoiaNumOfUseButton.GetInt())
if (ParaUsedButtonCount.TryGetValue(pc.PlayerId, out var count2) && count2 < ParanoiaNumOfUseButton.GetInt())
{
Main.ParaUsedButtonCount[pc.PlayerId] += 1;
ParaUsedButtonCount[pc.PlayerId] += 1;
if (AmongUsClient.Instance.AmHost)
{
_ = new LateTask(() => { Utils.SendMessage(Translator.GetString("SkillUsedLeft") + (ParanoiaNumOfUseButton.GetInt() - Main.ParaUsedButtonCount[pc.PlayerId]), pc.PlayerId); }, 4.0f, "Paranoia Skill Remain Message");
_ = new LateTask(() => { Utils.SendMessage(Translator.GetString("SkillUsedLeft") + (ParanoiaNumOfUseButton.GetInt() - ParaUsedButtonCount[pc.PlayerId]), pc.PlayerId); }, 4.0f, "Paranoia Skill Remain Message");
}
pc.NoCheckStartMeeting(pc.Data);
+9 -6
View File
@@ -1,11 +1,14 @@
using AmongUs.GameOptions;
using System.Text;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Crewmate
{
internal class SecurityGuard : RoleBase
{
public static Dictionary<byte, long> BlockSabo = [];
public static bool On;
public override bool IsEnable => On;
@@ -51,7 +54,7 @@ namespace TOHE.Roles.Crewmate
{
var ProgressText = new StringBuilder();
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, Main.BlockSabo.ContainsKey(playerId)));
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, BlockSabo.ContainsKey(playerId)));
ProgressText.Append(Utils.GetTaskCount(playerId, comms));
return ProgressText.ToString();
@@ -72,11 +75,11 @@ namespace TOHE.Roles.Crewmate
static void Guard(PlayerControl pc)
{
if (Main.BlockSabo.ContainsKey(pc.PlayerId)) return;
if (BlockSabo.ContainsKey(pc.PlayerId)) return;
if (pc.GetAbilityUseLimit() >= 1)
{
Main.BlockSabo.Remove(pc.PlayerId);
Main.BlockSabo.Add(pc.PlayerId, Utils.TimeStamp);
BlockSabo.Remove(pc.PlayerId);
BlockSabo.Add(pc.PlayerId, Utils.TimeStamp);
pc.Notify(Translator.GetString("SecurityGuardSkillInUse"), SecurityGuardSkillDuration.GetFloat());
pc.RpcRemoveAbilityUse();
}
@@ -90,9 +93,9 @@ namespace TOHE.Roles.Crewmate
public override void OnFixedUpdate(PlayerControl player)
{
var playerId = player.PlayerId;
if (Main.BlockSabo.TryGetValue(playerId, out var stime) && stime + SecurityGuardSkillDuration.GetInt() < Utils.TimeStamp)
if (BlockSabo.TryGetValue(playerId, out var stime) && stime + SecurityGuardSkillDuration.GetInt() < Utils.TimeStamp)
{
Main.BlockSabo.Remove(playerId);
BlockSabo.Remove(playerId);
player.RpcResetAbilityCooldown();
player.Notify(Translator.GetString("SecurityGuardSkillStop"));
}
+18 -13
View File
@@ -1,5 +1,7 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using AmongUs.GameOptions;
using System.Text;
using UnityEngine;
using static TOHE.Options;
namespace TOHE.Roles.Crewmate
@@ -8,6 +10,9 @@ namespace TOHE.Roles.Crewmate
{
public static bool On;
public override bool IsEnable => On;
public static Dictionary<byte, Vector2> TimeMasterBackTrack = [];
public static Dictionary<byte, int> TimeMasterNum = [];
public static Dictionary<byte, long> TimeMasterInProtect = [];
public static void SetupCustomOption()
{
@@ -32,7 +37,7 @@ namespace TOHE.Roles.Crewmate
public override void Add(byte playerId)
{
On = true;
Main.TimeMasterNum[playerId] = 0;
TimeMasterNum[playerId] = 0;
playerId.SetAbilityUseLimit(TimeMasterMaxUses.GetInt());
}
@@ -52,7 +57,7 @@ namespace TOHE.Roles.Crewmate
{
var ProgressText = new StringBuilder();
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, Main.TimeMasterInProtect.ContainsKey(playerId)));
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, TimeMasterInProtect.ContainsKey(playerId)));
ProgressText.Append(Utils.GetTaskCount(playerId, comms));
return ProgressText.ToString();
@@ -79,16 +84,16 @@ namespace TOHE.Roles.Crewmate
static void Rewind(PlayerControl pc)
{
if (Main.TimeMasterInProtect.ContainsKey(pc.PlayerId)) return;
if (TimeMasterInProtect.ContainsKey(pc.PlayerId)) return;
if (pc.GetAbilityUseLimit() >= 1)
{
pc.RpcRemoveAbilityUse();
Main.TimeMasterInProtect.Remove(pc.PlayerId);
Main.TimeMasterInProtect.Add(pc.PlayerId, Utils.TimeStamp);
TimeMasterInProtect.Remove(pc.PlayerId);
TimeMasterInProtect.Add(pc.PlayerId, Utils.TimeStamp);
pc.Notify(Translator.GetString("TimeMasterOnGuard"), TimeMasterSkillDuration.GetFloat());
foreach (PlayerControl player in Main.AllPlayerControls)
{
if (Main.TimeMasterBackTrack.TryGetValue(player.PlayerId, out var position))
if (TimeMasterBackTrack.TryGetValue(player.PlayerId, out var position))
{
if (!pc.inVent && !pc.inMovingPlat && pc.IsAlive() && !pc.onLadder && pc.MyPhysics != null && !pc.MyPhysics.Animations.IsPlayingAnyLadderAnimation() && !pc.MyPhysics.Animations.IsPlayingEnterVentAnimation() && player.PlayerId != pc.PlayerId)
{
@@ -99,11 +104,11 @@ namespace TOHE.Roles.Crewmate
player.MyPhysics?.RpcBootFromVent(Main.LastEnteredVent.TryGetValue(player.PlayerId, out var vent) ? vent.Id : player.PlayerId);
}
Main.TimeMasterBackTrack.Remove(player.PlayerId);
TimeMasterBackTrack.Remove(player.PlayerId);
}
else
{
Main.TimeMasterBackTrack.Add(player.PlayerId, player.Pos());
TimeMasterBackTrack.Add(player.PlayerId, player.Pos());
}
}
}
@@ -116,11 +121,11 @@ namespace TOHE.Roles.Crewmate
public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target)
{
if (killer.PlayerId != target.PlayerId && Main.TimeMasterInProtect.TryGetValue(target.PlayerId, out var ts) && ts + TimeMasterSkillDuration.GetInt() >= Utils.TimeStamp)
if (killer.PlayerId != target.PlayerId && TimeMasterInProtect.TryGetValue(target.PlayerId, out var ts) && ts + TimeMasterSkillDuration.GetInt() >= Utils.TimeStamp)
{
foreach (var player in Main.AllPlayerControls)
{
if (!killer.Is(CustomRoles.Pestilence) && Main.TimeMasterBackTrack.TryGetValue(player.PlayerId, out var pos))
if (!killer.Is(CustomRoles.Pestilence) && TimeMasterBackTrack.TryGetValue(player.PlayerId, out var pos))
{
player.TP(pos);
}
@@ -136,9 +141,9 @@ namespace TOHE.Roles.Crewmate
public override void OnFixedUpdate(PlayerControl player)
{
var playerId = player.PlayerId;
if (Main.TimeMasterInProtect.TryGetValue(playerId, out var ttime) && ttime + TimeMasterSkillDuration.GetInt() < Utils.TimeStamp)
if (TimeMasterInProtect.TryGetValue(playerId, out var ttime) && ttime + TimeMasterSkillDuration.GetInt() < Utils.TimeStamp)
{
Main.TimeMasterInProtect.Remove(playerId);
TimeMasterInProtect.Remove(playerId);
player.RpcResetAbilityCooldown();
player.Notify(Translator.GetString("TimeMasterSkillStop"), (int)player.GetAbilityUseLimit());
}
+4 -1
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Crewmate
@@ -8,6 +9,8 @@ namespace TOHE.Roles.Crewmate
public static bool On;
public override bool IsEnable => On;
public static List<int> BlockedVents = [];
public static void SetupCustomOption()
{
SetupSingleRoleOptions(5525, TabGroup.CrewmateRoles, CustomRoles.Ventguard, 1);
@@ -48,7 +51,7 @@ namespace TOHE.Roles.Crewmate
if (pc.GetAbilityUseLimit() >= 1)
{
pc.RpcRemoveAbilityUse();
if (!Main.BlockedVents.Contains(vent.Id)) Main.BlockedVents.Add(vent.Id);
if (!BlockedVents.Contains(vent.Id)) BlockedVents.Add(vent.Id);
pc.Notify(Translator.GetString("VentBlockSuccess"));
}
else
+10 -7
View File
@@ -1,5 +1,6 @@
using AmongUs.GameOptions;
using System.Text;
using System.Collections.Generic;
using TOHE.Modules;
using static TOHE.Options;
@@ -7,6 +8,8 @@ namespace TOHE.Roles.Crewmate
{
internal class Veteran : RoleBase
{
public static Dictionary<byte, long> VeteranInProtect = [];
public static bool On;
public override bool IsEnable => On;
@@ -52,7 +55,7 @@ namespace TOHE.Roles.Crewmate
{
var ProgressText = new StringBuilder();
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, Main.VeteranInProtect.ContainsKey(playerId)));
ProgressText.Append(Utils.GetAbilityUseLimitDisplay(playerId, VeteranInProtect.ContainsKey(playerId)));
ProgressText.Append(Utils.GetTaskCount(playerId, comms));
return ProgressText.ToString();
@@ -78,10 +81,10 @@ namespace TOHE.Roles.Crewmate
static void Alert(PlayerControl pc)
{
if (Main.VeteranInProtect.ContainsKey(pc.PlayerId)) return;
if (VeteranInProtect.ContainsKey(pc.PlayerId)) return;
if (pc.GetAbilityUseLimit() >= 1)
{
Main.VeteranInProtect[pc.PlayerId] = Utils.TimeStamp;
VeteranInProtect[pc.PlayerId] = Utils.TimeStamp;
pc.RpcRemoveAbilityUse();
pc.RPCPlayCustomSound("Gunload");
pc.Notify(Translator.GetString("VeteranOnGuard"), VeteranSkillDuration.GetFloat());
@@ -95,9 +98,9 @@ namespace TOHE.Roles.Crewmate
public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target)
{
if (Main.VeteranInProtect.ContainsKey(target.PlayerId)
if (VeteranInProtect.ContainsKey(target.PlayerId)
&& killer.PlayerId != target.PlayerId
&& Main.VeteranInProtect[target.PlayerId] + VeteranSkillDuration.GetInt() >= Utils.TimeStamp)
&& VeteranInProtect[target.PlayerId] + VeteranSkillDuration.GetInt() >= Utils.TimeStamp)
{
if (!killer.Is(CustomRoles.Pestilence))
{
@@ -119,9 +122,9 @@ namespace TOHE.Roles.Crewmate
public override void OnFixedUpdate(PlayerControl player)
{
var playerId = player.PlayerId;
if (Main.VeteranInProtect.TryGetValue(playerId, out var vtime) && vtime + VeteranSkillDuration.GetInt() < Utils.TimeStamp)
if (VeteranInProtect.TryGetValue(playerId, out var vtime) && vtime + VeteranSkillDuration.GetInt() < Utils.TimeStamp)
{
Main.VeteranInProtect.Remove(playerId);
VeteranInProtect.Remove(playerId);
player.RpcResetAbilityCooldown();
player.Notify(string.Format(Translator.GetString("VeteranOffGuard"), (int)player.GetAbilityUseLimit()));
}
+5 -2
View File
@@ -1,11 +1,14 @@
using AmongUs.GameOptions;
using TOHE.Roles.Neutral;
using System.Collections.Generic;
using static TOHE.Options;
namespace TOHE.Roles.Impostor
{
internal class Cleaner : RoleBase
{
public static List<byte> CleanerBodies = [];
private bool HasImpostorVision;
private bool CanVent;
private float KillCooldown;
@@ -78,8 +81,8 @@ namespace TOHE.Roles.Impostor
{
if (Main.KillTimers[cleaner.PlayerId] > 0f) return true;
Main.CleanerBodies.Remove(target.PlayerId);
Main.CleanerBodies.Add(target.PlayerId);
CleanerBodies.Remove(target.PlayerId);
CleanerBodies.Add(target.PlayerId);
cleaner.Notify(Translator.GetString("CleanerCleanBody"));
cleaner.SetKillCooldown(KCDAfterClean);
+2 -2
View File
@@ -156,7 +156,7 @@ namespace TOHE.Roles.Impostor
case 5: // Ignore defense
killer.Notify(GetString("GamblerGet.IgnoreDefense"));
if ((target.Is(CustomRoles.Pestilence) && IgnorePestilence.GetBool())
|| (Main.VeteranInProtect.ContainsKey(target.PlayerId) && IgnoreVeteranAlert.GetBool())
|| (Veteran.VeteranInProtect.ContainsKey(target.PlayerId) && IgnoreVeteranAlert.GetBool())
|| (Medic.InProtect(target.PlayerId) && IgnoreMedicShield.GetBool())
|| ((target.Is(CustomRoles.Jinx) || target.Is(CustomRoles.CursedWolf)) && IgnoreCursedWolfAndJinx.GetBool()))
{
@@ -165,7 +165,7 @@ namespace TOHE.Roles.Impostor
}
if ((target.Is(CustomRoles.Pestilence) && !IgnorePestilence.GetBool())
|| (Main.VeteranInProtect.ContainsKey(target.PlayerId) && !IgnoreVeteranAlert.GetBool())
|| (Veteran.VeteranInProtect.ContainsKey(target.PlayerId) && !IgnoreVeteranAlert.GetBool())
|| (Medic.InProtect(target.PlayerId) && !IgnoreMedicShield.GetBool())
|| ((target.Is(CustomRoles.Jinx) || target.Is(CustomRoles.CursedWolf)) && !IgnoreCursedWolfAndJinx.GetBool()))
{
+1 -1
View File
@@ -62,7 +62,7 @@ public class Hangman : RoleBase
if (killer.IsShifted())
{
if (target.Is(CustomRoles.Pestilence)) return false;
if (target.Is(CustomRoles.Veteran) && Main.VeteranInProtect.ContainsKey(target.PlayerId)) return false;
if (target.Is(CustomRoles.Veteran) && Veteran.VeteranInProtect.ContainsKey(target.PlayerId)) return false;
killer.RpcRemoveAbilityUse();
target.Data.IsDead = true;
target.SetRealKiller(killer);
+6 -3
View File
@@ -2,6 +2,7 @@
using HarmonyLib;
using Hazel;
using System;
using System.Collections.Generic;
using System.Linq;
using TOHE.Modules;
using UnityEngine;
@@ -16,6 +17,8 @@ namespace TOHE.Roles.Impostor
public static bool On;
public override bool IsEnable => On;
public static Dictionary<byte, int> MafiaRevenged = [];
public static void SetupCustomOption()
{
SetupRoleOptions(3100, TabGroup.ImpostorRoles, CustomRoles.Mafia);
@@ -82,9 +85,9 @@ namespace TOHE.Roles.Impostor
return true;
}
if (!Main.MafiaRevenged.TryAdd(pc.PlayerId, 0))
if (!MafiaRevenged.TryAdd(pc.PlayerId, 0))
{
if (Main.MafiaRevenged[pc.PlayerId] >= MafiaCanKillNum.GetInt())
if (MafiaRevenged[pc.PlayerId] >= MafiaCanKillNum.GetInt())
{
if (!isUI) Utils.SendMessage(GetString("MafiaKillMax"), pc.PlayerId);
else pc.ShowPopUp(GetString("MafiaKillMax"));
@@ -123,7 +126,7 @@ namespace TOHE.Roles.Impostor
string Name = target.GetRealName();
Main.MafiaRevenged[pc.PlayerId]++;
MafiaRevenged[pc.PlayerId]++;
CustomSoundsManager.RPCPlayCustomSoundAll("AWP");
+1 -1
View File
@@ -159,7 +159,7 @@ namespace TOHE.Roles.Impostor
(Main.PlayerStates[id].Role as Mastermind)?.NotifyMastermindTargetSurvived();
}
if (target.Is(CustomRoles.Pestilence) || Main.VeteranInProtect.ContainsKey(target.PlayerId) || target.Is(CustomRoles.Mastermind))
if (target.Is(CustomRoles.Pestilence) || Veteran.VeteranInProtect.ContainsKey(target.PlayerId) || target.Is(CustomRoles.Mastermind))
{
Main.PlayerStates[killer.PlayerId].deathReason = PlayerState.DeathReason.Suicide;
Main.PlayerStates[killer.PlayerId].SetDead();
+7 -3
View File
@@ -1,4 +1,5 @@
using Hazel;
using System.Collections.Generic;
using Hazel;
using InnerNet;
using System.Linq;
using TOHE.Roles.Crewmate;
@@ -12,6 +13,8 @@ namespace TOHE.Roles.Impostor
public static bool On;
public override bool IsEnable => On;
public static List<byte> OverDeadPlayerList = [];
public override void Add(byte playerId)
{
On = true;
@@ -39,7 +42,7 @@ namespace TOHE.Roles.Impostor
Main.PlayerStates[target.PlayerId].deathReason = PlayerState.DeathReason.Dismembered;
_ = new LateTask(() =>
{
if (!Main.OverDeadPlayerList.Contains(target.PlayerId)) Main.OverDeadPlayerList.Add(target.PlayerId);
if (!OverDeadPlayerList.Contains(target.PlayerId)) OverDeadPlayerList.Add(target.PlayerId);
if (target.Is(CustomRoles.Avanger))
{
foreach (var pc in Main.AllAlivePlayerControls)
@@ -52,6 +55,7 @@ namespace TOHE.Roles.Impostor
}
var ops = target.Pos();
var originPos = killer.Pos();
var rd = IRandom.Instance;
for (int i = 0; i < 20; i++)
{
@@ -79,7 +83,7 @@ namespace TOHE.Roles.Impostor
AmongUsClient.Instance.FinishRpcImmediately(messageWriter);
}
killer.TP(ops);
killer.TP(originPos);
}, 0.05f, "OverKiller Murder");
}
+1 -1
View File
@@ -83,7 +83,7 @@ public class Vampire : RoleBase
if (target.Is(CustomRoles.Pestilence)) return true;
if (target.Is(CustomRoles.Guardian) && target.AllTasksCompleted()) return true;
if (target.Is(CustomRoles.Opportunist) && target.AllTasksCompleted() && Options.OppoImmuneToAttacksWhenTasksDone.GetBool()) return false;
if (target.Is(CustomRoles.Veteran) && Main.VeteranInProtect.ContainsKey(target.PlayerId)) return true;
if (target.Is(CustomRoles.Veteran) && Veteran.VeteranInProtect.ContainsKey(target.PlayerId)) return true;
if (Medic.ProtectList.Contains(target.PlayerId)) return false;
killer.SetKillCooldown();
+99 -33
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using System;
using AmongUs.GameOptions;
using System.Collections.Generic;
using System.Linq;
using TOHE.Modules;
@@ -14,6 +15,20 @@ namespace TOHE.Roles.Impostor
public static bool On;
public override bool IsEnable => On;
public static OptionItem WarlockCanKillAllies;
public static OptionItem WarlockCanKillSelf;
public static OptionItem KillCooldown;
public static OptionItem CurseCooldown;
public static Dictionary<byte, float> WarlockTimer = [];
public static Dictionary<byte, PlayerControl> CursedPlayers = [];
public static Dictionary<byte, bool> isCurseAndKill = [];
public static bool isCursed;
private float KCD;
private float CurseCD;
private long LastNotify;
public static void SetupCustomOption()
{
SetupRoleOptions(4600, TabGroup.ImpostorRoles, CustomRoles.Warlock);
@@ -21,7 +36,10 @@ namespace TOHE.Roles.Impostor
.SetParent(CustomRoleSpawnChances[CustomRoles.Warlock]);
WarlockCanKillSelf = BooleanOptionItem.Create(4611, "CanKillSelf", false, TabGroup.ImpostorRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Warlock]);
WarlockShiftDuration = FloatOptionItem.Create(4612, "ShapeshiftDuration", new(0, 180, 1), 1, TabGroup.ImpostorRoles, false)
KillCooldown = FloatOptionItem.Create(4613, "KillCooldown", new(0f, 180f, 1f), 30f, TabGroup.ImpostorRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Warlock])
.SetValueFormat(OptionFormat.Seconds);
CurseCooldown = FloatOptionItem.Create(4614, "CurseCooldown", new(0f, 180f, 1f), 30f, TabGroup.ImpostorRoles, false)
.SetParent(CustomRoleSpawnChances[CustomRoles.Warlock])
.SetValueFormat(OptionFormat.Seconds);
}
@@ -29,8 +47,11 @@ namespace TOHE.Roles.Impostor
public override void Add(byte playerId)
{
On = true;
Main.CursedPlayers.Add(playerId, null);
Main.isCurseAndKill.Add(playerId, false);
CursedPlayers.Add(playerId, null);
isCurseAndKill.Add(playerId, false);
KCD = KillCooldown.GetFloat();
CurseCD = CurseCooldown.GetFloat();
LastNotify = 0;
}
public override void Init()
@@ -43,17 +64,22 @@ namespace TOHE.Roles.Impostor
if (UsePets.GetBool()) return;
try
{
AURoleOptions.ShapeshifterCooldown = Main.isCursed ? 1f : DefaultKillCooldown;
AURoleOptions.ShapeshifterDuration = WarlockShiftDuration.GetFloat();
AURoleOptions.ShapeshifterCooldown = isCursed ? 1f : DefaultKillCooldown;
AURoleOptions.ShapeshifterDuration = 1f;
}
catch
{
}
}
public override void SetKillCooldown(byte id)
{
Main.AllPlayerKillCooldown[id] = 1f;
}
public override void SetButtonTexts(HudManager hud, byte id)
{
bool curse = Main.isCurseAndKill.TryGetValue(id, out bool wcs) && wcs;
bool curse = isCurseAndKill.TryGetValue(id, out bool wcs) && wcs;
bool shapeshifting = id.IsPlayerShifted();
if (!shapeshifting && !curse)
hud.KillButton?.OverrideText(Translator.GetString("WarlockCurseButtonText"));
@@ -65,24 +91,36 @@ namespace TOHE.Roles.Impostor
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
Main.isCurseAndKill.TryAdd(killer.PlayerId, false);
if (killer.IsShifted()) return false;
if (!killer.IsShifted() && !Main.isCurseAndKill[killer.PlayerId])
if (killer.CheckDoubleTrigger(target, () =>
{
if (CurseCD > 0f) return;
isCurseAndKill.TryAdd(killer.PlayerId, false);
if (!killer.IsShifted() && !isCurseAndKill[killer.PlayerId])
{
if (target.Is(CustomRoles.Needy) || target.Is(CustomRoles.Lazy)) return;
isCursed = true;
killer.SetKillCooldown();
RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound);
killer.RPCPlayCustomSound("Line");
CursedPlayers[killer.PlayerId] = target;
WarlockTimer.Add(killer.PlayerId, 0f);
isCurseAndKill[killer.PlayerId] = true;
CurseCD = CurseCooldown.GetFloat();
return;
}
if (isCurseAndKill[killer.PlayerId]) killer.RpcGuardAndKill(target);
}))
{
if (target.Is(CustomRoles.Needy) || target.Is(CustomRoles.Lazy)) return false;
Main.isCursed = true;
killer.SetKillCooldown();
RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound);
killer.RPCPlayCustomSound("Line");
Main.CursedPlayers[killer.PlayerId] = target;
Main.WarlockTimer.Add(killer.PlayerId, 0f);
Main.isCurseAndKill[killer.PlayerId] = true;
return false;
if (KCD > 0f) return false;
KCD = KillCooldown.GetFloat();
return true;
}
if (killer.IsShifted()) return true;
if (Main.isCurseAndKill[killer.PlayerId]) killer.RpcGuardAndKill(target);
return false;
}
@@ -100,12 +138,12 @@ namespace TOHE.Roles.Impostor
static void Curse(PlayerControl pc)
{
Main.isCurseAndKill.TryAdd(pc.PlayerId, false);
if (Main.CursedPlayers[pc.PlayerId] != null)
isCurseAndKill.TryAdd(pc.PlayerId, false);
if (CursedPlayers[pc.PlayerId] != null)
{
if (!Main.CursedPlayers[pc.PlayerId].Data.IsDead)
if (!CursedPlayers[pc.PlayerId].Data.IsDead)
{
var cp = Main.CursedPlayers[pc.PlayerId];
var cp = CursedPlayers[pc.PlayerId];
Vector2 cppos = cp.Pos();
Dictionary<PlayerControl, float> cpdistance = [];
foreach (PlayerControl p in Main.AllAlivePlayerControls)
@@ -140,34 +178,62 @@ namespace TOHE.Roles.Impostor
pc.Notify(Translator.GetString("WarlockNoTarget"));
}
Main.isCurseAndKill[pc.PlayerId] = false;
isCurseAndKill[pc.PlayerId] = false;
}
Main.CursedPlayers[pc.PlayerId] = null;
CursedPlayers[pc.PlayerId] = null;
}
}
public override void OnGlobalFixedUpdate(PlayerControl player, bool lowLoad)
{
byte playerId = player.PlayerId;
if (GameStates.IsInTask && Main.WarlockTimer.ContainsKey(playerId))
if (GameStates.IsInTask && WarlockTimer.ContainsKey(playerId))
{
if (player.IsAlive())
{
if (Main.WarlockTimer[playerId] >= 1f)
if (WarlockTimer[playerId] >= 1f)
{
player.RpcResetAbilityCooldown();
Main.isCursed = false;
isCursed = false;
player.MarkDirtySettings();
Main.WarlockTimer.Remove(playerId);
WarlockTimer.Remove(playerId);
}
else Main.WarlockTimer[playerId] += Time.fixedDeltaTime;
else WarlockTimer[playerId] += Time.fixedDeltaTime;
}
else
{
Main.WarlockTimer.Remove(playerId);
WarlockTimer.Remove(playerId);
}
}
}
public override void OnFixedUpdate(PlayerControl pc)
{
if (!GameStates.IsInTask || !pc.IsAlive()) return;
var beforeKCD = KCD;
var beforeCCD = CurseCD;
if (KCD > 0f) KCD -= Time.fixedDeltaTime;
if (CurseCD > 0f) CurseCD -= Time.fixedDeltaTime;
if (!pc.IsModClient() && (Math.Abs(KCD - beforeKCD) > 0.5f || Math.Abs(beforeCCD - CurseCD) > 0.5f) && LastNotify != Utils.TimeStamp)
{
LastNotify = Utils.TimeStamp;
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
}
}
public static string GetSuffixAndHudText(PlayerControl seer, bool hud = false)
{
if (seer.IsModClient() && !hud) return string.Empty;
if (Main.PlayerStates[seer.PlayerId].Role is not Warlock { IsEnable: true } wl) return string.Empty;
var sb = new System.Text.StringBuilder();
if (wl.KCD > 0f) sb.Append($"<#ffa500>{Translator.GetString("KillCooldown")}:</color> <#ffffff>{(int)Math.Round(wl.KCD)}s</color>");
if (wl.CurseCD > 0f) sb.Append($"{(sb.Length > 0 ? "\n" : string.Empty)}<#00ffa5>{Translator.GetString("CurseCooldown")}:</color> <#ffffff>{(int)Math.Round(wl.CurseCD)}s</color>");
return hud ? sb.ToString() : $"<size=1.7>{sb}</size>";
}
}
}
+2 -2
View File
@@ -84,7 +84,7 @@ public class Agitater : RoleBase
{
if (!IsEnable) return false;
if (AgitaterAutoReportBait.GetBool() && target.Is(CustomRoles.Bait)) return true;
if (target.Is(CustomRoles.Pestilence) || (target.Is(CustomRoles.Veteran) && Main.VeteranInProtect.ContainsKey(target.PlayerId)))
if (target.Is(CustomRoles.Pestilence) || (target.Is(CustomRoles.Veteran) && Veteran.VeteranInProtect.ContainsKey(target.PlayerId)))
{
target.Kill(killer);
ResetBomb();
@@ -181,7 +181,7 @@ public class Agitater : RoleBase
if (!AgitaterCanGetBombed.GetBool() && target.Is(CustomRoles.Agitater)) return;
if (target.Is(CustomRoles.Pestilence) || (target.Is(CustomRoles.Veteran) && Main.VeteranInProtect.ContainsKey(target.PlayerId)))
if (target.Is(CustomRoles.Pestilence) || (target.Is(CustomRoles.Veteran) && Veteran.VeteranInProtect.ContainsKey(target.PlayerId)))
{
target.Kill(player);
ResetBomb();
+19 -14
View File
@@ -1,5 +1,6 @@
using AmongUs.GameOptions;
using System.Linq;
using System.Collections.Generic;
using TOHE.Modules;
using UnityEngine;
using static TOHE.Options;
@@ -8,6 +9,10 @@ namespace TOHE.Roles.Neutral
{
internal class Arsonist : RoleBase
{
public static Dictionary<byte, (PlayerControl PLAYER, float TIMER)> ArsonistTimer = [];
public static Dictionary<(byte, byte), bool> isDoused = [];
public static byte currentDousingTarget = byte.MaxValue;
public static bool On;
public override bool IsEnable => On;
@@ -35,7 +40,7 @@ namespace TOHE.Roles.Neutral
On = true;
foreach (PlayerControl ar in Main.AllPlayerControls)
{
Main.isDoused.Add((playerId, ar.PlayerId), false);
isDoused.Add((playerId, ar.PlayerId), false);
}
}
@@ -73,9 +78,9 @@ namespace TOHE.Roles.Neutral
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
killer.SetKillCooldown(ArsonistDouseTime.GetFloat());
if (!Main.isDoused[(killer.PlayerId, target.PlayerId)] && !Main.ArsonistTimer.ContainsKey(killer.PlayerId))
if (!isDoused[(killer.PlayerId, target.PlayerId)] && !ArsonistTimer.ContainsKey(killer.PlayerId))
{
Main.ArsonistTimer.Add(killer.PlayerId, (target, 0f));
ArsonistTimer.Add(killer.PlayerId, (target, 0f));
Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true);
RPC.SetCurrentDousingTarget(killer.PlayerId, target.PlayerId);
}
@@ -155,28 +160,28 @@ namespace TOHE.Roles.Neutral
public override void OnGlobalFixedUpdate(PlayerControl player, bool lowLoad)
{
var playerId = player.PlayerId;
if (GameStates.IsInTask && Main.ArsonistTimer.ContainsKey(playerId))
if (GameStates.IsInTask && ArsonistTimer.ContainsKey(playerId))
{
var arTarget = Main.ArsonistTimer[playerId].PLAYER;
var arTarget = ArsonistTimer[playerId].PLAYER;
if (!player.IsAlive() || Pelican.IsEaten(playerId))
{
Main.ArsonistTimer.Remove(playerId);
ArsonistTimer.Remove(playerId);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: arTarget, ForceLoop: true);
RPC.ResetCurrentDousingTarget(playerId);
}
else
{
var ar_target = Main.ArsonistTimer[playerId].PLAYER;
var ar_time = Main.ArsonistTimer[playerId].TIMER;
if (!ar_target.IsAlive())
var ar_target = ArsonistTimer[playerId].PLAYER;
var ar_time = ArsonistTimer[playerId].TIMER;
if (!ExtendedPlayerControl.IsAlive(ar_target))
{
Main.ArsonistTimer.Remove(playerId);
ArsonistTimer.Remove(playerId);
}
else if (ar_time >= ArsonistDouseTime.GetFloat())
{
player.SetKillCooldown();
Main.ArsonistTimer.Remove(playerId);
Main.isDoused[(playerId, ar_target.PlayerId)] = true;
ArsonistTimer.Remove(playerId);
isDoused[(playerId, ar_target.PlayerId)] = true;
player.RpcSetDousedPlayer(ar_target, true);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: arTarget, ForceLoop: true);
RPC.ResetCurrentDousingTarget(playerId);
@@ -187,11 +192,11 @@ namespace TOHE.Roles.Neutral
float dis = Vector2.Distance(player.transform.position, ar_target.transform.position);
if (dis <= range)
{
Main.ArsonistTimer[playerId] = (ar_target, ar_time + Time.fixedDeltaTime);
ArsonistTimer[playerId] = (ar_target, ar_time + Time.fixedDeltaTime);
}
else
{
Main.ArsonistTimer.Remove(playerId);
ArsonistTimer.Remove(playerId);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: arTarget, ForceLoop: true);
RPC.ResetCurrentDousingTarget(playerId);
+10 -8
View File
@@ -7,6 +7,8 @@ namespace TOHE.Roles.Neutral
{
internal class Mario : RoleBase
{
public static Dictionary<byte, int> MarioVentCount = [];
public static bool On;
public override bool IsEnable => On;
@@ -24,7 +26,7 @@ namespace TOHE.Roles.Neutral
public override void Add(byte playerId)
{
On = true;
Main.MarioVentCount[playerId] = 0;
MarioVentCount[playerId] = 0;
}
public override void Init()
@@ -40,21 +42,21 @@ namespace TOHE.Roles.Neutral
public override string GetProgressText(byte playerId, bool comms)
{
return Utils.ColorString(Color.white, $"<color=#777777>-</color> {Main.MarioVentCount.GetValueOrDefault(playerId, 0)}/{MarioVentNumWin.GetInt()}");
return Utils.ColorString(Color.white, $"<color=#777777>-</color> {CollectionExtensions.GetValueOrDefault(MarioVentCount, playerId, 0)}/{MarioVentNumWin.GetInt()}");
}
public override void SetButtonTexts(HudManager hud, byte id)
{
hud.AbilityButton.buttonLabelText.text = Translator.GetString("MarioVentButtonText");
hud.AbilityButton?.SetUsesRemaining(MarioVentNumWin.GetInt() - Main.MarioVentCount.GetValueOrDefault(id, 0));
hud.AbilityButton?.SetUsesRemaining(MarioVentNumWin.GetInt() - CollectionExtensions.GetValueOrDefault(MarioVentCount, id, 0));
}
public override void OnFixedUpdate(PlayerControl pc)
{
var playerId = pc.PlayerId;
if (Main.MarioVentCount[playerId] > MarioVentNumWin.GetInt() && GameStates.IsInTask)
if (MarioVentCount[playerId] > MarioVentNumWin.GetInt() && GameStates.IsInTask)
{
Main.MarioVentCount[playerId] = MarioVentNumWin.GetInt();
MarioVentCount[playerId] = MarioVentNumWin.GetInt();
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Mario);
CustomWinnerHolder.WinnerIds.Add(playerId);
}
@@ -62,11 +64,11 @@ namespace TOHE.Roles.Neutral
public override void OnEnterVent(PlayerControl pc, Vent vent)
{
Main.MarioVentCount.TryAdd(pc.PlayerId, 0);
Main.MarioVentCount[pc.PlayerId]++;
MarioVentCount.TryAdd(pc.PlayerId, 0);
MarioVentCount[pc.PlayerId]++;
Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc);
if (AmongUsClient.Instance.AmHost && Main.MarioVentCount[pc.PlayerId] >= MarioVentNumWin.GetInt())
if (AmongUsClient.Instance.AmHost && MarioVentCount[pc.PlayerId] >= MarioVentNumWin.GetInt())
{
CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Mario); //马里奥这个多动症赢了
CustomWinnerHolder.WinnerIds.Add(pc.PlayerId);
+1
View File
@@ -118,6 +118,7 @@ namespace TOHE.Roles.Neutral
public static string GetSuffixAndHudText(PlayerControl seer, bool hud = false)
{
if (seer.IsModClient() && !hud) return string.Empty;
if (Main.PlayerStates[seer.PlayerId].Role is not Predator { IsEnable: true } pt) return string.Empty;
if (pt.IsWon) return !hud ? "<#00ff00>\u2713</color>" : Translator.GetString("PredatorDone");
var text = pt.RolesToKill.Join(x => Utils.ColorString(Utils.GetRoleColor(x), Translator.GetString($"{x}")));
+5 -2
View File
@@ -1,9 +1,12 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
namespace TOHE.Roles.Neutral
{
internal class Provocateur : RoleBase
{
public static Dictionary<byte, byte> Provoked = [];
public static bool On;
public override bool IsEnable => On;
@@ -21,7 +24,7 @@ namespace TOHE.Roles.Neutral
public override bool CanUseKillButton(PlayerControl pc)
{
return pc.IsAlive() && !Main.Provoked.ContainsKey(pc.PlayerId);
return pc.IsAlive() && !Provoked.ContainsKey(pc.PlayerId);
}
public override bool CanUseImpostorVentButton(PlayerControl pc)
@@ -56,7 +59,7 @@ namespace TOHE.Roles.Neutral
{
Main.PlayerStates[target.PlayerId].deathReason = PlayerState.DeathReason.PissedOff;
killer.Kill(target);
Main.Provoked.TryAdd(killer.PlayerId, target.PlayerId);
Provoked.TryAdd(killer.PlayerId, target.PlayerId);
return false;
}
}
+36 -28
View File
@@ -1,5 +1,6 @@
using AmongUs.GameOptions;
using System.Linq;
using System.Collections.Generic;
using TOHE.Modules;
using UnityEngine;
using static TOHE.Options;
@@ -8,6 +9,13 @@ namespace TOHE.Roles.Neutral
{
internal class Revolutionist : RoleBase
{
public static Dictionary<(byte, byte), bool> isDraw = [];
public static Dictionary<byte, (PlayerControl PLAYER, float TIMER)> RevolutionistTimer = [];
public static Dictionary<byte, long> RevolutionistStart = [];
public static Dictionary<byte, long> RevolutionistLastTime = [];
public static Dictionary<byte, int> RevolutionistCountdown = [];
public static byte currentDrawTarget = byte.MaxValue;
public static bool On;
public override bool IsEnable => On;
@@ -37,7 +45,7 @@ namespace TOHE.Roles.Neutral
On = true;
foreach (PlayerControl ar in Main.AllPlayerControls)
{
Main.isDraw.Add((playerId, ar.PlayerId), false);
isDraw.Add((playerId, ar.PlayerId), false);
}
}
@@ -90,9 +98,9 @@ namespace TOHE.Roles.Neutral
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
killer.SetKillCooldown(RevolutionistDrawTime.GetFloat());
if (!Main.isDraw[(killer.PlayerId, target.PlayerId)] && !Main.RevolutionistTimer.ContainsKey(killer.PlayerId))
if (!isDraw[(killer.PlayerId, target.PlayerId)] && !RevolutionistTimer.ContainsKey(killer.PlayerId))
{
Main.RevolutionistTimer.TryAdd(killer.PlayerId, (target, 0f));
RevolutionistTimer.TryAdd(killer.PlayerId, (target, 0f));
Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true);
RPC.SetCurrentDrawTarget(killer.PlayerId, target.PlayerId);
}
@@ -102,7 +110,7 @@ namespace TOHE.Roles.Neutral
public override void OnReportDeadBody()
{
foreach (var x in Main.RevolutionistStart)
foreach (var x in RevolutionistStart)
{
var tar = Utils.GetPlayerById(x.Key);
if (tar == null) continue;
@@ -112,47 +120,47 @@ namespace TOHE.Roles.Neutral
Main.PlayerStates[tar.PlayerId].SetDead();
}
Main.RevolutionistTimer.Clear();
Main.RevolutionistStart.Clear();
Main.RevolutionistLastTime.Clear();
RevolutionistTimer.Clear();
RevolutionistStart.Clear();
RevolutionistLastTime.Clear();
}
public override void OnFixedUpdate(PlayerControl player)
{
var playerId = player.PlayerId;
if (GameStates.IsInTask && Main.RevolutionistTimer.ContainsKey(playerId))
if (GameStates.IsInTask && RevolutionistTimer.ContainsKey(playerId))
{
var rvTarget = Main.RevolutionistTimer[playerId].PLAYER;
var rvTarget = RevolutionistTimer[playerId].PLAYER;
if (!player.IsAlive() || Pelican.IsEaten(playerId))
{
Main.RevolutionistTimer.Remove(playerId);
RevolutionistTimer.Remove(playerId);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: rvTarget, ForceLoop: true);
RPC.ResetCurrentDrawTarget(playerId);
}
else
{
var rv_target = Main.RevolutionistTimer[playerId].PLAYER;
var rv_time = Main.RevolutionistTimer[playerId].TIMER;
if (!rv_target.IsAlive())
var rv_target = RevolutionistTimer[playerId].PLAYER;
var rv_time = RevolutionistTimer[playerId].TIMER;
if (!ExtendedPlayerControl.IsAlive(rv_target))
{
Main.RevolutionistTimer.Remove(playerId);
RevolutionistTimer.Remove(playerId);
}
else if (rv_time >= RevolutionistDrawTime.GetFloat())
{
player.SetKillCooldown();
Main.RevolutionistTimer.Remove(playerId);
Main.isDraw[(playerId, rv_target.PlayerId)] = true;
RevolutionistTimer.Remove(playerId);
isDraw[(playerId, rv_target.PlayerId)] = true;
player.RpcSetDrawPlayer(rv_target, true);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: rv_target, ForceLoop: true);
RPC.ResetCurrentDrawTarget(playerId);
if (IRandom.Instance.Next(1, 100) <= RevolutionistKillProbability.GetInt())
{
rv_target.SetRealKiller(player);
ExtendedPlayerControl.SetRealKiller(rv_target, player);
Main.PlayerStates[rv_target.PlayerId].deathReason = PlayerState.DeathReason.Sacrifice;
player.Kill(rv_target);
Main.PlayerStates[rv_target.PlayerId].SetDead();
Logger.Info($"Revolutionist: {player.GetNameWithRole().RemoveHtmlTags()} killed {rv_target.GetNameWithRole().RemoveHtmlTags()}", "Revolutionist");
Logger.Info($"Revolutionist: {player.GetNameWithRole().RemoveHtmlTags()} killed {ExtendedPlayerControl.GetNameWithRole(rv_target).RemoveHtmlTags()}", "Revolutionist");
}
}
else
@@ -161,11 +169,11 @@ namespace TOHE.Roles.Neutral
float dis = Vector2.Distance(player.transform.position, rv_target.transform.position);
if (dis <= range)
{
Main.RevolutionistTimer[playerId] = (rv_target, rv_time + Time.fixedDeltaTime);
RevolutionistTimer[playerId] = (rv_target, rv_time + Time.fixedDeltaTime);
}
else
{
Main.RevolutionistTimer.Remove(playerId);
RevolutionistTimer.Remove(playerId);
Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: rv_target);
RPC.ResetCurrentDrawTarget(playerId);
@@ -177,15 +185,15 @@ namespace TOHE.Roles.Neutral
if (GameStates.IsInTask && player.IsDrawDone() && player.IsAlive())
{
if (Main.RevolutionistStart.ContainsKey(playerId))
if (RevolutionistStart.ContainsKey(playerId))
{
if (Main.RevolutionistLastTime.ContainsKey(playerId))
if (RevolutionistLastTime.ContainsKey(playerId))
{
long nowtime = Utils.TimeStamp;
Main.RevolutionistLastTime[playerId] = nowtime;
int time = (int)(Main.RevolutionistLastTime[playerId] - Main.RevolutionistStart[playerId]);
RevolutionistLastTime[playerId] = nowtime;
int time = (int)(RevolutionistLastTime[playerId] - RevolutionistStart[playerId]);
int countdown = RevolutionistVentCountDown.GetInt() - time;
Main.RevolutionistCountdown.Clear();
RevolutionistCountdown.Clear();
if (countdown <= 0)
{
Utils.GetDrawPlayerCount(playerId, out var y);
@@ -199,17 +207,17 @@ namespace TOHE.Roles.Neutral
}
else
{
Main.RevolutionistCountdown.Add(playerId, countdown);
RevolutionistCountdown.Add(playerId, countdown);
}
}
else
{
Main.RevolutionistLastTime.TryAdd(playerId, Main.RevolutionistStart[playerId]);
RevolutionistLastTime.TryAdd(playerId, RevolutionistStart[playerId]);
}
}
else
{
Main.RevolutionistStart.TryAdd(playerId, Utils.TimeStamp);
RevolutionistStart.TryAdd(playerId, Utils.TimeStamp);
}
}
}
+5 -3
View File
@@ -14,6 +14,8 @@ namespace TOHE.Roles.Neutral
private const int Id = 13200;
private static List<byte> playerIdList = [];
public static List<byte> InfectedPlayer = [];
public static Dictionary<byte, string> VirusNotify = [];
public static List<byte> InfectedBodies = [];
private static OptionItem KillCooldown;
private static OptionItem InfectMax;
@@ -86,7 +88,7 @@ namespace TOHE.Roles.Neutral
public override bool OnCheckMurder(PlayerControl killer, PlayerControl target)
{
if (killer.GetAbilityUseLimit() < 1) return false;
Main.InfectedBodies.Add(target.PlayerId);
InfectedBodies.Add(target.PlayerId);
return false;
}
@@ -100,7 +102,7 @@ namespace TOHE.Roles.Neutral
{
InfectedPlayer.Add(target.PlayerId);
Main.VirusNotify.Add(target.PlayerId, GetString("VirusNoticeMessage2"));
VirusNotify.Add(target.PlayerId, GetString("VirusNoticeMessage2"));
}
else
{
@@ -108,7 +110,7 @@ namespace TOHE.Roles.Neutral
Utils.NotifyRoles(ForceLoop: true);
Main.VirusNotify.Add(target.PlayerId, GetString("VirusNoticeMessage"));
VirusNotify.Add(target.PlayerId, GetString("VirusNoticeMessage"));
}
Logger.Info("Add-on assigned:" + target.Data?.PlayerName + " = " + target.GetCustomRole() + " + " + CustomRoles.Contagious, "Assign " + CustomRoles.Contagious);
+2 -1
View File
@@ -2,6 +2,7 @@ using AmongUs.GameOptions;
using Hazel;
using System.Collections.Generic;
using TOHE.Modules;
using TOHE.Roles.Crewmate;
using UnityEngine;
using static TOHE.Options;
using static TOHE.Translator;
@@ -151,7 +152,7 @@ public class WeaponMaster : RoleBase
{
foreach (PlayerControl player in Main.AllAlivePlayerControls)
{
if (Pelican.IsEaten(player.PlayerId) || player == killer || player.Is(CustomRoles.Pestilence) || Main.VeteranInProtect.ContainsKey(target.PlayerId)) continue;
if (Pelican.IsEaten(player.PlayerId) || player == killer || player.Is(CustomRoles.Pestilence) || Veteran.VeteranInProtect.ContainsKey(target.PlayerId)) continue;
if (Vector2.Distance(killer.transform.position, player.transform.position) <= Radius.GetFloat())
{
player.Suicide(PlayerState.DeathReason.Kill, killer);
+3
View File
@@ -1,4 +1,5 @@
using AmongUs.GameOptions;
using System.Collections.Generic;
using System.Linq;
using TOHE.Modules;
using static TOHE.Options;
@@ -10,6 +11,8 @@ namespace TOHE.Roles.Neutral
public static bool On;
public override bool IsEnable => On;
public static List<byte> WorkaholicAlive = [];
public static void SetupCustomOption()
{
SetupRoleOptions(11700, TabGroup.NeutralRoles, CustomRoles.Workaholic); //TOH_Y
+12 -64
View File
@@ -79,6 +79,7 @@ public class Main : BasePlugin
public static ConfigEntry<string> BetaBuildURL { get; private set; }
public static ConfigEntry<float> LastKillCooldown { get; private set; }
public static ConfigEntry<float> LastShapeshifterCooldown { get; private set; }
public static bool IsFixedCooldown => CustomRoles.Vampire.IsEnable() || CustomRoles.Poisoner.IsEnable();
public static bool ChangedRole = false;
public static OptionBackupData RealOptionsData;
public static Dictionary<byte, float> KillTimers = [];
@@ -93,7 +94,6 @@ public class Main : BasePlugin
public static Dictionary<CustomRoles, CustomRoles> AlwaysSpawnTogetherCombos = [];
public static Dictionary<CustomRoles, CustomRoles> NeverSpawnTogetherCombos = [];
public static List<RoleBase> AllRoleClasses;
public static bool IsFixedCooldown => CustomRoles.Vampire.IsEnable() || CustomRoles.Poisoner.IsEnable();
public static float RefixCooldownDelay;
public static bool ProcessShapeshifts = true;
public static Dictionary<byte, (long START_TIMESTAMP, int TOTALCD)> AbilityCD = [];
@@ -105,41 +105,13 @@ public class Main : BasePlugin
public static List<byte> ResetCamPlayerList = [];
public static List<byte> winnerList = [];
public static List<CustomRoles> winnerRolesList = [];
public static List<byte> ForCrusade = [];
public static List<byte> KillGhoul = [];
public static List<string> winnerNameList = [];
public static List<int> clientIdList = [];
public static List<(string MESSAGE, byte RECEIVER_ID, string TITLE)> MessagesToSend = [];
public static bool isChatCommand;
public static List<PlayerControl> LoversPlayers = [];
public static bool isLoversDead = true;
public static Dictionary<byte, float> AllPlayerKillCooldown = [];
public static Dictionary<byte, Vent> LastEnteredVent = [];
public static Dictionary<byte, Vector2> LastEnteredVentLocation = [];
public static Dictionary<byte, Vector2> TimeMasterBackTrack = [];
//public static Dictionary<byte, int> MasochistKillMax = new();
public static Dictionary<byte, int> TimeMasterNum = [];
public static Dictionary<byte, long> TimeMasterInProtect = [];
//public static Dictionary<byte, long> FlashbangInProtect = new();
public static List<byte> CyberStarDead = [];
public static List<int> BlockedVents = [];
public static List<byte> WorkaholicAlive = [];
public static List<byte> SpeedrunnerAlive = [];
public static List<byte> BaitAlive = [];
//public static List<byte> KilledDiseased = new();
public static Dictionary<byte, int> KilledDiseased = [];
public static Dictionary<byte, int> KilledAntidote = [];
//public static List<byte> ForFlashbang = new();
public static Dictionary<byte, string> DetectiveNotify = [];
public static Dictionary<byte, string> VirusNotify = [];
public static List<byte> OverDeadPlayerList = [];
public static List<(string MESSAGE, byte RECEIVER_ID, string TITLE)> MessagesToSend = [];
public static bool isChatCommand;
public static bool DoBlockNameChange;
public static int updateTime;
public static bool newLobby;
@@ -147,54 +119,30 @@ public class Main : BasePlugin
public static Dictionary<int, int> SayBanwordsTimes = [];
public static Dictionary<byte, float> AllPlayerSpeed = [];
public const float MinSpeed = 0.0001f;
public static List<byte> CleanerBodies = [];
public static List<byte> MedusaBodies = [];
public static List<byte> InfectedBodies = [];
public static List<byte> BrakarVoteFor = [];
public static Dictionary<byte, float> WarlockTimer = [];
public static Dictionary<byte, float> AssassinTimer = [];
public static Dictionary<byte, float> UndertakerTimer = [];
public static Dictionary<byte, PlayerControl> CursedPlayers = [];
public static Dictionary<byte, bool> isCurseAndKill = [];
public static Dictionary<byte, int> MafiaRevenged = [];
public static Dictionary<byte, int> GuesserGuessed = [];
public static Dictionary<(byte, byte), bool> isDoused = [];
public static Dictionary<(byte, byte), bool> isDraw = [];
public static Dictionary<(byte, byte), bool> isRevealed = [];
public static Dictionary<byte, (PlayerControl PLAYER, float TIMER)> ArsonistTimer = [];
public static Dictionary<byte, (PlayerControl PLAYER, float TIMER)> RevolutionistTimer = [];
public static Dictionary<byte, long> RevolutionistStart = [];
public static Dictionary<byte, long> RevolutionistLastTime = [];
public static Dictionary<byte, int> RevolutionistCountdown = [];
public static Dictionary<byte, byte> TaglockedList = [];
public static Dictionary<byte, byte> SpeedBoostTarget = [];
public static Dictionary<byte, int> MayorUsedButtonCount = [];
public static Dictionary<byte, int> ParaUsedButtonCount = [];
public static Dictionary<byte, int> MarioVentCount = [];
public static Dictionary<byte, long> VeteranInProtect = [];
public static Dictionary<byte, long> BlockSabo = [];
public static Dictionary<byte, int> JinxSpellCount = [];
public static Dictionary<byte, string> SleuthMsgs = [];
public static bool HasJustStarted;
public static int AliveImpostorCount;
public static bool isCursed;
public static Dictionary<byte, bool> CheckShapeshift = [];
public static Dictionary<byte, byte> ShapeshiftTarget = [];
public static bool VisibleTasksCount;
public static string nickName = "";
public static bool introDestroyed;
public static byte currentDousingTarget = byte.MaxValue;
public static byte currentDrawTarget = byte.MaxValue;
public static float DefaultCrewmateVision;
public static float DefaultImpostorVision;
public static bool IsAprilFools = DateTime.Now.Month == 4 && DateTime.Now.Day is 1;
public static bool ResetOptions = true;
public static byte FirstDied = byte.MaxValue;
public static byte ShieldPlayer = byte.MaxValue;
public static int MadmateNum;
public static Dictionary<byte, byte> Provoked = [];
public static Dictionary<byte, CustomRoles> DevRole = [];
public static List<PlayerControl> LoversPlayers = [];
public static bool isLoversDead = true;
public static List<byte> CyberStarDead = [];
public static List<byte> BaitAlive = [];
public static Dictionary<byte, int> KilledDiseased = [];
public static Dictionary<byte, int> KilledAntidote = [];
public static List<byte> BrakarVoteFor = [];
public static Dictionary<byte, string> SleuthMsgs = [];
public static int MadmateNum;
public static PlayerControl[] AllPlayerControls