using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Net.Http; using System.Net.Sockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using AmongUs.Data; using AmongUs.Data.Player; using AmongUs.GameOptions; using Assets.CoreScripts; using Assets.InnerNet; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using Costura; using Discord; using HarmonyLib; using Hazel; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using InnerNet; using LibCpp2IL; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Rewired; using TMPro; using TOHE.Modules; using TOHE.Modules.ChatManager; using TOHE.Patches; using TOHE.Roles.AddOns.Common; using TOHE.Roles.AddOns.Crewmate; using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Core; using TOHE.Roles.Core.AssignManager; using TOHE.Roles.Crewmate; using TOHE.Roles.Double; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; using TOHE.Roles.Vanilla; using Twitch; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("2024.0813.203.9999")] [assembly: AssemblyInformationalVersion("2024.0813.203.9999")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Moe")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Town Of Host Enhanced")] [assembly: AssemblyProduct("TOHE")] [assembly: AssemblyTitle("TOHE")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2024.813.203.9999")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class { static () { AssemblyLoader.Attach(); } } [CompilerGenerated] internal delegate TResult <>f__AnonymousDelegate0(T1 arg1 = default(T1), T2 arg2 = default(T2)); namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } internal class ThisAssembly { public static class Git { public static class BaseVersion { public const string Major = "2"; public const string Minor = "0"; public const string Patch = "2"; } public static class SemVer { public const string Major = "2"; public const string Minor = "0"; public const string Patch = "26"; public const string Label = ""; public const string DashLabel = ""; public const string Source = "Tag"; } public const bool IsDirty = false; public const string IsDirtyString = "false"; public const string RepositoryUrl = "https://github.com/0xDrMoe/TownofHost-Enhanced"; public const string Branch = "main"; public const string Commit = "f6840257"; public const string Sha = "f6840257e5d402fa347434d5de5536a2a68e5d30"; public const string CommitDate = "2024-08-14T03:58:50+08:00"; public const string Commits = "24"; public const string Tag = "v2.0.2-24-gf6840257"; public const string BaseTag = "v2.0.2"; } } namespace TOHE { internal static class FFAManager { [HarmonyPatch(typeof(PlayerControl), "FixedUpdate")] private class FixedUpdateInGameModeFFAPatch { private static long LastFixedUpdate; public static void Postfix() { //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsInTask || Options.CurrentGameMode != CustomGameMode.FFA) { return; } long now = Utils.GetTimeStamp(); if (LastFixedUpdate == now) { return; } LastFixedUpdate = now; RoundTime--; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } PlayerControl[] array = Main.AllPlayerControls.Where((PlayerControl pc) => NameNotify.TryGetValue(pc.PlayerId, out (string, long) value5) && value5.Item2 < now).ToArray(); foreach (PlayerControl val in array) { NameNotify.Remove(val.PlayerId); SendRPCSyncNameNotify(val); Utils.NotifyRoles(val, val); } byte num = (byte)IRandom.Instance.Next(0, 100); bool flag = false; if (num == 0) { flag = true; } if (FFA_EnableRandomTwists.GetBool() && flag) { Logger.Info("Swap everyone with someone", "FFA", escapeCRLF: true, 449, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); List changePositionPlayers = new List(); array = Main.AllAlivePlayerControls; foreach (PlayerControl pc2 in array) { if (!changePositionPlayers.Contains(pc2.PlayerId) && pc2.IsAlive() && !pc2.onLadder && !pc2.inVent) { PlayerControl[] array2 = Main.AllAlivePlayerControls.Where((PlayerControl a) => pc2.IsAlive() && !pc2.inVent && a.PlayerId != pc2.PlayerId && !changePositionPlayers.Contains(a.PlayerId)).ToArray(); if (array2.Length == 0) { break; } PlayerControl val2 = array2.RandomElement(); if (!pc2.inVent && !val2.inVent) { changePositionPlayers.Add(val2.PlayerId); changePositionPlayers.Add(pc2.PlayerId); pc2.RPCPlayCustomSound("Teleport"); Vector2 customPosition = val2.GetCustomPosition(); val2.RpcTeleport(pc2.GetCustomPosition()); pc2.RpcTeleport(customPosition); val2.Notify(Utils.ColorString(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue), string.Format(Translator.GetString("FFA-Event-RandomTP"), pc2.GetRealName()))); pc2.Notify(Utils.ColorString(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue), string.Format(Translator.GetString("FFA-Event-RandomTP"), val2.GetRealName()))); } } } changePositionPlayers.Clear(); } if (GameStates.AirshipIsActive) { return; } array = Main.AllAlivePlayerControls; foreach (PlayerControl val3 in array) { if ((Object)(object)val3 == (Object)null) { break; } bool flag2 = false; if (FFADecreasedSpeedList.TryGetValue(val3.PlayerId, out var value) && value + FFA_ModifiedSpeedDuration.GetInt() < now) { Logger.Info(val3.GetRealName() + "'s decreased speed expired", "FFA", escapeCRLF: true, 491, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); FFADecreasedSpeedList.Remove(val3.PlayerId); Main.AllPlayerSpeed[val3.PlayerId] = originalSpeed[val3.PlayerId]; originalSpeed.Remove(val3.PlayerId); flag2 = true; } if (FFAIncreasedSpeedList.TryGetValue(val3.PlayerId, out var value2) && value2 + FFA_ModifiedSpeedDuration.GetInt() < now) { Logger.Info(val3.GetRealName() + "'s increased speed expired", "FFA", escapeCRLF: true, 499, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); FFAIncreasedSpeedList.Remove(val3.PlayerId); Main.AllPlayerSpeed[val3.PlayerId] = originalSpeed[val3.PlayerId]; originalSpeed.Remove(val3.PlayerId); flag2 = true; } if (FFALowerVisionList.TryGetValue(val3.PlayerId, out var value3) && value3 + FFA_ModifiedSpeedDuration.GetInt() < now) { Logger.Info(val3.GetRealName() + "'s lower vision effect expired", "FFA", escapeCRLF: true, 507, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); FFALowerVisionList.Remove(val3.PlayerId); flag2 = true; } if (FFAShieldedList.TryGetValue(val3.PlayerId, out var value4) && value4 + FFA_ShieldDuration.GetInt() < now) { Logger.Info(val3.GetRealName() + "'s shield expired", "FFA", escapeCRLF: true, 513, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); FFAShieldedList.Remove(val3.PlayerId); } if (flag2) { val3.MarkDirtySettings(); } } } } private static Dictionary FFAShieldedList = new Dictionary(); private static Dictionary FFAIncreasedSpeedList = new Dictionary(); private static Dictionary FFADecreasedSpeedList = new Dictionary(); public static Dictionary FFALowerVisionList = new Dictionary(); public static Dictionary FFAEnterVentTime = new Dictionary(); public static Dictionary FFAVentDuration = new Dictionary(); private static Dictionary originalSpeed = new Dictionary(); public static Dictionary KBScore = new Dictionary(); public static Dictionary FFALastKill = new Dictionary(); public static int RoundTime; public static OptionItem FFA_GameTime; public static OptionItem FFA_KCD; public static OptionItem FFA_LowerVision; public static OptionItem FFA_IncreasedSpeed; public static OptionItem FFA_DecreasedSpeed; public static OptionItem FFA_ShieldDuration; public static OptionItem FFA_ModifiedVisionDuration; public static OptionItem FFA_ModifiedSpeedDuration; public static OptionItem FFA_DisableVentingWhenTwoPlayersAlive; public static OptionItem FFA_DisableVentingWhenKCDIsUp; public static OptionItem FFA_EnableRandomAbilities; public static OptionItem FFA_EnableRandomTwists; public static OptionItem FFA_ShieldIsOneTimeUse; public static Dictionary NameNotify = new Dictionary(); public static void SetupCustomOption() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) FFA_GameTime = IntegerOptionItem.Create(67223001, "FFA_GameTime", new IntegerValueRule(30, 600, 10), 300, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Seconds) .SetHeader(value: true); FFA_KCD = FloatOptionItem.Create(67223002, "FFA_KCD", new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Seconds); FFA_DisableVentingWhenTwoPlayersAlive = BooleanOptionItem.Create(67223003, "FFA_DisableVentingWhenTwoPlayersAlive", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))); FFA_DisableVentingWhenKCDIsUp = BooleanOptionItem.Create(67223004, "FFA_DisableVentingWhenKCDIsUp", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))); FFA_EnableRandomAbilities = BooleanOptionItem.Create(67223005, "FFA_EnableRandomAbilities", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))); FFA_ShieldDuration = FloatOptionItem.Create(67223006, "FFA_ShieldDuration", new FloatValueRule(1f, 70f, 1f), 7f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Seconds); FFA_IncreasedSpeed = FloatOptionItem.Create(67223007, "FFA_IncreasedSpeed", new FloatValueRule(0.1f, 5f, 0.1f), 1.5f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Multiplier); FFA_DecreasedSpeed = FloatOptionItem.Create(67223008, "FFA_DecreasedSpeed", new FloatValueRule(0.1f, 5f, 0.1f), 1f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Multiplier); FFA_ModifiedSpeedDuration = FloatOptionItem.Create(67223009, "FFA_ModifiedSpeedDuration", new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Seconds); FFA_LowerVision = FloatOptionItem.Create(67223010, "FFA_LowerVision", new FloatValueRule(0f, 1f, 0.05f), 0.5f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Multiplier); FFA_ModifiedVisionDuration = FloatOptionItem.Create(67223011, "FFA_ModifiedVisionDuration", new FloatValueRule(1f, 70f, 1f), 5f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))) .SetValueFormat(OptionFormat.Seconds); FFA_EnableRandomTwists = BooleanOptionItem.Create(67223012, "FFA_EnableRandomTwists", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))); FFA_ShieldIsOneTimeUse = BooleanOptionItem.Create(67223013, "FFA_ShieldIsOneTimeUse", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.FFA).SetColor(Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, (byte)165, byte.MaxValue))); } public static void Init() { if (Options.CurrentGameMode != CustomGameMode.FFA) { return; } FFADecreasedSpeedList = new Dictionary(); FFAIncreasedSpeedList = new Dictionary(); FFALowerVisionList = new Dictionary(); FFAShieldedList = new Dictionary(); originalSpeed = new Dictionary(); KBScore = new Dictionary(); if (FFA_DisableVentingWhenKCDIsUp.GetBool()) { FFALastKill = new Dictionary(); FFAVentDuration = new Dictionary(); FFAEnterVentTime = new Dictionary(); } new LateTask(delegate { try { Utils.SetChatVisibleForEveryone(); } catch (Exception value) { Logger.Error($"Error: {value}", "FFA Init", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); } RoundTime = FFA_GameTime.GetInt() + 8; long value2 = Utils.GetTimeStamp() + 8; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { KBScore.TryAdd(val.PlayerId, 0); if (FFA_DisableVentingWhenKCDIsUp.GetBool()) { FFALastKill.TryAdd(val.PlayerId, value2); } } }, 10f, "Set Chat Visible for Everyone"); } private static void SendRPCSyncFFAPlayer(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)195, (SendOption)1, -1); val.Write(playerId); val.Write(KBScore[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCSyncFFAPlayer(MessageReader reader) { byte key = reader.ReadByte(); KBScore[key] = reader.ReadInt32(); } public static void SendRPCSyncNameNotify(PlayerControl pc) { if (!((InnerNetObject)pc).AmOwner && pc.IsModClient()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)196, (SendOption)1, pc.GetClientId()); if (NameNotify.ContainsKey(pc.PlayerId)) { val.Write(NameNotify[pc.PlayerId].TEXT); } else { val.Write(string.Empty); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPCSyncNameNotify(MessageReader reader) { string text = reader.ReadString(); NameNotify.Remove(PlayerControl.LocalPlayer.PlayerId); if (text != null && text != string.Empty) { NameNotify.Add(PlayerControl.LocalPlayer.PlayerId, (text, 0L)); } } public static void GetNameNotify(PlayerControl player, ref string name) { if (Options.CurrentGameMode == CustomGameMode.FFA && !((Object)(object)player == (Object)null) && NameNotify.ContainsKey(player.PlayerId)) { name = NameNotify[player.PlayerId].TEXT; } } public static string GetDisplayScore(byte playerId) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) int rankOfScore = GetRankOfScore(playerId); int value; string arg = (KBScore.TryGetValue(playerId, out value) ? $"{value}" : "Invalid"); string str = string.Format(Translator.GetString("FFADisplayScore"), rankOfScore.ToString(), arg); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Killer)), str); } public static int GetRankOfScore(byte playerId) { try { int ms = KBScore[playerId]; return 1 + KBScore.Values.Count((int x) => x > ms) + KBScore.Where((KeyValuePair x) => x.Value == ms).ToList().IndexOf(new KeyValuePair(playerId, ms)); } catch { return Main.AllPlayerControls.Length; } } public static string GetHudText() { return string.Format(Translator.GetString("FFATimeRemain"), RoundTime.ToString()); } public static void OnPlayerAttack(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || Options.CurrentGameMode != CustomGameMode.FFA) { return; } if (target.inVent) { Logger.Info("Target is in a vent, kill blocked", "FFA", escapeCRLF: true, 191, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); return; } int num = Main.AllAlivePlayerControls.Length; if (FFAShieldedList.TryGetValue(target.PlayerId, out var value)) { killer.Notify(Translator.GetString("FFA_TargetIsShielded")); Logger.Info($"{killer.GetRealName().RemoveHtmlTags()} attacked shielded player {target.GetRealName().RemoveHtmlTags()}, their shield expires in {FFA_ShieldDuration.GetInt() - (Utils.GetTimeStamp() - value)}s", "FFA", escapeCRLF: true, 198, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); if (FFA_ShieldIsOneTimeUse.GetBool()) { FFAShieldedList.Remove(target.PlayerId); target.Notify(Translator.GetString("FFA_ShieldBroken")); Logger.Info(target.GetRealName().RemoveHtmlTags() + "'s shield was removed because " + killer.GetRealName().RemoveHtmlTags() + " tried to kill them and the shield is one-time-use according to settings", "FFA", escapeCRLF: true, 203, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); } return; } OnPlayerKill(killer); SendRPCSyncFFAPlayer(target.PlayerId); if (num == 3) { PlayerControl val = null; PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl a) => a.PlayerId != killer.PlayerId && a.PlayerId != target.PlayerId && a.IsAlive()).ToArray(); foreach (PlayerControl val2 in array) { TargetArrow.Add(killer.PlayerId, val2.PlayerId); TargetArrow.Add(val2.PlayerId, killer.PlayerId); val = val2; } Logger.Info($"The last 2 players ({killer.GetRealName().RemoveHtmlTags()} & {val?.GetRealName().RemoveHtmlTags()}) now have an arrow toward each other", "FFA", escapeCRLF: true, 221, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); } if (FFA_EnableRandomAbilities.GetBool()) { bool flag = false; bool flag2 = false; float num2 = Main.AllPlayerKillCooldown[killer.PlayerId]; byte b = (GameStates.AirshipIsActive ? ((byte)HashRandom.Next(4, 10)) : ((byte)HashRandom.Next(0, 10))); if (b <= 7) { byte b2 = (byte)HashRandom.Next(0, 3); if (GameStates.AirshipIsActive) { b2 = 2; } switch (b2) { case 0: FFAShieldedList.TryAdd(killer.PlayerId, Utils.GetTimeStamp()); killer.Notify(Translator.GetString("FFA-Event-GetShield"), FFA_ShieldDuration.GetFloat()); Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); break; case 1: if (FFAIncreasedSpeedList.ContainsKey(killer.PlayerId)) { FFAIncreasedSpeedList.Remove(killer.PlayerId); FFAIncreasedSpeedList.Add(killer.PlayerId, Utils.GetTimeStamp()); } else { FFAIncreasedSpeedList.TryAdd(killer.PlayerId, Utils.GetTimeStamp()); originalSpeed.TryAdd(killer.PlayerId, Main.AllPlayerSpeed[killer.PlayerId]); Main.AllPlayerSpeed[killer.PlayerId] = FFA_IncreasedSpeed.GetFloat(); } killer.Notify(Translator.GetString("FFA-Event-GetIncreasedSpeed"), FFA_ModifiedSpeedDuration.GetFloat()); Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); flag = true; break; case 2: Main.AllPlayerKillCooldown[killer.PlayerId] = Math.Clamp(FFA_KCD.GetFloat() - 3f, 1f, 60f); killer.Notify(Translator.GetString("FFA-Event-GetLowKCD")); flag = true; break; default: Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); flag = true; break; } } else if (b == 8) { byte b3 = (byte)HashRandom.Next(0, 3); if (GameStates.AirshipIsActive) { b3 = 1; } switch (b3) { case 0: if (FFADecreasedSpeedList.ContainsKey(killer.PlayerId)) { FFADecreasedSpeedList.Remove(killer.PlayerId); FFADecreasedSpeedList.Add(killer.PlayerId, Utils.GetTimeStamp()); } else { FFADecreasedSpeedList.TryAdd(killer.PlayerId, Utils.GetTimeStamp()); originalSpeed.TryAdd(killer.PlayerId, Main.AllPlayerSpeed[killer.PlayerId]); Main.AllPlayerSpeed[killer.PlayerId] = FFA_DecreasedSpeed.GetFloat(); } killer.Notify(Translator.GetString("FFA-Event-GetDecreasedSpeed"), FFA_ModifiedSpeedDuration.GetFloat()); Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); flag = true; break; case 1: Main.AllPlayerKillCooldown[killer.PlayerId] = Math.Clamp(FFA_KCD.GetFloat() + 3f, 1f, 60f); killer.Notify(Translator.GetString("FFA-Event-GetHighKCD")); flag = true; break; case 2: FFALowerVisionList.TryAdd(killer.PlayerId, Utils.GetTimeStamp()); Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); killer.Notify(Translator.GetString("FFA-Event-GetLowVision")); flag2 = true; break; default: Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); flag = true; break; } } else { new LateTask(killer.RpcRandomVentTeleport, 0.5f, "FFA-Event-TP"); killer.Notify(Translator.GetString("FFA-Event-GetTP")); Main.AllPlayerKillCooldown[killer.PlayerId] = FFA_KCD.GetFloat(); } if (flag || num2 != Main.AllPlayerKillCooldown[killer.PlayerId]) { flag2 = false; killer.SyncSettings(); } if (flag2) { killer.MarkDirtySettings(); } } long timeStamp = Utils.GetTimeStamp(); if (FFA_DisableVentingWhenKCDIsUp.GetBool()) { FFALastKill[killer.PlayerId] = timeStamp; FFAVentDuration[killer.PlayerId] = 0f; FFAEnterVentTime.Remove(killer.PlayerId); } killer.RpcMurderPlayer(target); } public static void OnPlayerKill(PlayerControl killer) { if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) { PlayerControl.LocalPlayer.KillFlash(); } KBScore[killer.PlayerId]++; } public static bool CheckCoEnterVent(PlayerPhysics physics, int ventId) { if (FFA_DisableVentingWhenTwoPlayersAlive.GetBool() && Main.AllAlivePlayerControls.Length <= 2) { PlayerControl pc2 = ((physics != null) ? physics.myPlayer : null); new LateTask(delegate { pc2?.Notify(Translator.GetString("FFA-NoVentingBecauseTwoPlayers"), 7f); PlayerControl obj2 = pc2; if (obj2 != null) { PlayerPhysics myPhysics2 = obj2.MyPhysics; if (myPhysics2 != null) { myPhysics2.RpcBootFromVent(ventId); } } }, 0.5f, "Player No Venting Because Two Players"); return true; } if (FFA_DisableVentingWhenKCDIsUp.GetBool()) { PlayerControl pc = ((physics != null) ? physics.myPlayer : null); long timeStamp = Utils.GetTimeStamp(); FFAEnterVentTime[pc.PlayerId] = timeStamp; if (!FFAVentDuration.ContainsKey(pc.PlayerId)) { FFAVentDuration[pc.PlayerId] = 0f; } bool flag = (float)(timeStamp - FFALastKill[pc.PlayerId]) <= Main.AllPlayerKillCooldown[pc.PlayerId] + FFAVentDuration[pc.PlayerId]; Logger.Warn($"Enter Time = {timeStamp}, last kill time = {FFALastKill[pc.PlayerId]}, {FFAVentDuration[pc.PlayerId]}", "VENT DURATION TESTING", escapeCRLF: true, 365, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); Logger.Warn($"can vent {flag}", "FFA MODE VENTING", escapeCRLF: true, 366, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); if (!flag) { new LateTask(delegate { pc?.Notify(Translator.GetString("FFA-NoVentingBecauseKCDIsUP"), 7f); PlayerControl obj = pc; if (obj != null) { PlayerPhysics myPhysics = obj.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventId); } } }, 0.5f, "Player No Venting Because KCD Is UP"); return true; } } return false; } public static void CoExitVent(PlayerControl player) { if ((Object)(object)player == (Object)null) { return; } long timeStamp = Utils.GetTimeStamp(); byte playerId = player.PlayerId; if (FFAEnterVentTime.ContainsKey(playerId)) { if (!FFAVentDuration.ContainsKey(playerId)) { FFAVentDuration[playerId] = 0f; } FFAVentDuration[playerId] += (float)(timeStamp - FFAEnterVentTime[playerId]); Logger.Warn($"Vent Duration = {FFAVentDuration[playerId]}, vent enter time = {FFAEnterVentTime[playerId]}, vent exit time = {timeStamp}, vent time = {timeStamp - FFAEnterVentTime[playerId]}", "FFA VENT DURATION", escapeCRLF: true, 393, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\GameModes\\FFAManager.cs"); FFAEnterVentTime.Remove(playerId); } } public static string GetPlayerArrow(PlayerControl seer, PlayerControl target = null) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsMeeting) { return string.Empty; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return string.Empty; } if (Main.AllAlivePlayerControls.Length != 2) { return string.Empty; } string empty = string.Empty; PlayerControl val = null; PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl pc) => pc.IsAlive() && pc.PlayerId != seer.PlayerId).ToArray(); int num = 0; if (num < array.Length) { val = array[num]; } if ((Object)(object)val == (Object)null) { return string.Empty; } string arrows = TargetArrow.GetArrows(seer, val.PlayerId); return empty + Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Killer)), arrows); } } public static class EnumerationHelpers { public static IEnumerable GetFastEnumerator(this List list) where T : Object { return new Il2CppListEnumerable(list); } } public class Il2CppListEnumerable : IEnumerable, IEnumerable, IEnumerator, IEnumerator, IDisposable where T : Object { private struct Il2CppListStruct { private IntPtr _unusedPtr1; private IntPtr _unusedPtr2; public IntPtr _items; public int _size; } private static readonly int _elemSize; private static readonly int _offset; private static Func _objFactory; private readonly IntPtr _arrayPointer; private readonly int _count; private int _index = -1; object IEnumerator.Current => Current; public T Current { get; private set; } static Il2CppListEnumerable() { _elemSize = IntPtr.Size; _offset = 4 * IntPtr.Size; ConstructorInfo? constructor = typeof(T).GetConstructor(new Type[1] { typeof(IntPtr) }); ParameterExpression parameterExpression = Expression.Parameter(typeof(IntPtr)); _objFactory = Expression.Lambda>(Expression.New(constructor, parameterExpression), new ParameterExpression[1] { parameterExpression }).Compile(); } public unsafe Il2CppListEnumerable(List list) { Il2CppListStruct* ptr = (Il2CppListStruct*)(void*)((Il2CppObjectBase)list).Pointer; _count = ptr->_size; _arrayPointer = ptr->_items; } public unsafe bool MoveNext() { if (++_index >= _count) { return false; } IntPtr arg = *(IntPtr*)(void*)IntPtr.Add(IntPtr.Add(_arrayPointer, _offset), _index * _elemSize); Current = _objFactory(arg); return true; } public void Reset() { _index = -1; } public IEnumerator GetEnumerator() { return this; } IEnumerator IEnumerable.GetEnumerator() { return this; } public void Dispose() { } } public static class EnumHelper { public static T[] GetAllValues() where T : Enum { return Enum.GetValues(typeof(T)) as T[]; } public static string[] GetAllNames() where T : Enum { return Enum.GetNames(typeof(T)); } public static List Achunk(int chunkSize, bool shuffle = false, Func exclude = null) where TEnum : Enum { List list = new List(); TEnum[] array = GetAllValues(); IRandom instance = IRandom.Instance; if (shuffle) { array = array.Shuffle(instance).ToArray(); } if (exclude != null) { array = array.Where(exclude).ToArray(); } for (int i = 0; i < array.Length; i += chunkSize) { TEnum[] array2 = new TEnum[Math.Min(chunkSize, array.Length - i)]; Array.Copy(array, i, array2, 0, array2.Length); list.Add(array2); } return list; } } public static class Il2CppHelper { public static List ToIl2Cpp(this List sysList) { List val = new List(); foreach (T sys in sysList) { val.Add(sys); } return val; } public static List ToManaged(this List iList) { return ((IEnumerable)iList.ToArray()).ToList(); } public static bool TryCast(this Il2CppObjectBase obj, out T casted) where T : Il2CppObjectBase { casted = obj.TryCast(); return casted != null; } } public static class ObjectHelper { public static void DestroyTranslator(this GameObject obj) { TextTranslatorTMP component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } public static void DestroyTranslator(this MonoBehaviour obj) { ((Component)obj).gameObject.DestroyTranslator(); } } [BepInPlugin("com.0xdrmoe.townofhostenhanced", "TOHE", "2024.0813.203.9999")] [BepInIncompatibility("jp.ykundesu.supernewroles")] [BepInProcess("Among Us.exe")] public class Main : BasePlugin { public const string OriginalForkId = "OriginalTOH"; public static readonly string ModName = "TOHE"; public static readonly string ForkId = "TOHE"; public static readonly string ModColor = "#ffc0cb"; public static readonly bool AllowPublicRoom = true; public const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d"; public const string DebugKeySalt = "59687b"; public const string PluginGuid = "com.0xdrmoe.townofhostenhanced"; public const string PluginVersion = "2024.0813.203.9999"; public const string PluginDisplayVersion = "2.0.3"; public const string SupportedVersionAU = "2024.8.13"; public static readonly bool devRelease = false; public static readonly bool canaryRelease = false; public static readonly bool fullRelease = true; public static bool hasAccess = true; public static readonly bool ShowUpdateButton = true; public static readonly bool ShowGitHubButton = true; public static readonly string GitHubInviteUrl = "https://github.com/0xDrMoe/TownofHost-Enhanced"; public static readonly bool ShowDiscordButton = true; public static readonly string DiscordInviteUrl = "https://discord.gg/tohe"; public static readonly bool ShowWebsiteButton = true; public static readonly string WebsiteInviteUrl = "https://weareten.ca/"; public static readonly bool ShowDonationButton = true; public static readonly string DonationInviteUrl = "https://weareten.ca/TOHE"; public static Version version = Version.Parse("2024.0813.203.9999"); public static ManualLogSource Logger; public static bool hasArgumentException = false; public static string ExceptionMessage; public static bool ExceptionMessageIsShown = false; public static bool AlreadyShowMsgBox = false; public static string credentialsText; public Coroutines coroutines; public static bool IsHostVersionCheating = false; public static Dictionary playerVersion = new Dictionary(); public static OptionBackupData RealOptionsData; public static Dictionary PlayerStates = new Dictionary(); public static readonly Dictionary AllPlayerNames = new Dictionary(); public static readonly Dictionary AllClientRealNames = new Dictionary(); public static readonly Dictionary AllPlayerCustomRoles = new Dictionary(); public static readonly Dictionary<(byte, byte), string> LastNotifyNames = new Dictionary<(byte, byte), string>(); public static readonly Dictionary LateOutfits = new Dictionary(); public static readonly Dictionary PlayerColors = new Dictionary(); public static readonly Dictionary AfterMeetingDeathPlayers = new Dictionary(); public static readonly Dictionary roleColors = new Dictionary(); private const string LANGUAGE_FOLDER_NAME = "Language"; public static float RefixCooldownDelay = 0f; public static NetworkedPlayerInfo LastVotedPlayerInfo; public static string LastVotedPlayer; public static readonly HashSet ResetCamPlayerList = new HashSet(); public static readonly HashSet winnerList = new HashSet(); public static readonly HashSet winnerNameList = new HashSet(); public static readonly HashSet clientIdList = new HashSet(); public static readonly List<(string, byte, string)> MessagesToSend = new List<(string, byte, string)>(); public static readonly Dictionary PlayerQuitTimes = new Dictionary(); public static bool isChatCommand = false; public static bool MeetingIsStarted = false; public static readonly HashSet TasklessCrewmate = new HashSet(); public static readonly HashSet OverDeadPlayerList = new HashSet(); public static readonly HashSet UnreportableBodies = new HashSet(); public static readonly Dictionary AllPlayerKillCooldown = new Dictionary(); public static readonly Dictionary LastEnteredVent = new Dictionary(); public static readonly Dictionary LastEnteredVentLocation = new Dictionary(); public static readonly Dictionary SayStartTimes = new Dictionary(); public static readonly Dictionary SayBanwordsTimes = new Dictionary(); public static readonly Dictionary AllPlayerSpeed = new Dictionary(); public static readonly HashSet PlayersDiedInMeeting = new HashSet(); public static readonly Dictionary AllKillers = new Dictionary(); public static readonly Dictionary CheckShapeshift = new Dictionary(); public static readonly Dictionary ShapeshiftTarget = new Dictionary(); public static bool isLoversDead = true; public static readonly HashSet LoversPlayers = new HashSet(); public static bool DoBlockNameChange = false; public static int updateTime; public const float MinSpeed = 0.0001f; public static int AliveImpostorCount; public static bool VisibleTasksCount = false; public static bool AssignRolesIsStarted = false; public static string HostRealName = ""; public static bool introDestroyed = false; public static int DiscussionTime; public static int VotingTime; public static float DefaultCrewmateVision; public static float DefaultImpostorVision; public static bool IsInitialRelease = DateTime.Now.Month == 1 && DateTime.Now.Day == 17; public static bool IsAprilFools = DateTime.Now.Month == 4 && DateTime.Now.Day == 1; public static bool ResetOptions = true; public static string FirstDied = ""; public static string ShieldPlayer = ""; public static int MadmateNum = 0; public static int BardCreations = 0; public static int MeetingsPassed = 0; public static Main Instance; public static string OverrideWelcomeMsg = ""; public static int HostClientId; public static Dictionary> GuessNumber = new Dictionary>(); public static List TName_Snacks_CN = new List(35) { "冰激凌", "奶茶", "巧克力", "蛋糕", "甜甜圈", "可乐", "柠檬水", "冰糖葫芦", "果冻", "糖果", "牛奶", "抹茶", "烧仙草", "菠萝包", "布丁", "椰子冻", "曲奇", "红豆土司", "三彩团子", "艾草团子", "泡芙", "可丽饼", "桃酥", "麻薯", "鸡蛋仔", "马卡龙", "雪梅娘", "炒酸奶", "蛋挞", "松饼", "西米露", "奶冻", "奶酥", "可颂", "奶糖" }; public static List TName_Snacks_EN = new List(35) { "Ice cream", "Milk tea", "Chocolate", "Cake", "Donut", "Coke", "Lemonade", "Candied haws", "Jelly", "Candy", "Milk", "Matcha", "Burning Grass Jelly", "Pineapple Bun", "Pudding", "Coconut Jelly", "Cookies", "Red Bean Toast", "Three Color Dumplings", "Wormwood Dumplings", "Puffs", "Can be Crepe", "Peach Crisp", "Mochi", "Egg Waffle", "Macaron", "Snow Plum Niang", "Fried Yogurt", "Egg Tart", "Muffin", "Sago Dew", "panna cotta", "soufflé", "croissant", "toffee" }; public static HashAuth DebugKeyAuth { get; private set; } public static ConfigEntry DebugKeyInput { get; private set; } public Harmony Harmony { get; } = new Harmony("com.0xdrmoe.townofhostenhanced"); public static NormalGameOptionsV08 NormalOptions => GameOptionsManager.Instance.currentNormalGameOptions; public static HideNSeekGameOptionsV08 HideNSeekOptions => GameOptionsManager.Instance.currentHideNSeekGameOptions; public static ConfigEntry HideName { get; private set; } public static ConfigEntry HideColor { get; private set; } public static ConfigEntry MessageWait { get; private set; } public static ConfigEntry UnlockFPS { get; private set; } public static ConfigEntry ShowFPS { get; private set; } public static ConfigEntry EnableGM { get; private set; } public static ConfigEntry AutoStart { get; private set; } public static ConfigEntry DarkTheme { get; private set; } public static ConfigEntry DisableLobbyMusic { get; private set; } public static ConfigEntry ShowTextOverlay { get; private set; } public static ConfigEntry HorseMode { get; private set; } public static ConfigEntry ForceOwnLanguage { get; private set; } public static ConfigEntry ForceOwnLanguageRoleName { get; private set; } public static ConfigEntry EnableCustomButton { get; private set; } public static ConfigEntry EnableCustomSoundEffect { get; private set; } public static ConfigEntry EnableCustomDecorations { get; private set; } public static ConfigEntry SwitchVanilla { get; private set; } public static ConfigEntry VersionCheat { get; private set; } public static ConfigEntry GodMode { get; private set; } public static ConfigEntry AutoRehost { get; private set; } public static ConfigEntry Preset1 { get; private set; } public static ConfigEntry Preset2 { get; private set; } public static ConfigEntry Preset3 { get; private set; } public static ConfigEntry Preset4 { get; private set; } public static ConfigEntry Preset5 { get; private set; } public static ConfigEntry WebhookURL { get; private set; } public static ConfigEntry BetaBuildURL { get; private set; } public static ConfigEntry LastKillCooldown { get; private set; } public static ConfigEntry LastShapeshifterCooldown { get; private set; } public static ConfigEntry PlayerSpawnTimeOutCooldown { get; private set; } public static bool IsFixedCooldown { get { if (!CustomRoles.Vampire.IsEnable()) { return CustomRoles.Poisoner.IsEnable(); } return true; } } public static PlayerControl[] AllPlayerControls => ((IEnumerable)PlayerControl.AllPlayerControls.ToArray()).Where((PlayerControl p) => (Object)(object)p != (Object)null).ToArray(); public static PlayerControl[] AllAlivePlayerControls => ((IEnumerable)PlayerControl.AllPlayerControls.ToArray()).Where((PlayerControl p) => (Object)(object)p != (Object)null && p.IsAlive() && !p.Data.Disconnected && !Pelican.IsEaten(p.PlayerId)).ToArray(); public static string Get_TName_Snacks { get { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; if (languageID - 13 > 1) { return TName_Snacks_EN.RandomElement(); } return TName_Snacks_CN.RandomElement(); } } private static void CreateTemplateRoleColorFile() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair roleColor in roleColors) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(roleColor.Key); handler.AppendLiteral(":\n"); stringBuilder2.Append(ref handler); } File.WriteAllText("./Language/templateRoleColor.dat", stringBuilder.ToString()); } public static void LoadCustomRoleColor() { string path = "./Language/RoleColor.dat"; if (File.Exists(path)) { TOHE.Logger.Info("Load custom Role Color file:RoleColor.dat", "LoadCustomRoleColor", escapeCRLF: true, 209, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); using StreamReader streamReader = new StreamReader(path, Encoding.GetEncoding("UTF-8")); string[] array = Array.Empty(); string text; while ((text = streamReader.ReadLine()) != null) { array = text.Split(":"); if (array.Length <= 1 || !(array[1] != "")) { continue; } try { if (Enum.TryParse(array[0], out var result)) { string text2 = array[1].Trim().TrimStart('#'); if (Utils.CheckColorHex(text2)) { roleColors[result] = "#" + text2; } else { TOHE.Logger.Error("Invalid Hexcolor #" + text2, "LoadCustomRoleColor", escapeCRLF: true, 227, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } } catch (KeyNotFoundException) { TOHE.Logger.Warn("Invalid Key:" + array[0], "LoadCustomTranslation", escapeCRLF: true, 232, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } return; } TOHE.Logger.Error("File not found:RoleColor.dat", "LoadCustomTranslation", escapeCRLF: true, 239, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } public void StartCoroutine(IEnumerator coroutine) { if (coroutine != null) { ((MonoBehaviour)coroutines).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(coroutine)); } } public void StopCoroutine(IEnumerator coroutine) { if (coroutine != null) { ((MonoBehaviour)coroutines).StopCoroutine(CollectionExtensions.WrapToIl2Cpp(coroutine)); } } public void StopAllCoroutines() { ((MonoBehaviour)coroutines).StopAllCoroutines(); } public static void LoadRoleColors() { try { roleColors.Clear(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = "TOHE.Resources.roleColor.json"; using (Stream stream = executingAssembly.GetManifestResourceStream(name)) { if (stream != null) { using StreamReader streamReader = new StreamReader(stream); foreach (KeyValuePair item in JsonSerializer.Deserialize>(streamReader.ReadToEnd())) { if (Enum.TryParse(item.Key, out var result)) { roleColors[result] = item.Value; } else { TOHE.Logger.Error("Invalid enum key: " + item.Key, "Reading Role Colors", escapeCRLF: true, 290, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } } else { TOHE.Logger.Error("Embedded resource not found.", "Reading Role Colors", escapeCRLF: true, 296, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } CustomRoles[] allValues = EnumHelper.GetAllValues(); foreach (CustomRoles customRoles in allValues) { if (customRoles.GetCustomRoleTeam() == Custom_Team.Impostor) { roleColors.TryAdd(customRoles, "#ff1919"); } } if (!Directory.Exists("Language")) { Directory.CreateDirectory("Language"); } CreateTemplateRoleColorFile(); if (File.Exists("./Language/RoleColor.dat")) { UpdateCustomTranslation(); LoadCustomRoleColor(); } } catch (ArgumentException ex) { TOHE.Logger.Error("错误:字典出现重复项", "LoadDictionary", escapeCRLF: true, 321, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); TOHE.Logger.Exception(ex, "LoadDictionary", 322, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); hasArgumentException = true; ExceptionMessage = ex.Message; ExceptionMessageIsShown = false; } } public static void LoadRoleClasses() { TOHE.Logger.Info("Loading All RoleClasses...", "LoadRoleClasses", escapeCRLF: true, 330, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); try { IEnumerable source = from myType in Assembly.GetAssembly(typeof(RoleBase)).GetTypes() where myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(RoleBase)) select myType; CustomRolesHelper.DuplicatedRoles = new Dictionary { { CustomRoles.NiceMini, typeof(Mini) }, { CustomRoles.EvilMini, typeof(Mini) } }; foreach (CustomRoles role in CustomRolesHelper.AllRoles.Where((CustomRoles x) => x < CustomRoles.NotAssigned)) { if (!CustomRolesHelper.DuplicatedRoles.TryGetValue(role, out var value)) { value = source.FirstOrDefault((Type x) => x.Name.Equals(role.ToString(), StringComparison.OrdinalIgnoreCase)) ?? typeof(DefaultSetup); } CustomRoleManager.RoleClass.Add(role, (RoleBase)Activator.CreateInstance(value)); } TOHE.Logger.Info("RoleClasses Loaded Successfully", "LoadRoleClasses", escapeCRLF: true, 354, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } catch (Exception value2) { TOHE.Logger.Error($"Error at LoadRoleClasses: {value2}", "LoadRoleClasses", escapeCRLF: true, 358, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } private static void UpdateCustomTranslation() { string path = "./Language/RoleColor.dat"; if (!File.Exists(path)) { return; } TOHE.Logger.Info("Updating Custom Role Colors", "UpdateRoleColors", escapeCRLF: true, 366, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); try { List list = new List(); using (StreamReader streamReader = new StreamReader(path, Encoding.GetEncoding("UTF-8"))) { string text; while ((text = streamReader.ReadLine()) != null) { string[] array = text.Split(':'); if (array.Length >= 1) { string item = array[0].Trim(); list.Add(item); } } } StringBuilder stringBuilder = new StringBuilder(); foreach (CustomRoles key in roleColors.Keys) { if (!list.Contains(key.ToString())) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(key); handler.AppendLiteral(":\n"); stringBuilder2.Append(ref handler); } } using FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write); using StreamWriter streamWriter = new StreamWriter(stream); streamWriter.WriteLine(stringBuilder.ToString()); } catch (Exception ex) { TOHE.Logger.Error("An error occurred: " + ex.Message, "UpdateRoleColors", escapeCRLF: true, 399, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } public static void ExportCustomRoleColors() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair roleColor in roleColors) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder2); handler.AppendFormatted(roleColor.Key.ToString()); handler.AppendLiteral(":"); handler.AppendFormatted(roleColor.Value); handler.AppendLiteral("\n"); stringBuilder2.Append(ref handler); } File.WriteAllText("./Language/export_RoleColor.dat", stringBuilder.ToString()); } public override void Load() { Instance = this; HideName = ((BasePlugin)this).Config.Bind("Client Options", "Hide Game Code Name", "TOHE", (ConfigDescription)null); HideColor = ((BasePlugin)this).Config.Bind("Client Options", "Hide Game Code Color", ModColor ?? "", (ConfigDescription)null); DebugKeyInput = ((BasePlugin)this).Config.Bind("Authentication", "Debug Key", "", (ConfigDescription)null); UnlockFPS = ((BasePlugin)this).Config.Bind("Client Options", "UnlockFPS", false, (ConfigDescription)null); ShowFPS = ((BasePlugin)this).Config.Bind("Client Options", "ShowFPS", false, (ConfigDescription)null); EnableGM = ((BasePlugin)this).Config.Bind("Client Options", "EnableGM", false, (ConfigDescription)null); AutoStart = ((BasePlugin)this).Config.Bind("Client Options", "AutoStart", false, (ConfigDescription)null); DarkTheme = ((BasePlugin)this).Config.Bind("Client Options", "DarkTheme", false, (ConfigDescription)null); DisableLobbyMusic = ((BasePlugin)this).Config.Bind("Client Options", "DisableLobbyMusic", false, (ConfigDescription)null); ShowTextOverlay = ((BasePlugin)this).Config.Bind("Client Options", "ShowTextOverlay", false, (ConfigDescription)null); HorseMode = ((BasePlugin)this).Config.Bind("Client Options", "HorseMode", false, (ConfigDescription)null); ForceOwnLanguage = ((BasePlugin)this).Config.Bind("Client Options", "ForceOwnLanguage", false, (ConfigDescription)null); ForceOwnLanguageRoleName = ((BasePlugin)this).Config.Bind("Client Options", "ForceOwnLanguageRoleName", false, (ConfigDescription)null); EnableCustomButton = ((BasePlugin)this).Config.Bind("Client Options", "EnableCustomButton", true, (ConfigDescription)null); EnableCustomSoundEffect = ((BasePlugin)this).Config.Bind("Client Options", "EnableCustomSoundEffect", true, (ConfigDescription)null); EnableCustomDecorations = ((BasePlugin)this).Config.Bind("Client Options", "EnableCustomDecorations", true, (ConfigDescription)null); SwitchVanilla = ((BasePlugin)this).Config.Bind("Client Options", "SwitchVanilla", false, (ConfigDescription)null); VersionCheat = ((BasePlugin)this).Config.Bind("Client Options", "VersionCheat", false, (ConfigDescription)null); GodMode = ((BasePlugin)this).Config.Bind("Client Options", "GodMode", false, (ConfigDescription)null); AutoRehost = ((BasePlugin)this).Config.Bind("Client Options", "AutoRehost", false, (ConfigDescription)null); Logger = Logger.CreateLogSource("TOHE"); coroutines = ((BasePlugin)this).AddComponent(); TOHE.Logger.Enable(); TOHE.Logger.Disable("SwitchSystem"); TOHE.Logger.Disable("ModNews"); TOHE.Logger.Disable("CustomRpcSender"); if (!DebugModeManager.AmDebugger) { TOHE.Logger.Disable("2018k"); TOHE.Logger.Disable("Github"); TOHE.Logger.Disable("SendRPC"); TOHE.Logger.Disable("SetRole"); TOHE.Logger.Disable("Info.Role"); TOHE.Logger.Disable("TaskState.Init"); TOHE.Logger.Disable("RpcSetNamePrivate"); TOHE.Logger.Disable("SetName"); TOHE.Logger.Disable("PlayerControl.RpcSetRole"); TOHE.Logger.Disable("SyncCustomSettings"); } DebugKeyAuth = new HashAuth("c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d", "59687b"); DebugModeManager.Auth(DebugKeyAuth, DebugKeyInput.Value); Preset1 = ((BasePlugin)this).Config.Bind("Preset Name Options", "Preset1", "Preset_1", (ConfigDescription)null); Preset2 = ((BasePlugin)this).Config.Bind("Preset Name Options", "Preset2", "Preset_2", (ConfigDescription)null); Preset3 = ((BasePlugin)this).Config.Bind("Preset Name Options", "Preset3", "Preset_3", (ConfigDescription)null); Preset4 = ((BasePlugin)this).Config.Bind("Preset Name Options", "Preset4", "Preset_4", (ConfigDescription)null); Preset5 = ((BasePlugin)this).Config.Bind("Preset Name Options", "Preset5", "Preset_5", (ConfigDescription)null); WebhookURL = ((BasePlugin)this).Config.Bind("Other", "WebhookURL", "none", (ConfigDescription)null); BetaBuildURL = ((BasePlugin)this).Config.Bind("Other", "BetaBuildURL", "", (ConfigDescription)null); MessageWait = ((BasePlugin)this).Config.Bind("Other", "MessageWait", 1, (ConfigDescription)null); LastKillCooldown = ((BasePlugin)this).Config.Bind("Other", "LastKillCooldown", 30f, (ConfigDescription)null); LastShapeshifterCooldown = ((BasePlugin)this).Config.Bind("Other", "LastShapeshifterCooldown", 30f, (ConfigDescription)null); PlayerSpawnTimeOutCooldown = ((BasePlugin)this).Config.Bind("Other", "PlayerSpawnTimeOutCooldown", 3f, (ConfigDescription)null); hasArgumentException = false; ExceptionMessage = ""; LoadRoleClasses(); LoadRoleColors(); CustomWinnerHolder.Reset(); Translator.Init(); BanManager.Init(); TemplateManager.Init(); DevManager.Init(); Cloud.Init(); IRandom.SetInstance(new NetRandomWrapper()); TOHE.Logger.Info(" " + Application.version, "Among Us Version", escapeCRLF: true, 507, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); LogHandler logHandler = TOHE.Logger.Handler("GitVersion"); logHandler.Info("BaseTag: v2.0.2"); logHandler.Info("Commit: f6840257"); logHandler.Info("Commits: 24"); logHandler.Info($"{"IsDirty"}: {0}"); logHandler.Info("Sha: f6840257e5d402fa347434d5de5536a2a68e5d30"); logHandler.Info("Tag: v2.0.2-24-gf6840257"); ClassInjector.RegisterTypeInIl2Cpp(); Harmony.PatchAll(); if (!DebugModeManager.AmDebugger) { ConsoleManager.DetachConsole(); } else { ConsoleManager.CreateConsole(); } TOHE.Logger.Msg("========= TOHE loaded! =========", "Plugin Load", escapeCRLF: true, 524, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\main.cs"); } } public enum CustomRoles { Crewmate = 0, Engineer = 1, GuardianAngel = 2, Noisemaker = 3, Scientist = 4, Tracker = 5, Impostor = 6, Phantom = 7, Shapeshifter = 8, CrewmateTOHE = 9, EngineerTOHE = 10, GuardianAngelTOHE = 11, NoisemakerTOHE = 12, ScientistTOHE = 13, TrackerTOHE = 14, ImpostorTOHE = 15, PhantomTOHE = 16, ShapeshifterTOHE = 17, Bloodmoon = 18, Minion = 19, Anonymous = 20, AntiAdminer = 21, Arrogance = 22, Bard = 23, Berserker = 24, Blackmailer = 25, Bomber = 26, BountyHunter = 27, Butcher = 28, Camouflager = 29, Chronomancer = 30, Cleaner = 31, Consigliere = 32, Councillor = 33, Crewpostor = 34, CursedWolf = 35, Dazzler = 36, Deathpact = 37, Devourer = 38, Disperser = 39, DollMaster = 40, Eraser = 41, Escapist = 42, EvilGuesser = 43, EvilHacker = 44, EvilMini = 45, EvilTracker = 46, Fireworker = 47, Gangster = 48, Godfather = 49, Greedy = 50, Hangman = 51, Inhibitor = 52, Instigator = 53, Kamikaze = 54, KillingMachine = 55, Lightning = 56, Ludopath = 57, Lurker = 58, Mastermind = 59, Mercenary = 60, Miner = 61, Morphling = 62, Nemesis = 63, Ninja = 64, Parasite = 65, Penguin = 66, Pitfall = 67, Puppeteer = 68, QuickShooter = 69, Refugee = 70, RiftMaker = 71, Saboteur = 72, Scavenger = 73, ShapeMaster = 74, Sniper = 75, SoulCatcher = 76, Stealth = 77, Swooper = 78, TimeThief = 79, Trapster = 80, Trickster = 81, Twister = 82, Underdog = 83, Undertaker = 84, Vampire = 85, Vindicator = 86, Visionary = 87, Warlock = 88, Wildling = 89, Witch = 90, Zombie = 91, Ghastly = 92, Hawk = 93, Warden = 94, Addict = 95, Admirer = 96, Alchemist = 97, Bastion = 98, Benefactor = 99, Bodyguard = 100, Captain = 101, Celebrity = 102, Chameleon = 103, ChiefOfPolice = 104, Cleanser = 105, CopyCat = 106, Coroner = 107, Crusader = 108, Deceiver = 109, Deputy = 110, Detective = 111, Dictator = 112, Doctor = 113, Enigma = 114, FortuneTeller = 115, Grenadier = 116, Guardian = 117, GuessMaster = 118, Inspector = 119, Investigator = 120, Jailer = 121, Judge = 122, Keeper = 123, Knight = 124, LazyGuy = 125, Lighter = 126, Lookout = 127, Marshall = 128, Mayor = 129, Mechanic = 130, Medic = 131, Medium = 132, Merchant = 133, Mole = 134, Monarch = 135, Mortician = 136, NiceGuesser = 137, NiceMini = 138, Observer = 139, Oracle = 140, Overseer = 141, Pacifist = 142, President = 143, Psychic = 144, Randomizer = 145, Retributionist = 146, Reverie = 147, Sheriff = 148, Snitch = 149, SpeedBooster = 150, Spiritualist = 151, Spy = 152, SuperStar = 153, Swapper = 154, TaskManager = 155, Telecommunication = 156, TimeManager = 157, TimeMaster = 158, Tracefinder = 159, Transporter = 160, Veteran = 161, Vigilante = 162, Witness = 163, Agitater = 164, Amnesiac = 165, Arsonist = 166, Bandit = 167, BloodKnight = 168, Collector = 169, Cultist = 170, CursedSoul = 171, Demon = 172, Doomsayer = 173, Doppelganger = 174, Executioner = 175, Follower = 176, Glitch = 177, God = 178, Hater = 179, HexMaster = 180, Huntsman = 181, Imitator = 182, Infectious = 183, Innocent = 184, Jackal = 185, Jester = 186, Jinx = 187, Juggernaut = 188, Lawyer = 189, Maverick = 190, Medusa = 191, Necromancer = 192, Opportunist = 193, Pelican = 194, Pestilence = 195, Pickpocket = 196, Pirate = 197, Pixie = 198, PlagueBearer = 199, PlagueDoctor = 200, Poisoner = 201, PotionMaster = 202, Provocateur = 203, PunchingBag = 204, Pursuer = 205, Pyromaniac = 206, Quizmaster = 207, Revolutionist = 208, Romantic = 209, RuthlessRomantic = 210, SchrodingersCat = 211, Seeker = 212, SerialKiller = 213, Shaman = 214, Shroud = 215, Sidekick = 216, Solsticer = 217, SoulCollector = 218, Specter = 219, Spiritcaller = 220, Stalker = 221, Sunnyboy = 222, Taskinator = 223, Terrorist = 224, Traitor = 225, Vector = 226, VengefulRomantic = 227, Virus = 228, Vulture = 229, Werewolf = 230, Workaholic = 231, Wraith = 232, Mini = 233, Killer = 234, GM = 235, NotAssigned = 500, Admired = 501, Antidote = 502, Autopsy = 503, Avanger = 504, Aware = 505, Bait = 506, Bewilder = 507, Bloodthirst = 508, Burst = 509, Charmed = 510, Circumvent = 511, Cleansed = 512, Clumsy = 513, Contagious = 514, Cyber = 515, Diseased = 516, DoubleShot = 517, Egoist = 518, EvilSpirit = 519, Flash = 520, Fool = 521, Fragile = 522, Ghoul = 523, Glow = 524, Gravestone = 525, Guesser = 526, Hurried = 527, Infected = 528, Influenced = 529, Knighted = 530, LastImpostor = 531, Lazy = 532, Lovers = 533, Loyal = 534, Lucky = 535, Madmate = 536, Mare = 537, Mimic = 538, Mundane = 539, Necroview = 540, Nimble = 541, Oblivious = 542, Oiiai = 543, Onbound = 544, Overclocked = 545, Paranoia = 546, Radar = 547, Rainbow = 548, Rascal = 549, Reach = 550, Rebound = 551, Recruit = 552, Seer = 553, Silent = 554, Sleuth = 555, Soulless = 556, Statue = 557, Stubborn = 558, Susceptible = 559, Swift = 560, Tiebreaker = 561, TicketsStealer = 562, Torch = 563, Trapper = 564, Tricky = 565, Tired = 566, Unlucky = 567, Unreportable = 568, VoidBallot = 569, Watcher = 570, Workhorse = 571, Youtuber = 572 } public enum CustomWinner { Draw = -1, Default = -2, None = -3, Error = -4, Neutrals = -5, Impostor = 6, Crewmate = 0, Jester = 186, Terrorist = 224, Lovers = 533, Executioner = 175, Arsonist = 166, Pyromaniac = 206, Agitater = 164, Revolutionist = 208, Jackal = 185, Sidekick = 216, God = 178, Vector = 226, Innocent = 184, Pelican = 194, Youtuber = 572, Egoist = 518, Demon = 172, Stalker = 221, Workaholic = 231, Collector = 169, BloodKnight = 168, Poisoner = 201, HexMaster = 180, Quizmaster = 207, Cultist = 170, Wraith = 232, Bandit = 167, Pirate = 197, SerialKiller = 213, Werewolf = 230, Necromancer = 192, Huntsman = 181, Juggernaut = 188, Infectious = 183, Virus = 228, Specter = 219, Jinx = 187, CursedSoul = 171, PotionMaster = 202, Pickpocket = 196, Traitor = 225, Vulture = 229, Pestilence = 195, Medusa = 191, Spiritcaller = 220, Glitch = 177, Plaguebearer = 199, PlagueDoctor = 200, PunchingBag = 204, Doomsayer = 173, Shroud = 215, Seeker = 212, SoulCollector = 218, RuthlessRomantic = 210, NiceMini = 233, Doppelganger = 174, Solsticer = 217 } public enum AdditionalWinners { None = -1, Lovers = 533, Opportunist = 193, Executioner = 175, Lawyer = 189, Hater = 179, Provocateur = 203, Sunnyboy = 222, Follower = 176, Romantic = 209, VengefulRomantic = 227, RuthlessRomantic = 210, Jackal = 185, Sidekick = 216, Pursuer = 205, Specter = 219, Maverick = 190, Shaman = 214, Taskinator = 223, Pixie = 198, Quizmaster = 207, SchrodingersCat = 211 } public enum SuffixModes { None, TOHE, Streaming, Recording, RoomHost, OriginalName, DoNotKillMe, NoAndroidPlz, AutoHost } public enum VoteMode { Default, Suicide, SelfVote, Skip } public enum TieMode { Default, All, Random } public class Coroutines : MonoBehaviour { } public static class AntiBlackout { private static Dictionary isDeadCache = new Dictionary(); private static readonly LogHandler logger = Logger.Handler("AntiBlackout"); public static bool ShowExiledInfo = false; public static string StoreExiledMessage = ""; public static bool BlackOutIsActive { get { if (!Options.DisableAntiBlackoutProtects.GetBool()) { return CheckBlackOut(); } return false; } } public static bool IsCached { get; private set; } = false; public static bool CheckBlackOut() { HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); HashSet hashSet3 = new HashSet(); NetworkedPlayerInfo antiBlackout_LastExiled = ExileControllerWrapUpPatch.AntiBlackout_LastExiled; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!((Object)(object)antiBlackout_LastExiled != (Object)null) || val.PlayerId != antiBlackout_LastExiled.PlayerId) { if (val.Is(Custom_Team.Impostor)) { hashSet.Add(val.PlayerId); } else if (val.IsNeutralKiller()) { hashSet3.Add(val.PlayerId); } else { hashSet2.Add(val.PlayerId); } } } int count = hashSet.Count; int count2 = hashSet2.Count; int count3 = hashSet3.Count; Logger.Info($" {count}", "AntiBlackout Num Alive Impostors", escapeCRLF: true, 47, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\AntiBlackout.cs"); Logger.Info($" {count2}", "AntiBlackout Num Alive Crewmates", escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\AntiBlackout.cs"); Logger.Info($" {count3}", "AntiBlackout Num Alive Neutral Killers", escapeCRLF: true, 49, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\AntiBlackout.cs"); bool flag = false; if (!flag) { flag = count <= 0; } if (!flag) { flag = count3 + count2 <= count; } if (!flag) { flag = count3 == 1 && count == 1 && count2 <= 2; } Logger.Info($" {flag}", "BlackOut Is Active", escapeCRLF: true, 65, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\AntiBlackout.cs"); return flag; } public static void SetIsDead(bool doSend = true, [CallerMemberName] string callerMethodName = "") { logger.Info("SetIsDead is called from " + callerMethodName); if (IsCached) { logger.Info("Please run RestoreIsDead before running SetIsDead again."); return; } isDeadCache.Clear(); Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { NetworkedPlayerInfo current = enumerator.Current; if (!((Object)(object)current == (Object)null)) { isDeadCache[current.PlayerId] = (current.IsDead, current.Disconnected); current.IsDead = false; current.Disconnected = false; } } IsCached = true; if (doSend) { SendGameData("SetIsDead"); } } public static void RestoreIsDead(bool doSend = true, [CallerMemberName] string callerMethodName = "") { logger.Info("RestoreIsDead is called from " + callerMethodName); Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { NetworkedPlayerInfo current = enumerator.Current; if (!((Object)(object)current == (Object)null) && isDeadCache.TryGetValue(current.PlayerId, out (bool, bool) value)) { current.IsDead = value.Item1; current.Disconnected = value.Item2; } } isDeadCache.Clear(); IsCached = false; if (doSend) { SendGameData("RestoreIsDead"); } } public static void SendGameData([CallerMemberName] string callerMethodName = "") { logger.Info("SendGameData is called from " + callerMethodName); Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { NetworkedPlayerInfo current = enumerator.Current; MessageWriter val = MessageWriter.Get((SendOption)1); val.StartMessage((byte)5); val.Write(((InnerNetClient)AmongUsClient.Instance).GameId); val.StartMessage((byte)1); val.WritePacked(((InnerNetObject)current).NetId); ((InnerNetObject)current).Serialize(val, true); val.EndMessage(); val.EndMessage(); ((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(val); val.Recycle(); } } public static void OnDisconnect(NetworkedPlayerInfo player) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && IsCached && player.Disconnected) { isDeadCache[player.PlayerId] = (true, true); bool isDead = (player.Disconnected = false); player.IsDead = isDead; SendGameData("OnDisconnect"); } } public static void TempRestore(Action action) { logger.Info("==Temp Restore=="); bool isCached = IsCached; try { if (isCached) { RestoreIsDead(doSend: false, "TempRestore"); } action(); } catch (Exception ex) { logger.Warn("An exception occurred within AntiBlackout.TempRestore"); logger.Exception(ex); } finally { if (isCached) { SetIsDead(doSend: false, "TempRestore"); } logger.Info("==/Temp Restore=="); } } public static void AntiBlackRpcVotingComplete(this MeetingHud __instance, VoterState[] states, NetworkedPlayerInfo exiled, bool tie) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (((InnerNetClient)AmongUsClient.Instance).AmClient) { __instance.VotingComplete(Il2CppStructArray.op_Implicit(states), exiled, tie); } CustomRpcSender customRpcSender = CustomRpcSender.Create("AntiBlack RpcVotingComplete", (SendOption)0); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (((InnerNetObject)val).AmOwner) { continue; } if (val.IsModClient()) { customRpcSender.AutoStartRpc(((InnerNetObject)__instance).NetId, 23, val.GetClientId()); customRpcSender.WritePacked(states.Length); VoterState[] array = states; foreach (VoterState val2 in array) { customRpcSender.WriteMessageType(val2.VoterId); customRpcSender.Write(val2.VotedForId); customRpcSender.WriteEndMessage(); } customRpcSender.Write(((Object)(object)exiled != (Object)null) ? exiled.PlayerId : byte.MaxValue); customRpcSender.Write(tie); customRpcSender.EndRpc(); } else { customRpcSender.AutoStartRpc(((InnerNetObject)__instance).NetId, 23, val.GetClientId()); customRpcSender.WritePacked(states.Length); VoterState[] array = states; foreach (VoterState val3 in array) { customRpcSender.WriteMessageType(val3.VoterId); customRpcSender.Write(val3.VotedForId); customRpcSender.WriteEndMessage(); } customRpcSender.Write(byte.MaxValue); customRpcSender.Write(val: true); customRpcSender.EndRpc(); } } customRpcSender.SendMessage(); } public static void AfterMeetingTasks() { float num = 0f; if (CheckForEndVotingPatch.TempExileMsg != null && BlackOutIsActive) { num = 4f; PlayerControl[] array = Main.AllPlayerControls.Where((PlayerControl p) => (Object)(object)p != (Object)null && !((InnerNetObject)p).AmOwner && !p.IsModClient()).ToArray(); for (int i = 0; i < array.Length; i++) { array[i].Notify(CheckForEndVotingPatch.TempExileMsg, num); } } try { new LateTask(delegate { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; for (int j = 0; j < allAlivePlayerControls.Length; j++) { allAlivePlayerControls[j].GetRoleClass()?.NotifyAfterMeeting(); } }, num + 0.2f, "Notify AfterMeetingTasks"); } catch (Exception value) { Logger.Error($"{value}", "AntiBlackout.AfterMeetingTasks", escapeCRLF: true, 236, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\AntiBlackout.cs"); } } public static void Reset() { logger.Info("==Reset=="); if (isDeadCache == null) { isDeadCache = new Dictionary(); } isDeadCache.Clear(); IsCached = false; ShowExiledInfo = false; StoreExiledMessage = ""; } } public static class AURoleOptions { private static IGameOptions Opt; public static float KillCooldown { get { return Opt.GetFloat((FloatOptionNames)1); } set { Opt.SetFloat((FloatOptionNames)1, value); } } public static float PlayerSpeedMod { get { return Opt.GetFloat((FloatOptionNames)2); } set { Opt.SetFloat((FloatOptionNames)2, value); } } public static float ScientistCooldown { get { return Opt.GetFloat((FloatOptionNames)1200); } set { Opt.SetFloat((FloatOptionNames)1200, value); } } public static float ScientistBatteryCharge { get { return Opt.GetFloat((FloatOptionNames)1201); } set { Opt.SetFloat((FloatOptionNames)1201, value); } } public static float EngineerCooldown { get { return Opt.GetFloat((FloatOptionNames)1300); } set { Opt.SetFloat((FloatOptionNames)1300, value); } } public static float EngineerInVentMaxTime { get { return Opt.GetFloat((FloatOptionNames)1301); } set { Opt.SetFloat((FloatOptionNames)1301, value); } } public static float GuardianAngelCooldown { get { return Opt.GetFloat((FloatOptionNames)1101); } set { Opt.SetFloat((FloatOptionNames)1101, value); } } public static float ProtectionDurationSeconds { get { return Opt.GetFloat((FloatOptionNames)1100); } set { Opt.SetFloat((FloatOptionNames)1100, value); } } public static bool ImpostorsCanSeeProtect { get { return Opt.GetBool((BoolOptionNames)1100); } set { Opt.SetBool((BoolOptionNames)1100, value); } } public static float ShapeshifterDuration { get { return Opt.GetFloat((FloatOptionNames)1001); } set { Opt.SetFloat((FloatOptionNames)1001, value); } } public static float ShapeshifterCooldown { get { return Opt.GetFloat((FloatOptionNames)1000); } set { Opt.SetFloat((FloatOptionNames)1000, value); } } public static bool ShapeshifterLeaveSkin { get { return Opt.GetBool((BoolOptionNames)1000); } set { Opt.SetBool((BoolOptionNames)1000, value); } } public static bool NoisemakerImpostorAlert { get { return Opt.GetBool((BoolOptionNames)1300); } set { Opt.SetBool((BoolOptionNames)1300, value); } } public static float NoisemakerAlertDuration { get { return Opt.GetFloat((FloatOptionNames)1600); } set { Opt.SetFloat((FloatOptionNames)1600, value); } } public static float PhantomCooldown { get { return Opt.GetFloat((FloatOptionNames)1500); } set { Opt.SetFloat((FloatOptionNames)1500, value); } } public static float PhantomDuration { get { return Opt.GetFloat((FloatOptionNames)1501); } set { Opt.SetFloat((FloatOptionNames)1501, value); } } public static float TrackerCooldown { get { return Opt.GetFloat((FloatOptionNames)1550); } set { Opt.SetFloat((FloatOptionNames)1550, value); } } public static float TrackerDuration { get { return Opt.GetFloat((FloatOptionNames)1551); } set { Opt.SetFloat((FloatOptionNames)1551, value); } } public static float TrackerDelay { get { return Opt.GetFloat((FloatOptionNames)1552); } set { Opt.SetFloat((FloatOptionNames)1552, value); } } public static void SetOpt(IGameOptions opt) { Opt = opt; } } public static class BanManager { private static readonly string DENY_NAME_LIST_PATH = "./TOHE-DATA/DenyName.txt"; private static readonly string BAN_LIST_PATH = "./TOHE-DATA/BanList.txt"; private static readonly string MODERATOR_LIST_PATH = "./TOHE-DATA/Moderators.txt"; private static readonly string VIP_LIST_PATH = "./TOHE-DATA/VIP-List.txt"; private static readonly string WHITE_LIST_LIST_PATH = "./TOHE-DATA/WhiteList.txt"; public static List TempBanWhiteList = new List(); public static List> EACDict = new List>(); public static void Init() { try { Directory.CreateDirectory("TOHE-DATA"); if (!File.Exists(BAN_LIST_PATH)) { Logger.Warn("Create a new BanList.txt file", "BanManager", escapeCRLF: true, 30, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); File.Create(BAN_LIST_PATH).Close(); } if (!File.Exists(DENY_NAME_LIST_PATH)) { Logger.Warn("Create a new DenyName.txt file", "BanManager", escapeCRLF: true, 35, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); File.Create(DENY_NAME_LIST_PATH).Close(); File.WriteAllText(DENY_NAME_LIST_PATH, GetResourcesTxt("TOHE.Resources.Config.DenyName.txt")); } if (!File.Exists(MODERATOR_LIST_PATH)) { Logger.Warn("Creating a new Moderators.txt file", "BanManager", escapeCRLF: true, 41, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); File.Create(MODERATOR_LIST_PATH).Close(); } if (!File.Exists(VIP_LIST_PATH)) { Logger.Warn("Creating a new VIP-List.txt file", "BanManager", escapeCRLF: true, 46, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); File.Create(VIP_LIST_PATH).Close(); } if (!File.Exists(WHITE_LIST_LIST_PATH)) { Logger.Warn("Creating a new WhiteList.txt file", "BanManager", escapeCRLF: true, 51, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); File.Create(WHITE_LIST_LIST_PATH).Close(); } } catch (Exception ex) { Logger.Exception(ex, "BanManager", 69, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } } private static string GetResourcesTxt(string path) { Stream? manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); manifestResourceStream.Position = 0L; using StreamReader streamReader = new StreamReader(manifestResourceStream, Encoding.UTF8); return streamReader.ReadToEnd(); } public static string GetHashedPuid(this ClientData player) { if (player == null) { return ""; } string productUserId = player.ProductUserId; using SHA256 sHA = SHA256.Create(); string text = BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(productUserId))).Replace("-", "").ToLower(); return string.Concat(text.AsSpan(0, 5), text.AsSpan(text.Length - 4)); } public static void AddBanPlayer(ClientData player) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || player == null || CheckBanList((player != null) ? player.FriendCode : null, player?.GetHashedPuid()) || TempBanWhiteList.Contains(player?.GetHashedPuid())) { return; } if (player?.GetHashedPuid() != "" && player != null && player.GetHashedPuid() != null && player?.GetHashedPuid() != "e3b0cb855") { string value = ""; if (CheckEACList((player != null) ? player.FriendCode : null, player?.GetHashedPuid())) { value = " //added by EAC"; } File.AppendAllText(BAN_LIST_PATH, $"{((player != null) ? player.FriendCode : null)},{player?.GetHashedPuid()},{player.PlayerName.RemoveHtmlTags()}{value}\n"); Logger.SendInGame(string.Format(Translator.GetString("Message.AddedPlayerToBanList"), player.PlayerName)); } else { Logger.Info($"Failed to add player {((player != null) ? player.PlayerName.RemoveHtmlTags() : null)}/{((player != null) ? player.FriendCode : null)}/{player?.GetHashedPuid()} to ban list!", "AddBanPlayer", escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } } public static bool CheckDenyNamePlayer(PlayerControl player, string name) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !Options.ApplyDenyNameList.GetBool()) { return false; } try { Directory.CreateDirectory("TOHE-DATA"); if (!File.Exists(DENY_NAME_LIST_PATH)) { File.Create(DENY_NAME_LIST_PATH).Close(); } using StreamReader streamReader = new StreamReader(DENY_NAME_LIST_PATH); string text; while ((text = streamReader.ReadLine()) != null) { if (!(text == "")) { if (text.Contains("Amogus")) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(((InnerNetObject)player).OwnerId, false); Logger.SendInGame(string.Format(Translator.GetString("Message.KickedByDenyName"), name, text)); Logger.Info(name + "は名前が「" + text + "」に一致したためキックされました。", "Kick", escapeCRLF: true, 125, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); return true; } if (text.Contains("Amogus V")) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(((InnerNetObject)player).OwnerId, false); Logger.SendInGame(string.Format(Translator.GetString("Message.KickedByDenyName"), name, text)); Logger.Info(name + "は名前が「" + text + "」に一致したためキックされました。", "Kick", escapeCRLF: true, 132, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); return true; } if (Regex.IsMatch(name, text)) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(((InnerNetObject)player).OwnerId, false); Logger.SendInGame(string.Format(Translator.GetString("Message.KickedByDenyName"), name, text)); Logger.Info(name + "は名前が「" + text + "」に一致したためキックされました。", "Kick", escapeCRLF: true, 140, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); return true; } } } return false; } catch (Exception ex) { Logger.Exception(ex, "CheckDenyNamePlayer", 148, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); return true; } } public static void CheckBanPlayer(ClientData player) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && Options.ApplyBanList.GetBool()) { string code = ((player != null) ? player.FriendCode : null); if (CheckBanList(code, player?.GetHashedPuid())) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.Id, true); Logger.SendInGame(string.Format(Translator.GetString("Message.BannedByBanList"), player.PlayerName)); Logger.Info(player.PlayerName + "は過去にBAN済みのためBANされました。", "BAN", escapeCRLF: true, 162, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } else if (CheckEACList(code, player?.GetHashedPuid())) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.Id, true); Logger.SendInGame(string.Format(Translator.GetString("Message.BannedByEACList"), player.PlayerName)); Logger.Info(player.PlayerName + "存在于EAC封禁名单", "BAN", escapeCRLF: true, 169, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } else if (TempBanWhiteList.Contains(player?.GetHashedPuid())) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.Id, true); Logger.Info(player.PlayerName + " was in temp ban list", "BAN", escapeCRLF: true, 176, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } } } public static bool CheckBanList(string code, string hashedpuid = "") { bool flag = false; if (code == "" && hashedpuid != "") { flag = true; } else if (code == "") { return false; } string value = ""; if (code.Contains('#')) { value = code[..code.IndexOf('#')]; } try { Directory.CreateDirectory("TOHE-DATA"); if (!File.Exists(BAN_LIST_PATH)) { File.Create(BAN_LIST_PATH).Close(); } using StreamReader streamReader = new StreamReader(BAN_LIST_PATH); string text; while ((text = streamReader.ReadLine()) != null) { if (text == "") { continue; } if (!flag) { if (text.Contains(code)) { return true; } if (!string.IsNullOrEmpty(value) && !text.Contains('#') && text.Contains(value)) { return true; } } if (text.Contains(hashedpuid)) { return true; } } } catch (Exception ex) { Logger.Exception(ex, "CheckBanList", 212, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); } return false; } public static bool CheckEACList(string code, string hashedPuid) { string text = code.Split("#")[0].ToLower().Trim(); if (string.IsNullOrEmpty(text) && string.IsNullOrEmpty(hashedPuid)) { return false; } foreach (Dictionary item in EACDict) { string text2 = item["friendcode"].ToString().Split('#')[0].ToLower().Trim(); if ((!string.IsNullOrEmpty(text) && text == text2) || item["hashPUID"].ToString().ToLower().Trim() == hashedPuid.ToLower().Trim()) { Logger.Warn($"friendcode : {code}, hashedPUID : {hashedPuid} banned by EAC reason : {item["reason"]}", "CheckEACList", escapeCRLF: true, 228, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\BanManager.cs"); return true; } } return false; } public static bool CheckAllowList(string friendcode) { if (friendcode == "") { return false; } string path = "./TOHE-DATA/WhiteList.txt"; if (!File.Exists(path)) { File.Create(path).Close(); } return File.ReadAllLines(path).Any((string x) => x == friendcode || x.Contains(friendcode)); } } [HarmonyPatch(typeof(BanMenu), "Select")] internal class BanMenuSelectPatch { public static void Postfix(BanMenu __instance, int clientId) { ClientData recentClient = ((InnerNetClient)AmongUsClient.Instance).GetRecentClient(clientId); if (recentClient != null && !BanManager.CheckBanList((recentClient != null) ? recentClient.FriendCode : null, recentClient?.GetHashedPuid())) { ((Component)__instance.BanButton).GetComponent().SetEnabledColors(); } } } internal static class PlayerOutfitExtension { public static PlayerOutfit Set(this PlayerOutfit instance, string playerName, int colorId, string hatId, string skinId, string visorId, string petId, string nameplateId) { instance.PlayerName = playerName; instance.ColorId = colorId; instance.HatId = hatId; instance.SkinId = skinId; instance.VisorId = visorId; instance.PetId = petId; instance.NamePlateId = nameplateId; return instance; } public static bool Compare(this PlayerOutfit instance, PlayerOutfit targetOutfit) { if (instance.ColorId == targetOutfit.ColorId && instance.HatId == targetOutfit.HatId && instance.SkinId == targetOutfit.SkinId && instance.VisorId == targetOutfit.VisorId) { return instance.PetId == targetOutfit.PetId; } return false; } public static string GetString(this PlayerOutfit instance) { return $"{instance.PlayerName} Color:{instance.ColorId} {instance.HatId} {instance.SkinId} {instance.VisorId} {instance.PetId}"; } public static PlayerOutfit GetRandomOutfit() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown IRandom instance = IRandom.Instance; int num = instance.Next(0, 101); return (PlayerOutfit)(Options.KPDCamouflageMode.GetValue() switch { 2 => (object)new PlayerOutfit { ColorId = instance.Next(((Il2CppArrayBase)(object)Palette.PlayerColors).Length), HatId = ((CosmeticData)((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allHats)[(num >= instance.Next(0, 101)) ? instance.Next(0, ((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allHats).Length) : 0]).ProdId, SkinId = ((CosmeticData)((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allSkins)[(num >= instance.Next(0, 101)) ? instance.Next(0, ((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allSkins).Length) : 0]).ProdId, VisorId = ((CosmeticData)((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allVisors)[(num >= instance.Next(0, 101)) ? instance.Next(0, ((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allVisors).Length) : 0]).ProdId, PetId = ((CosmeticData)((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allPets)[(num >= instance.Next(0, 101)) ? instance.Next(0, ((Il2CppArrayBase)(object)DestroyableSingleton.Instance.allPets).Length) : 0]).ProdId }, 3 => Set(new PlayerOutfit(), "", instance.Next(((Il2CppArrayBase)(object)Palette.PlayerColors).Length), "", "", "", "", ""), _ => Set(new PlayerOutfit(), "", 15, "", "", "", "", ""), }); } } public static class Camouflage { public static bool IsCamouflage; private static PlayerOutfit CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 15, "", "", "", "", ""); public static List ResetSkinAfterDeathPlayers = new List(); public static Dictionary PlayerSkins = new Dictionary(); public static bool IsActive; public static void Init() { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Expected O, but got Unknown IsCamouflage = false; PlayerSkins.Clear(); ResetSkinAfterDeathPlayers = new List(); IsActive = Options.CommsCamouflage.GetBool() && (!Options.DisableOnSomeMaps.GetBool() || ((!Options.DisableOnSkeld.GetBool() || !GameStates.SkeldIsActive) && (!Options.DisableOnMira.GetBool() || !GameStates.MiraHQIsActive) && (!Options.DisableOnPolus.GetBool() || !GameStates.PolusIsActive) && (!Options.DisableOnDleks.GetBool() || !GameStates.DleksIsActive) && (!Options.DisableOnAirship.GetBool() || !GameStates.AirshipIsActive) && (!Options.DisableOnFungle.GetBool() || !GameStates.FungleIsActive))); switch (Options.KPDCamouflageMode.GetValue()) { case 0: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 15, "", "", "", "", ""); break; case 1: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", DataManager.Player.Customization.Color, DataManager.Player.Customization.Hat, DataManager.Player.Customization.Skin, DataManager.Player.Customization.Visor, DataManager.Player.Customization.Pet, ""); break; case 2: case 3: CamouflageOutfit = PlayerOutfitExtension.GetRandomOutfit(); break; case 4: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 13, "hat_pk05_Plant", "", "visor_BubbleBumVisor", "", ""); break; case 5: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 13, "hat_rabbitEars", "skin_Bananaskin", "visor_BubbleBumVisor", "pet_Pusheen", ""); break; case 6: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 0, "hat_mira_headset_yellow", "skin_SuitB", "visor_lollipopCrew", "pet_EmptyPet", ""); break; case 7: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 17, "hat_pkHW01_Witch", "skin_greedygrampaskin", "visor_Plsno", "pet_Pusheen", ""); break; case 8: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 7, "hat_theohair", "skin_Theoskin", "visor_Carrot", "pet_Snow", ""); break; case 9: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 7, "hat_pk04_Snowman", "", "", "", ""); break; case 10: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 17, "hat_baseball_Black", "skin_Scientist-Darkskin", "visor_pusheenSmileVisor", "pet_Pip", ""); break; case 11: CamouflageOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 17, "hat_mira_flower", "skin_PusheenPurpleskin", "visor_hl_hmph", "pet_Charles", ""); break; } } public static void CheckCamouflage() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (!Options.CommsCamouflage.GetBool() && !Camouflager.HasEnabled)) { return; } bool isCamouflage = IsCamouflage; IsCamouflage = (Utils.IsActive((SystemTypes)14) && IsActive) || Camouflager.AbilityActivated; if (isCamouflage == IsCamouflage) { return; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { RpcSetSkin(val); if (!IsCamouflage && !val.IsAlive()) { val.RpcRemovePet(); } } Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); } public static void RpcSetSkin(PlayerControl target, bool ForceRevert = false, bool RevertToDefault = false, bool GameEnd = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (!Options.CommsCamouflage.GetBool() && !Camouflager.HasEnabled) || (Object)(object)target == (Object)null) { return; } byte b = target.PlayerId; if (IsCamouflage && Main.PlayerStates[b].IsDead) { return; } int value = Options.KPDCamouflageMode.GetValue(); bool flag = (uint)(value - 2) <= 1u; PlayerOutfit val = (flag ? PlayerOutfitExtension.GetRandomOutfit() : CamouflageOutfit); if (!IsCamouflage || ForceRevert) { if (Main.CheckShapeshift.TryGetValue(b, out var value2) && value2 && !RevertToDefault) { b = Main.ShapeshiftTarget[b]; } if (!GameEnd && Doppelganger.HasEnabled && Doppelganger.DoppelPresentSkin.TryGetValue(b, out var value3)) { val = value3; } else { if (GameEnd && Doppelganger.DoppelVictim.TryGetValue(b, out var value4)) { PlayerControl playerById = Utils.GetPlayerById(b); if (playerById != null) { playerById.RpcSetName(value4); } } val = PlayerSkins[b]; } } if (!val.Compare(target.Data.DefaultOutfit)) { Logger.Info($"playerId {target.PlayerId} newOutfit={val.GetString().RemoveHtmlTags()}", "RpcSetSkin", escapeCRLF: true, 212, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Camouflague.cs"); target.SetNewOutfit(val, setName: false, setNamePlate: false); } } } public class ClientOptionItem { public ConfigEntry Config; public ToggleButtonBehaviour ToggleButton; public static SpriteRenderer CustomBackground; private static int numOptions; private ClientOptionItem(string name, ConfigEntry config, OptionsMenuBehaviour optionsMenuBehaviour, Action additionalOnClickAction = null) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) ClientOptionItem clientOptionItem = this; try { Config = config; ToggleButtonBehaviour disableMouseMovement = optionsMenuBehaviour.DisableMouseMovement; if ((Object)(object)CustomBackground == (Object)null) { numOptions = 0; CustomBackground = Object.Instantiate(optionsMenuBehaviour.Background, ((Component)optionsMenuBehaviour).transform); ((Object)CustomBackground).name = "CustomBackground"; ((Component)CustomBackground).transform.localScale = new Vector3(0.9f, 0.9f, 1f); Transform transform = ((Component)CustomBackground).transform; transform.localPosition += Vector3.back * 8f; ((Component)CustomBackground).gameObject.SetActive(false); ToggleButtonBehaviour obj = Object.Instantiate(disableMouseMovement, ((Component)CustomBackground).transform); ((Component)obj).transform.localPosition = new Vector3(1.3f, -2.3f, -6f); ((Object)obj).name = "Back"; ((TMP_Text)obj.Text).text = Translator.GetString("Back"); obj.Background.color = Palette.DisabledGrey; PassiveButton component = ((Component)obj).GetComponent(); component.OnClick = new ButtonClickedEvent(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { ((Component)CustomBackground).gameObject.SetActive(false); })); UiElement[] array = Il2CppArrayBase.op_Implicit(optionsMenuBehaviour.ControllerSelectable.ToArray()); PassiveButton val = null; PassiveButton val2 = null; UiElement[] array2 = array; foreach (UiElement val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { if (((Object)val3).name == "LeaveGameButton") { val = ((Component)val3).GetComponent(); } else if (((Object)val3).name == "ReturnToGameButton") { val2 = ((Component)val3).GetComponent(); } } } Transform parent = ((Component)disableMouseMovement).transform.parent.parent.parent; ToggleButtonBehaviour obj2 = Object.Instantiate(disableMouseMovement, parent); Transform transform2 = ((Component)obj2).transform; Vector3? obj3; if (val == null) { obj3 = null; } else { Transform transform3 = ((Component)val).transform; obj3 = ((transform3 != null) ? new Vector3?(transform3.localPosition) : null); } transform2.localPosition = (Vector3)(((??)obj3) ?? new Vector3(0f, -2.4f, 1f)); ((Object)obj2).name = "TOHEOptions"; ((TMP_Text)obj2.Text).text = Translator.GetString("TOHEOptions"); obj2.Background.color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)192, (byte)203, byte.MaxValue)); PassiveButton component2 = ((Component)obj2).GetComponent(); component2.OnClick = new ButtonClickedEvent(); ((UnityEvent)component2.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { ((Component)CustomBackground).gameObject.SetActive(true); })); if ((Object)(object)val != (Object)null) { ((Component)val).transform.localPosition = new Vector3(-1.35f, -2.411f, -1f); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).transform.localPosition = new Vector3(1.35f, -2.411f, -1f); } } ToggleButton = Object.Instantiate(disableMouseMovement, ((Component)CustomBackground).transform); ((Component)ToggleButton).transform.localPosition = new Vector3((numOptions % 2 == 0) ? (-1.3f) : 1.3f, 2.2f - 0.5f * (float)(numOptions / 2), -6f); ((Object)ToggleButton).name = name; ((TMP_Text)ToggleButton.Text).text = Translator.GetString(name); PassiveButton component3 = ((Component)ToggleButton).GetComponent(); component3.OnClick = new ButtonClickedEvent(); ((UnityEvent)component3.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { if (config != null) { config.Value = !config.Value; } clientOptionItem.UpdateToggle(); additionalOnClickAction?.Invoke(); })); UpdateToggle(); } finally { numOptions++; } } public static ClientOptionItem Create(string name, ConfigEntry config, OptionsMenuBehaviour optionsMenuBehaviour, Action additionalOnClickAction = null) { return new ClientOptionItem(name, config, optionsMenuBehaviour, additionalOnClickAction); } public void UpdateToggle() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ToggleButton == (Object)null)) { Color32 val = ((Config != null && Config.Value) ? new Color32(byte.MaxValue, (byte)192, (byte)203, byte.MaxValue) : new Color32((byte)77, (byte)77, (byte)77, byte.MaxValue)); ToggleButton.Background.color = Color32.op_Implicit(val); ButtonRolloverHandler rollover = ToggleButton.Rollover; if (rollover != null) { rollover.ChangeOutColor(Color32.op_Implicit(val)); } } } } internal class Cloud { [HarmonyPatch(typeof(PlayerControl), "FixedUpdate")] private class EACConnectTimeOut { public static void Postfix() { if (LastRepotTimeStamp != 0L && LastRepotTimeStamp + 8 < Utils.GetTimeStamp()) { LastRepotTimeStamp = 0L; StopConnect(); Logger.Warn("超时自动断开与TOHE服务器的连接", "EAC Cloud", escapeCRLF: true, 126, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Cloud.cs"); } } } private static string IP; private static int EAC_PORT; private static Socket EacClientSocket; private static long LastRepotTimeStamp; private static bool connecting; public static void Init() { try { string[] array = GetResourcesTxt("TOHE.Resources.Config.Port.txt").Split('|'); IP = array[0]; EAC_PORT = int.Parse(array[2]); } catch (Exception ex) { Logger.Exception(ex, "Cloud Init", 29, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Cloud.cs"); } } private static string GetResourcesTxt(string path) { Stream? manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); manifestResourceStream.Position = 0L; using StreamReader streamReader = new StreamReader(manifestResourceStream, Encoding.UTF8); return streamReader.ReadToEnd(); } public static void StartConnect() { if (connecting || (EacClientSocket != null && EacClientSocket.Connected)) { return; } connecting = true; new LateTask(delegate { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !Object.op_Implicit((Object)(object)GameData.Instance) || (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 0) { connecting = false; } else { try { if (IP == null || EAC_PORT == 0) { throw new Exception("Has no ip or port"); } LastRepotTimeStamp = Utils.GetTimeStamp(); EacClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); EacClientSocket.Connect(IP, EAC_PORT); Logger.Warn("已连接至TOHE服务器", "EAC Cloud", escapeCRLF: true, 91, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Cloud.cs"); } catch (Exception ex) { connecting = false; Logger.Exception(ex, "EAC Cloud", 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Cloud.cs"); throw; } connecting = false; } }, 3.5f, "EAC Cloud Connect"); } public static void StopConnect() { if (EacClientSocket != null && EacClientSocket.Connected) { EacClientSocket.Close(); } } public static void SendData(string msg) { StartConnect(); if (EacClientSocket == null || !EacClientSocket.Connected) { Logger.Warn("未连接至TOHE服务器,报告被取消", "EAC Cloud", escapeCRLF: true, 112, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Cloud.cs"); } else { EacClientSocket.Send(Encoding.Default.GetBytes(msg)); } } } public static class CustomRolesHelper { public static readonly CustomRoles[] AllRoles = EnumHelper.GetAllValues(); public static Dictionary DuplicatedRoles; public static readonly Custom_Team[] AllRoleTypes = EnumHelper.GetAllValues(); public static CustomRoles GetVNRole(this CustomRoles role) { if (role.IsVanilla()) { return role; } if (!(role.GetStaticRoleClass() is DefaultSetup)) { return role.GetStaticRoleClass().ThisRoleBase; } return role switch { CustomRoles.ShapeshifterTOHE => CustomRoles.Shapeshifter, CustomRoles.PhantomTOHE => CustomRoles.Phantom, CustomRoles.ScientistTOHE => CustomRoles.Scientist, CustomRoles.EngineerTOHE => CustomRoles.Engineer, CustomRoles.NoisemakerTOHE => CustomRoles.Noisemaker, CustomRoles.TrackerTOHE => CustomRoles.Tracker, _ => role.IsImpostor() ? CustomRoles.Impostor : CustomRoles.Crewmate, }; } public static RoleTypes GetDYRole(this CustomRoles role) { if ((role.GetStaticRoleClass().ThisRoleBase != CustomRoles.Impostor || role.IsImpostor()) && role != CustomRoles.Killer) { return (RoleTypes)4; } return (RoleTypes)1; } public static bool HasImpKillButton(this PlayerControl player, bool considerVanillaShift = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Invalid comparison between Unknown and I4 if ((Object)(object)player == (Object)null) { return false; } CustomRoles customRole = player.GetCustomRole(); bool flag = (int)customRole.GetDYRole() == 1; if (!flag) { CustomRoles vNRole = customRole.GetVNRole(); bool flag2 = (uint)(vNRole - 6) <= 2u; flag = flag2; } bool result = flag; if (player.IsModClient() || (!considerVanillaShift && !player.IsModClient())) { return result; } if (EAC.OriginalRoles.TryGetValue(player.PlayerId, out var value)) { bool flag2 = (int)value.GetDYRole() == 1; if (!flag2) { CustomRoles vNRole = value.GetVNRole(); bool flag3 = (uint)(vNRole - 6) <= 2u; flag2 = flag3; } return flag2; } return result; } public static bool IsGhostRole(this CustomRoles role) { Custom_RoleType thisRoleType = role.GetStaticRoleClass().ThisRoleType; if ((thisRoleType == Custom_RoleType.ImpostorGhosts || thisRoleType == Custom_RoleType.CrewmateVanillaGhosts || thisRoleType == Custom_RoleType.CrewmateGhosts) ? true : false) { return true; } return role == CustomRoles.EvilSpirit; } public static bool IsAdditionRole(this CustomRoles role) { return role > CustomRoles.NotAssigned; } public static bool IsAmneMaverick(this CustomRoles role) { switch (role) { case CustomRoles.Crewpostor: case CustomRoles.Agitater: case CustomRoles.Amnesiac: case CustomRoles.Arsonist: case CustomRoles.Bandit: case CustomRoles.Collector: case CustomRoles.CursedSoul: case CustomRoles.Demon: case CustomRoles.Doomsayer: case CustomRoles.Doppelganger: case CustomRoles.Executioner: case CustomRoles.Follower: case CustomRoles.Glitch: case CustomRoles.God: case CustomRoles.Hater: case CustomRoles.Huntsman: case CustomRoles.Imitator: case CustomRoles.Innocent: case CustomRoles.Jester: case CustomRoles.Lawyer: case CustomRoles.Maverick: case CustomRoles.Opportunist: case CustomRoles.Pestilence: case CustomRoles.Pirate: case CustomRoles.Pixie: case CustomRoles.PlagueBearer: case CustomRoles.Provocateur: case CustomRoles.PunchingBag: case CustomRoles.Pursuer: case CustomRoles.Revolutionist: case CustomRoles.Romantic: case CustomRoles.RuthlessRomantic: case CustomRoles.SchrodingersCat: case CustomRoles.Seeker: case CustomRoles.Shaman: case CustomRoles.Solsticer: case CustomRoles.SoulCollector: case CustomRoles.Specter: case CustomRoles.Stalker: case CustomRoles.Sunnyboy: case CustomRoles.Taskinator: case CustomRoles.Terrorist: case CustomRoles.Vector: case CustomRoles.VengefulRomantic: case CustomRoles.Vulture: case CustomRoles.Workaholic: return true; default: return false; } } public static bool IsAmneCrew(this PlayerControl target) { bool flag = target.IsCrewVenter(); if (!flag) { bool flag2; switch (target.GetCustomRole()) { case CustomRoles.Admirer: case CustomRoles.Bodyguard: case CustomRoles.Celebrity: case CustomRoles.Cleanser: case CustomRoles.CopyCat: case CustomRoles.Crusader: case CustomRoles.Deceiver: case CustomRoles.Dictator: case CustomRoles.Jailer: case CustomRoles.Judge: case CustomRoles.LazyGuy: case CustomRoles.Lookout: case CustomRoles.Mayor: case CustomRoles.Mechanic: case CustomRoles.Medic: case CustomRoles.Medium: case CustomRoles.Monarch: case CustomRoles.NiceGuesser: case CustomRoles.Observer: case CustomRoles.Overseer: case CustomRoles.Retributionist: case CustomRoles.Sheriff: case CustomRoles.SuperStar: case CustomRoles.Swapper: case CustomRoles.Telecommunication: flag2 = true; break; default: flag2 = false; break; } flag = flag2; } return flag; } public static bool IsAmneNK(this CustomRoles role) { switch (role) { case CustomRoles.Parasite: case CustomRoles.Refugee: case CustomRoles.BloodKnight: case CustomRoles.Cultist: case CustomRoles.Infectious: case CustomRoles.Jackal: case CustomRoles.Juggernaut: case CustomRoles.Medusa: case CustomRoles.Necromancer: case CustomRoles.Pelican: case CustomRoles.Pickpocket: case CustomRoles.PlagueDoctor: case CustomRoles.Pyromaniac: case CustomRoles.SerialKiller: case CustomRoles.Shroud: case CustomRoles.Sidekick: case CustomRoles.Spiritcaller: case CustomRoles.Traitor: case CustomRoles.Virus: case CustomRoles.Werewolf: case CustomRoles.Wraith: return true; default: return false; } } public static bool IsTasklessCrewmate(this CustomRoles role) { if (role.GetVNRole() == CustomRoles.Impostor) { return role.IsCrewmate(); } return false; } public static bool IsTaskBasedCrewmate(this CustomRoles role) { switch (role) { case CustomRoles.Alchemist: case CustomRoles.Benefactor: case CustomRoles.Captain: case CustomRoles.FortuneTeller: case CustomRoles.Guardian: case CustomRoles.Marshall: case CustomRoles.Mayor: case CustomRoles.Merchant: case CustomRoles.Retributionist: case CustomRoles.Snitch: case CustomRoles.TimeManager: case CustomRoles.Transporter: return true; default: return false; } } public static bool IsCrewKiller(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.CrewmateKilling; } public static bool IsCrewVenter(this PlayerControl target) { if (!target.Is(CustomRoles.EngineerTOHE) && !target.Is(CustomRoles.Mechanic) && !target.Is(CustomRoles.CopyCat) && (!target.Is(CustomRoles.Telecommunication) || !Telecommunication.CanUseVent()) && !Knight.CheckCanUseVent(target)) { return target.Is(CustomRoles.Nimble); } return true; } public static bool IsNeutral(this CustomRoles role) { if (role == CustomRoles.Killer) { return true; } if (!role.IsNK() && !role.IsNonNK()) { return role.IsMadmate(); } return true; } public static bool IsNK(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.NeutralKilling; } public static bool IsNonNK(this CustomRoles role) { if (!role.IsNB() && !role.IsNE()) { return role.IsNC(); } return true; } public static bool IsNB(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.NeutralBenign; } public static bool IsNE(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.NeutralEvil; } public static bool IsNC(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.NeutralChaos; } public static bool IsImpostor(this CustomRoles role) { Custom_RoleType thisRoleType = role.GetStaticRoleClass().ThisRoleType; if ((uint)thisRoleType <= 5u) { return true; } if ((uint)(role - 6) <= 2u) { return true; } return false; } public static bool IsAbleToBeSidekicked(this CustomRoles role) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)role.GetDYRole() == 1 && !role.IsImpostor()) { return !role.IsRecruitingRole(); } return false; } public static bool IsRecruitingRole(this CustomRoles role) { switch (role) { case CustomRoles.Cultist: case CustomRoles.Jackal: case CustomRoles.Necromancer: case CustomRoles.Spiritcaller: case CustomRoles.Virus: return true; default: return false; } } public static bool IsMadmate(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType == Custom_RoleType.Madmate; } public static bool IsConverted(this CustomRoles role) { bool flag = role == CustomRoles.Egoist && Egoist.EgoistCountAsConverted.GetBool(); if (!flag) { bool flag2; switch (role) { case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Recruit: case CustomRoles.Soulless: flag2 = true; break; default: flag2 = false; break; } flag = flag2; } return flag; } public static bool IsNotKnightable(this CustomRoles role) { switch (role) { case CustomRoles.Vindicator: case CustomRoles.Dictator: case CustomRoles.Mayor: case CustomRoles.Glitch: case CustomRoles.Pickpocket: case CustomRoles.Knighted: case CustomRoles.Stubborn: case CustomRoles.TicketsStealer: return true; default: return false; } } public static bool IsSpeedRole(this CustomRoles role) { if (role == CustomRoles.Alchemist || role == CustomRoles.Flash || role == CustomRoles.Tired) { return true; } return false; } public static bool IsRevealingRole(this CustomRoles role, PlayerControl target) { if ((role != CustomRoles.Mayor || !Mayor.VisibleToEveryone(target)) && (role != CustomRoles.SuperStar || !SuperStar.VisibleToEveryone(target)) && (role != CustomRoles.Marshall || !target.AllTasksCompleted()) && (role != CustomRoles.Workaholic || !Workaholic.WorkaholicVisibleToEveryone.GetBool()) && (role != CustomRoles.Doctor || !Doctor.VisibleToEveryone(target)) && (role != CustomRoles.Bait || !Bait.BaitNotification.GetBool() || !Inspector.CheckBaitCountType) && (role != CustomRoles.President || !President.CheckReveal(target.PlayerId))) { if (role == CustomRoles.Captain) { return Captain.CrewCanFindCaptain(); } return false; } return true; } public static bool IsBetrayalAddon(this CustomRoles role) { switch (role) { case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Egoist: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Rascal: case CustomRoles.Recruit: case CustomRoles.Soulless: return true; default: return false; } } public static bool IsImpOnlyAddon(this CustomRoles role) { switch (role) { case CustomRoles.Circumvent: case CustomRoles.Clumsy: case CustomRoles.LastImpostor: case CustomRoles.Mare: case CustomRoles.Mimic: case CustomRoles.Swift: case CustomRoles.TicketsStealer: case CustomRoles.Tricky: return true; default: return false; } } public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool checkLimitAddons = true) { if (!role.IsAdditionRole()) { return false; } if (pc.Is(role)) { return false; } if ((pc.Is(CustomRoles.RuthlessRomantic) || pc.Is(CustomRoles.Romantic) || pc.Is(CustomRoles.VengefulRomantic)) && role == CustomRoles.Lovers) { return false; } if (pc.Is(CustomRoles.GM) || role == CustomRoles.Lovers || pc.Is(CustomRoles.LazyGuy)) { return false; } if (checkLimitAddons && pc.HasSubRole() && pc.GetCustomSubRoles().Count >= Options.NoLimitAddonsNumMax.GetInt()) { return false; } switch (role) { case CustomRoles.Stubborn: if ((pc.GetCustomRole().IsCrewmate() && !Stubborn.CrewCanBeStubborn.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Stubborn.NeutralCanBeStubborn.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Stubborn.ImpCanBeStubborn.GetBool())) { return false; } break; case CustomRoles.Autopsy: if (pc.Is(CustomRoles.Doctor) || pc.Is(CustomRoles.Tracefinder) || pc.Is(CustomRoles.ScientistTOHE) || pc.Is(CustomRoles.Sunnyboy)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Autopsy.CrewCanBeAutopsy.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Autopsy.NeutralCanBeAutopsy.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Autopsy.ImpCanBeAutopsy.GetBool())) { return false; } break; case CustomRoles.Bait: if (pc.Is(CustomRoles.Trapper) || pc.Is(CustomRoles.Provocateur) || pc.Is(CustomRoles.Unreportable) || pc.Is(CustomRoles.Burst) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.PunchingBag) || (pc.Is(CustomRoles.Onbound) && Bait.BaitNotification.GetBool()) || (pc.Is(CustomRoles.Rebound) && Bait.BaitNotification.GetBool()) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Bait.CrewCanBeBait.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Bait.NeutralCanBeBait.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Bait.ImpCanBeBait.GetBool())) { return false; } break; case CustomRoles.Trapper: if (pc.Is(CustomRoles.Bait) || pc.Is(CustomRoles.Burst) || pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Trapper.CrewCanBeTrapper.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Trapper.NeutralCanBeTrapper.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Trapper.ImpCanBeTrapper.GetBool())) { return false; } break; case CustomRoles.Guesser: if (Options.GuesserMode.GetBool() && ((pc.GetCustomRole().IsCrewmate() && !Guesser.CrewCanBeGuesser.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Guesser.NeutralCanBeGuesser.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Guesser.ImpCanBeGuesser.GetBool()))) { return false; } if (pc.Is(CustomRoles.EvilGuesser) || pc.Is(CustomRoles.NiceGuesser) || pc.Is(CustomRoles.Judge) || pc.Is(CustomRoles.CopyCat) || pc.Is(CustomRoles.Doomsayer) || pc.Is(CustomRoles.Nemesis) || pc.Is(CustomRoles.Councillor) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.Is(CustomRoles.Specter) && !Specter.CanGuess.GetBool()) || (pc.Is(CustomRoles.Terrorist) && (!Terrorist.TerroristCanGuess.GetBool() || Terrorist.CanTerroristSuicideWin.GetBool())) || (pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicCanGuess.GetBool()) || (pc.Is(CustomRoles.Solsticer) && !Solsticer.SolsticerCanGuess.GetBool()) || (pc.Is(CustomRoles.God) && !God.CanGuess.GetBool())) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Guesser.CrewCanBeGuesser.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Guesser.NeutralCanBeGuesser.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Guesser.ImpCanBeGuesser.GetBool())) { return false; } break; case CustomRoles.Mundane: if (pc.HasImpKillButton() || !Utils.HasTasks(pc.Data, ForRecompute: false) || pc.GetCustomRole().IsTasklessCrewmate() || pc.Is(Custom_Team.Impostor)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Mundane.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Mundane.CanBeOnNeutral.GetBool())) { return false; } if (pc.Is(CustomRoles.CopyCat) || pc.Is(CustomRoles.Doomsayer) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.Collector) || pc.Is(CustomRoles.Ghoul)) { return false; } if ((pc.Is(CustomRoles.Specter) && !Specter.CanGuess.GetBool()) || (pc.Is(CustomRoles.Terrorist) && (!Terrorist.TerroristCanGuess.GetBool() || Terrorist.CanTerroristSuicideWin.GetBool())) || (pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicCanGuess.GetBool()) || (pc.Is(CustomRoles.Solsticer) && !Solsticer.SolsticerCanGuess.GetBool()) || (pc.Is(CustomRoles.God) && !God.CanGuess.GetBool())) { return false; } if (pc.Is(CustomRoles.Guesser) || pc.Is(CustomRoles.NiceGuesser)) { return true; } if (Options.GuesserMode.GetBool()) { if (pc.GetCustomRole().IsNonNK() && Options.PassiveNeutralsCanGuess.GetBool()) { return true; } if (pc.GetCustomRole().IsCrewmate() && Options.CrewmatesCanGuess.GetBool()) { return true; } return false; } return false; case CustomRoles.Onbound: if (pc.Is(CustomRoles.SuperStar) || Doctor.VisibleToEveryone(pc) || (pc.Is(CustomRoles.Bait) && Bait.BaitNotification.GetBool()) || pc.Is(CustomRoles.LastImpostor) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.Mare) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Rebound) || (pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicVisibleToEveryone.GetBool()) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Onbound.CrewCanBeOnbound.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Onbound.NeutralCanBeOnbound.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Onbound.ImpCanBeOnbound.GetBool())) { return false; } break; case CustomRoles.Rebound: if (pc.Is(CustomRoles.SuperStar) || Doctor.VisibleToEveryone(pc) || (pc.Is(CustomRoles.Bait) && Bait.BaitNotification.GetBool()) || pc.Is(CustomRoles.LastImpostor) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.Mare) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Onbound) || (pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicVisibleToEveryone.GetBool()) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Rebound.CrewCanBeRebound.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Rebound.NeutralCanBeRebound.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Rebound.ImpCanBeRebound.GetBool())) { return false; } break; case CustomRoles.DoubleShot: if (!Options.GuesserMode.GetBool() && !pc.Is(CustomRoles.EvilGuesser) && !pc.Is(CustomRoles.NiceGuesser) && !pc.Is(CustomRoles.Doomsayer) && !pc.Is(CustomRoles.Guesser)) { return false; } if (pc.Is(CustomRoles.Doomsayer) && Doomsayer.DoesNotSuicideWhenMisguessing.GetBool()) { return false; } if (pc.Is(CustomRoles.CopyCat) || (pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicCanGuess.GetBool()) || (pc.Is(CustomRoles.Terrorist) && (!Terrorist.TerroristCanGuess.GetBool() || Terrorist.CanTerroristSuicideWin.GetBool())) || (pc.Is(CustomRoles.Specter) && !Specter.CanGuess.GetBool()) || (pc.Is(CustomRoles.Solsticer) && !Solsticer.SolsticerCanGuess.GetBool()) || (pc.Is(CustomRoles.God) && !God.CanGuess.GetBool())) { return false; } if (Options.GuesserMode.GetBool()) { if (DoubleShot.ImpCanBeDoubleShot.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.EvilGuesser) && (pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && !Options.ImpostorsCanGuess.GetBool()) { return false; } if (DoubleShot.CrewCanBeDoubleShot.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.NiceGuesser) && pc.Is(Custom_Team.Crewmate) && !Options.CrewmatesCanGuess.GetBool()) { return false; } if (DoubleShot.NeutralCanBeDoubleShot.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Doomsayer) && ((pc.GetCustomRole().IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool()) || (pc.GetCustomRole().IsNK() && !Options.NeutralKillersCanGuess.GetBool()))) { return false; } } if ((pc.Is(Custom_Team.Impostor) && !DoubleShot.ImpCanBeDoubleShot.GetBool()) || (pc.Is(Custom_Team.Crewmate) && !DoubleShot.CrewCanBeDoubleShot.GetBool()) || (pc.Is(Custom_Team.Neutral) && !DoubleShot.NeutralCanBeDoubleShot.GetBool())) { return false; } break; case CustomRoles.Cyber: if (pc.Is(CustomRoles.Doppelganger) || pc.Is(CustomRoles.Celebrity) || pc.Is(CustomRoles.SuperStar)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Cyber.CrewCanBeCyber.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Cyber.NeutralCanBeCyber.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Cyber.ImpCanBeCyber.GetBool())) { return false; } break; case CustomRoles.Reach: if (!pc.CanUseKillButton()) { return false; } break; case CustomRoles.Overclocked: if (!pc.CanUseKillButton()) { return false; } break; case CustomRoles.Lazy: if (!Lazy.CheckConflicts(pc)) { return false; } break; case CustomRoles.Ghoul: if (pc.Is(CustomRoles.Lazy) || pc.Is(CustomRoles.LazyGuy) || pc.Is(CustomRoles.Mundane)) { return false; } if (pc.GetCustomRole().IsNeutral() || pc.GetCustomRole().IsImpostor() || pc.GetCustomRole().IsTasklessCrewmate() || pc.GetCustomRole().IsTaskBasedCrewmate()) { return false; } break; case CustomRoles.Bloodthirst: if (pc.Is(CustomRoles.Lazy) || pc.Is(CustomRoles.Merchant) || pc.Is(CustomRoles.Alchemist) || pc.Is(CustomRoles.LazyGuy) || pc.Is(CustomRoles.Crewpostor) || pc.Is(CustomRoles.Bodyguard)) { return false; } if (!pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsTasklessCrewmate()) { return false; } break; case CustomRoles.Torch: if (pc.Is(CustomRoles.Bewilder) || pc.Is(CustomRoles.Lighter) || pc.Is(CustomRoles.Tired) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.KillingMachine)) { return false; } if (!pc.GetCustomRole().IsCrewmate()) { return false; } break; case CustomRoles.Watcher: if ((pc.GetCustomRole().IsCrewmate() && !Watcher.CrewCanBeWatcher.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Watcher.NeutralCanBeWatcher.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Watcher.ImpCanBeWatcher.GetBool())) { return false; } break; case CustomRoles.Aware: if ((pc.GetCustomRole().IsCrewmate() && !Aware.CrewCanBeAware.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Aware.NeutralCanBeAware.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Aware.ImpCanBeAware.GetBool())) { return false; } break; case CustomRoles.Fragile: if (pc.Is(CustomRoles.Lucky) || pc.Is(CustomRoles.Veteran) || pc.Is(CustomRoles.Guardian) || pc.Is(CustomRoles.Medic) || pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.Jinx) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.CursedWolf) || pc.Is(CustomRoles.PunchingBag) || pc.Is(CustomRoles.SchrodingersCat) || pc.Is(CustomRoles.PlagueBearer) || pc.Is(CustomRoles.Pestilence) || pc.Is(CustomRoles.Spy) || pc.Is(CustomRoles.Necromancer) || pc.Is(CustomRoles.Demon) || pc.Is(CustomRoles.Shaman)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Fragile.CrewCanBeFragile.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Fragile.NeutralCanBeFragile.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Fragile.ImpCanBeFragile.GetBool())) { return false; } break; case CustomRoles.VoidBallot: if (pc.Is(CustomRoles.Mayor) || pc.Is(CustomRoles.Vindicator) || pc.Is(CustomRoles.TicketsStealer) || pc.Is(CustomRoles.Pickpocket) || pc.Is(CustomRoles.Dictator) || pc.Is(CustomRoles.Influenced) || pc.Is(CustomRoles.Silent) || pc.Is(CustomRoles.Tiebreaker) || pc.Is(CustomRoles.Paranoia)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !VoidBallot.CrewCanBeVoidBallot.GetBool()) || (pc.GetCustomRole().IsNeutral() && !VoidBallot.NeutralCanBeVoidBallot.GetBool()) || (pc.GetCustomRole().IsImpostor() && !VoidBallot.ImpCanBeVoidBallot.GetBool())) { return false; } break; case CustomRoles.Glow: if (pc.Is(CustomRoles.KillingMachine)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Glow.CrewCanBeGlow.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Glow.NeutralCanBeGlow.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Glow.ImpCanBeGlow.GetBool())) { return false; } break; case CustomRoles.Radar: if ((pc.GetCustomRole().IsCrewmate() && !Radar.CrewCanBeRadar.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Radar.NeutralCanBeRadar.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Radar.ImpCanBeRadar.GetBool())) { return false; } break; case CustomRoles.Antidote: if (pc.Is(CustomRoles.Diseased) || pc.Is(CustomRoles.Solsticer)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Antidote.CrewCanBeAntidote.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Antidote.NeutralCanBeAntidote.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Antidote.ImpCanBeAntidote.GetBool())) { return false; } break; case CustomRoles.Diseased: if (pc.Is(CustomRoles.Antidote) || pc.Is(CustomRoles.Solsticer)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Diseased.CrewCanBeDiseased.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Diseased.NeutralCanBeDiseased.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Diseased.ImpCanBeDiseased.GetBool())) { return false; } break; case CustomRoles.Seer: if (pc.Is(CustomRoles.Mortician) || pc.Is(CustomRoles.EvilTracker) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Seer.CrewCanBeSeer.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Seer.NeutralCanBeSeer.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Seer.ImpCanBeSeer.GetBool())) { return false; } break; case CustomRoles.Sleuth: if (pc.Is(CustomRoles.Oblivious) || pc.Is(CustomRoles.Detective) || pc.Is(CustomRoles.Mortician) || pc.Is(CustomRoles.Cleaner) || pc.Is(CustomRoles.Medusa) || pc.Is(CustomRoles.Vulture) || pc.Is(CustomRoles.Coroner)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Sleuth.CrewCanBeSleuth.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Sleuth.NeutralCanBeSleuth.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Sleuth.ImpCanBeSleuth.GetBool())) { return false; } break; case CustomRoles.Necroview: if (pc.Is(CustomRoles.Doctor) || pc.Is(CustomRoles.God) || pc.Is(CustomRoles.Visionary) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Necroview.CrewCanBeNecroview.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Necroview.NeutralCanBeNecroview.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Necroview.ImpCanBeNecroview.GetBool())) { return false; } break; case CustomRoles.Bewilder: if (pc.Is(CustomRoles.Torch) || pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Lighter) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Tired) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.PunchingBag) || pc.Is(CustomRoles.KillingMachine)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Bewilder.CrewCanBeBewilder.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Bewilder.NeutralCanBeBewilder.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Bewilder.ImpCanBeBewilder.GetBool())) { return false; } break; case CustomRoles.Lucky: if (pc.Is(CustomRoles.Guardian) || pc.Is(CustomRoles.Unlucky) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Fragile) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Lucky.CrewCanBeLucky.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Lucky.NeutralCanBeLucky.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Lucky.ImpCanBeLucky.GetBool())) { return false; } break; case CustomRoles.Unlucky: if (pc.Is(CustomRoles.Vector) || pc.Is(CustomRoles.Lucky) || pc.Is(CustomRoles.Vector) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Taskinator) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Unlucky.CrewCanBeUnlucky.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Unlucky.NeutralCanBeUnlucky.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Unlucky.ImpCanBeUnlucky.GetBool())) { return false; } break; case CustomRoles.Madmate: if (pc.Is(CustomRoles.Sidekick) || pc.Is(CustomRoles.SuperStar) || pc.Is(CustomRoles.Egoist) || pc.Is(CustomRoles.Rascal) || pc.Is(CustomRoles.NiceMini)) { return false; } if (!pc.CanBeMadmate() || pc.IsAnySubRole((CustomRoles sub) => sub.IsConverted())) { return false; } break; case CustomRoles.Oblivious: if (pc.Is(CustomRoles.Detective) || pc.Is(CustomRoles.Vulture) || pc.Is(CustomRoles.Sleuth) || pc.Is(CustomRoles.Cleaner) || pc.Is(CustomRoles.Amnesiac) || pc.Is(CustomRoles.Coroner) || pc.Is(CustomRoles.Medusa) || pc.Is(CustomRoles.Mortician) || pc.Is(CustomRoles.Medium) || pc.Is(CustomRoles.KillingMachine) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Oblivious.CrewCanBeOblivious.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Oblivious.NeutralCanBeOblivious.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Oblivious.ImpCanBeOblivious.GetBool())) { return false; } break; case CustomRoles.Tiebreaker: if (pc.Is(CustomRoles.Dictator) || pc.Is(CustomRoles.VoidBallot) || pc.Is(CustomRoles.Influenced) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Tiebreaker.CrewCanBeTiebreaker.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Tiebreaker.NeutralCanBeTiebreaker.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Tiebreaker.ImpCanBeTiebreaker.GetBool())) { return false; } break; case CustomRoles.Youtuber: if (pc.Is(CustomRoles.Madmate) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Sheriff) || pc.Is(CustomRoles.Hurried) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if (!pc.GetCustomRole().IsCrewmate()) { return false; } break; case CustomRoles.Egoist: if (pc.Is(CustomRoles.Sidekick) || pc.Is(CustomRoles.Madmate) || pc.Is(CustomRoles.Hurried) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if (pc.GetCustomRole().IsNeutral() || pc.GetCustomRole().IsMadmate() || pc.IsAnySubRole((CustomRoles sub) => sub.IsConverted())) { return false; } if ((pc.GetCustomRole().IsImpostor() && !Egoist.ImpCanBeEgoist.GetBool()) || (pc.GetCustomRole().IsCrewmate() && !Egoist.CrewCanBeEgoist.GetBool())) { return false; } break; case CustomRoles.Mimic: if (pc.Is(CustomRoles.Nemesis)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Rascal: if (pc.Is(CustomRoles.SuperStar) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.Madmate)) { return false; } if (!pc.GetCustomRole().IsCrewmate()) { return false; } break; case CustomRoles.TicketsStealer: if (pc.Is(CustomRoles.Vindicator) || pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.VoidBallot) || pc.Is(CustomRoles.Swift)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Tricky: if (pc.Is(CustomRoles.Mastermind) || pc.Is(CustomRoles.Vampire) || pc.Is(CustomRoles.Puppeteer) || pc.Is(CustomRoles.Scavenger) || pc.Is(CustomRoles.Lightning) || pc.Is(CustomRoles.Swift)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Mare: if (pc.Is(CustomRoles.Underdog) || pc.Is(CustomRoles.Berserker) || pc.Is(CustomRoles.Inhibitor) || pc.Is(CustomRoles.Saboteur) || pc.Is(CustomRoles.Swift) || pc.Is(CustomRoles.Nemesis) || pc.Is(CustomRoles.Sniper) || pc.Is(CustomRoles.Fireworker) || pc.Is(CustomRoles.Ludopath) || pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Vampire) || pc.Is(CustomRoles.Arrogance) || pc.Is(CustomRoles.LastImpostor) || pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.Trapster) || pc.Is(CustomRoles.Onbound) || pc.Is(CustomRoles.Rebound) || pc.Is(CustomRoles.Tired)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Swift: if (pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.Trapster) || pc.Is(CustomRoles.Kamikaze) || pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Vampire) || pc.Is(CustomRoles.Scavenger) || pc.Is(CustomRoles.Puppeteer) || pc.Is(CustomRoles.Mastermind) || pc.Is(CustomRoles.Warlock) || pc.Is(CustomRoles.Witch) || pc.Is(CustomRoles.Penguin) || pc.Is(CustomRoles.Nemesis) || pc.Is(CustomRoles.Mare) || pc.Is(CustomRoles.Clumsy) || pc.Is(CustomRoles.Wildling) || pc.Is(CustomRoles.Consigliere) || pc.Is(CustomRoles.Butcher) || pc.Is(CustomRoles.KillingMachine) || pc.Is(CustomRoles.Gangster) || pc.Is(CustomRoles.Berserker) || pc.Is(CustomRoles.BountyHunter) || pc.Is(CustomRoles.Lightning) || pc.Is(CustomRoles.Hangman) || pc.Is(CustomRoles.TicketsStealer) || pc.Is(CustomRoles.Tricky)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Nimble: if (Knight.CheckCanUseVent(pc) || pc.Is(CustomRoles.CopyCat)) { return false; } if (!pc.GetCustomRole().IsTasklessCrewmate()) { return false; } break; case CustomRoles.Circumvent: if ((pc.GetCustomRole() == CustomRoles.Vampire && !Vampire.CheckCanUseVent()) || (pc.Is(CustomRoles.Witch) && Witch.ModeSwitchActionOpt.GetValue() == 1) || pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Wildling) || pc.Is(CustomRoles.KillingMachine) || pc.Is(CustomRoles.Lurker)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Clumsy: if (pc.Is(CustomRoles.Swift) || pc.Is(CustomRoles.Bomber) || pc.Is(CustomRoles.KillingMachine)) { return false; } if (!pc.GetCustomRole().IsImpostor()) { return false; } break; case CustomRoles.Burst: if (pc.Is(CustomRoles.Avanger) || pc.Is(CustomRoles.Trapper) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Bait) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Burst.CrewCanBeBurst.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Burst.NeutralCanBeBurst.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Burst.ImpCanBeBurst.GetBool())) { return false; } break; case CustomRoles.Avanger: if (pc.Is(CustomRoles.Burst) || pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Avanger.CrewCanBeAvanger.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Avanger.NeutralCanBeAvanger.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Avanger.ImpCanBeAvanger.GetBool())) { return false; } break; case CustomRoles.Paranoia: if (pc.Is(CustomRoles.Dictator) || pc.Is(CustomRoles.Madmate) || pc.Is(CustomRoles.GuardianAngelTOHE)) { return false; } if (!pc.GetCustomRole().IsImpostor() && !pc.GetCustomRole().IsCrewmate()) { return false; } if ((pc.GetCustomRole().IsImpostor() && !Paranoia.CanBeImp.GetBool()) || (pc.GetCustomRole().IsCrewmate() && !Paranoia.CanBeCrew.GetBool())) { return false; } if (pc.GetCustomRole().IsNotKnightable() && Paranoia.DualVotes.GetBool()) { return false; } break; case CustomRoles.Loyal: if (pc.Is(CustomRoles.Madmate) || pc.Is(CustomRoles.Oiiai) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.Influenced) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.EvilMini) || (pc.Is(CustomRoles.CopyCat) && CopyCat.CanCopyTeamChangingAddon())) { return false; } if (!pc.GetCustomRole().IsImpostor() && !pc.GetCustomRole().IsCrewmate()) { return false; } if ((pc.GetCustomRole().IsImpostor() && !Loyal.ImpCanBeLoyal.GetBool()) || (pc.GetCustomRole().IsCrewmate() && !Loyal.CrewCanBeLoyal.GetBool())) { return false; } break; case CustomRoles.Gravestone: if (pc.Is(CustomRoles.SuperStar) || pc.Is(CustomRoles.Innocent) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.NiceMini)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Gravestone.CrewCanBeGravestone.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Gravestone.NeutralCanBeGravestone.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Gravestone.ImpCanBeGravestone.GetBool())) { return false; } break; case CustomRoles.Unreportable: if (pc.Is(CustomRoles.Randomizer) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Bait)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Unreportable.CrewCanBeUnreportable.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Unreportable.NeutralCanBeUnreportable.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Unreportable.ImpCanBeUnreportable.GetBool())) { return false; } break; case CustomRoles.Flash: if (pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Tired) || pc.Is(CustomRoles.Statue) || pc.Is(CustomRoles.Seeker) || pc.Is(CustomRoles.Doppelganger) || pc.Is(CustomRoles.DollMaster)) { return false; } break; case CustomRoles.Fool: if (pc.Is(CustomRoles.Mechanic) || pc.Is(CustomRoles.GuardianAngelTOHE) || pc.Is(CustomRoles.Alchemist)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Fool.CrewCanBeFool.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Fool.NeutralCanBeFool.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Fool.ImpCanBeFool.GetBool())) { return false; } break; case CustomRoles.Influenced: if (pc.Is(CustomRoles.Dictator) || pc.Is(CustomRoles.Loyal) || pc.Is(CustomRoles.VoidBallot) || pc.Is(CustomRoles.Tiebreaker) || pc.Is(CustomRoles.Collector) || pc.Is(CustomRoles.Keeper)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Influenced.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Influenced.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Influenced.CanBeOnImp.GetBool())) { return false; } break; case CustomRoles.Oiiai: if (pc.Is(CustomRoles.Loyal) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Innocent) || pc.Is(CustomRoles.PunchingBag)) { return false; } if ((pc.GetCustomRole().IsNeutral() && !Oiiai.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsCrewmate() && !Oiiai.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Oiiai.CanBeOnImp.GetBool())) { return false; } break; case CustomRoles.Hurried: if (pc.Is(CustomRoles.Youtuber) || pc.Is(CustomRoles.Egoist) || pc.Is(CustomRoles.Cleanser) || pc.Is(CustomRoles.Solsticer)) { return false; } if (pc.Is(CustomRoles.Madmate) && !Hurried.CanBeOnMadMate.GetBool()) { return false; } if (!pc.GetCustomRole().IsCrewmate() && !pc.Is(CustomRoles.Madmate)) { return false; } if (pc.GetCustomRole().IsTasklessCrewmate()) { return false; } if (pc.GetCustomRole().IsTaskBasedCrewmate() && !Hurried.CanBeOnTaskBasedCrew.GetBool()) { return false; } break; case CustomRoles.Silent: if (pc.Is(CustomRoles.Dictator) || pc.Is(CustomRoles.VoidBallot)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Silent.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Silent.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Silent.CanBeOnImp.GetBool())) { return false; } break; case CustomRoles.Rainbow: if (pc.Is(CustomRoles.Doppelganger) || pc.Is(CustomRoles.DollMaster) || pc.Is(CustomRoles.Chameleon) || pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Alchemist) || pc.Is(CustomRoles.Wraith)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Rainbow.CrewCanBeRainbow.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Rainbow.NeutralCanBeRainbow.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Rainbow.ImpCanBeRainbow.GetBool())) { return false; } break; case CustomRoles.Susceptible: if ((pc.GetCustomRole().IsCrewmate() && !Susceptible.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Susceptible.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Susceptible.CanBeOnImp.GetBool())) { return false; } break; case CustomRoles.Tired: if (pc.Is(CustomRoles.Overseer) || pc.Is(CustomRoles.Alchemist) || pc.Is(CustomRoles.Torch) || pc.Is(CustomRoles.Bewilder) || pc.Is(CustomRoles.Lighter) || pc.Is(CustomRoles.Flash) || pc.Is(CustomRoles.Mare)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Tired.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Tired.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Tired.CanBeOnImp.GetBool())) { return false; } break; case CustomRoles.Statue: if (pc.Is(CustomRoles.Alchemist) || pc.Is(CustomRoles.Flash) || pc.Is(CustomRoles.Tired)) { return false; } if ((pc.GetCustomRole().IsCrewmate() && !Statue.CanBeOnCrew.GetBool()) || (pc.GetCustomRole().IsNeutral() && !Statue.CanBeOnNeutral.GetBool()) || (pc.GetCustomRole().IsImpostor() && !Statue.CanBeOnImp.GetBool())) { return false; } break; } return true; } public static RoleTypes GetRoleTypes(this CustomRoles role) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) return (RoleTypes)(role.GetVNRole() switch { CustomRoles.Crewmate => 0, CustomRoles.Impostor => 1, CustomRoles.Scientist => 2, CustomRoles.Engineer => 3, CustomRoles.GuardianAngel => 4, CustomRoles.Shapeshifter => 5, CustomRoles.Noisemaker => 8, CustomRoles.Phantom => 9, CustomRoles.Tracker => 10, _ => role.IsImpostor() ? 1 : 0, }); } public static bool IsDesyncRole(this CustomRoles role) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 return (int)role.GetDYRole() != 4; } public static bool IsImpostorTeam(this CustomRoles role) { if (!role.IsImpostor()) { return role == CustomRoles.Madmate; } return true; } public static bool IsCrewmate(this CustomRoles role) { if (!role.IsImpostor() && !role.IsNeutral()) { return !role.IsMadmate(); } return false; } public static bool IsImpostorTeamV2(this CustomRoles role) { if (role != CustomRoles.Rascal && role != CustomRoles.Madmate) { if (role.IsImpostorTeamV3() && role != CustomRoles.Trickster) { if (role.IsConverted()) { return role == CustomRoles.Madmate; } return true; } return false; } return true; } public static bool IsNeutralTeamV2(this CustomRoles role) { if ((role.IsConverted() && role != CustomRoles.Madmate) || role.IsNeutral()) { return role != CustomRoles.Madmate; } return false; } public static bool IsCrewmateTeamV2(this CustomRoles role) { if (role.IsImpostorTeamV2() || role.IsNeutralTeamV2()) { return role == CustomRoles.Trickster; } return true; } public static bool IsImpostorTeamV3(this CustomRoles role) { if (!role.IsImpostor()) { return role.IsMadmate(); } return true; } public static bool IsNeutralKillerTeam(this CustomRoles role) { if (role.IsNK()) { return !role.IsMadmate(); } return false; } public static bool IsPassiveNeutralTeam(this CustomRoles role) { if (role.IsNonNK()) { return !role.IsMadmate(); } return false; } public static bool IsNNK(this CustomRoles role) { if (role.IsNeutral()) { return !role.IsNK(); } return false; } public static bool IsVanilla(this CustomRoles role) { if ((uint)role <= 8u) { return true; } return false; } public static Custom_Team GetCustomRoleTeam(this CustomRoles role) { Custom_Team result = Custom_Team.Crewmate; if (role.IsImpostor()) { result = Custom_Team.Impostor; } if (role.IsNeutral()) { result = Custom_Team.Neutral; } if (role.IsAdditionRole()) { result = Custom_Team.Addon; } return result; } public static Custom_RoleType GetCustomRoleType(this CustomRoles role) { return role.GetStaticRoleClass().ThisRoleType; } public static bool RoleExist(this CustomRoles role, bool countDead = false) { return Main.AllPlayerControls.Any((PlayerControl x) => x.Is(role) && (x.IsAlive() || countDead)); } public static int GetCount(this CustomRoles role) { if (role.IsVanilla()) { if (Options.DisableVanillaRoles.GetBool()) { return 0; } IRoleOptionsCollection roleOptions = Main.NormalOptions.RoleOptions; return role switch { CustomRoles.Crewmate => roleOptions.GetNumPerGame((RoleTypes)0), CustomRoles.Scientist => roleOptions.GetNumPerGame((RoleTypes)2), CustomRoles.Engineer => roleOptions.GetNumPerGame((RoleTypes)3), CustomRoles.GuardianAngel => roleOptions.GetNumPerGame((RoleTypes)4), CustomRoles.Shapeshifter => roleOptions.GetNumPerGame((RoleTypes)5), CustomRoles.Noisemaker => roleOptions.GetNumPerGame((RoleTypes)8), CustomRoles.Phantom => roleOptions.GetNumPerGame((RoleTypes)9), CustomRoles.Tracker => roleOptions.GetNumPerGame((RoleTypes)10), _ => 0, }; } return Options.GetRoleCount(role); } public static int GetMode(this CustomRoles role) { return Options.GetRoleSpawnMode(role); } public static float GetChance(this CustomRoles role) { if (role.IsVanilla()) { IRoleOptionsCollection roleOptions = Main.NormalOptions.RoleOptions; return (float)(role switch { CustomRoles.Crewmate => roleOptions.GetChancePerGame((RoleTypes)0), CustomRoles.Scientist => roleOptions.GetChancePerGame((RoleTypes)2), CustomRoles.Engineer => roleOptions.GetChancePerGame((RoleTypes)3), CustomRoles.GuardianAngel => roleOptions.GetChancePerGame((RoleTypes)4), CustomRoles.Shapeshifter => roleOptions.GetChancePerGame((RoleTypes)5), CustomRoles.Noisemaker => roleOptions.GetChancePerGame((RoleTypes)8), CustomRoles.Phantom => roleOptions.GetChancePerGame((RoleTypes)9), CustomRoles.Tracker => roleOptions.GetChancePerGame((RoleTypes)10), _ => 0, }) / 100f; } return Options.GetRoleChance(role); } public static bool IsEnable(this CustomRoles role) { return role.GetCount() > 0; } public static CountTypes GetCountTypes(this CustomRoles role) { switch (role) { case CustomRoles.GM: return CountTypes.OutOfGame; case CustomRoles.Jackal: return CountTypes.Jackal; case CustomRoles.Sidekick: return CountTypes.Jackal; case CustomRoles.Doppelganger: return CountTypes.Doppelganger; case CustomRoles.Bandit: return CountTypes.Bandit; case CustomRoles.Poisoner: return CountTypes.Poisoner; case CustomRoles.Pelican: return CountTypes.Pelican; case CustomRoles.Minion: return CountTypes.Impostor; case CustomRoles.Bloodmoon: return CountTypes.Impostor; case CustomRoles.Demon: return CountTypes.Demon; case CustomRoles.BloodKnight: return CountTypes.BloodKnight; case CustomRoles.Cultist: return CountTypes.Cultist; case CustomRoles.HexMaster: return CountTypes.HexMaster; case CustomRoles.Necromancer: return CountTypes.Necromancer; case CustomRoles.Stalker: return (!Stalker.SnatchesWin.GetBool()) ? CountTypes.Stalker : CountTypes.Crew; case CustomRoles.Arsonist: return Arsonist.CanIgniteAnytime() ? CountTypes.Arsonist : CountTypes.Crew; case CustomRoles.Shroud: return CountTypes.Shroud; case CustomRoles.Werewolf: return CountTypes.Werewolf; case CustomRoles.Wraith: return CountTypes.Wraith; case CustomRoles.Pestilence: return CountTypes.Pestilence; case CustomRoles.PlagueBearer: return CountTypes.PlagueBearer; case CustomRoles.Agitater: return CountTypes.Agitater; case CustomRoles.Parasite: return CountTypes.Impostor; case CustomRoles.SerialKiller: return CountTypes.SerialKiller; case CustomRoles.Quizmaster: return CountTypes.Quizmaster; case CustomRoles.Juggernaut: return CountTypes.Juggernaut; case CustomRoles.Jinx: return CountTypes.Jinx; case CustomRoles.Infectious: case CustomRoles.Infected: return CountTypes.Infectious; case CustomRoles.Crewpostor: return CountTypes.Impostor; case CustomRoles.Pyromaniac: return CountTypes.Pyromaniac; case CustomRoles.PlagueDoctor: return CountTypes.PlagueDoctor; case CustomRoles.Virus: return CountTypes.Virus; case CustomRoles.PotionMaster: return CountTypes.PotionMaster; case CustomRoles.Pickpocket: return CountTypes.Pickpocket; case CustomRoles.Traitor: return CountTypes.Traitor; case CustomRoles.Medusa: return CountTypes.Medusa; case CustomRoles.Refugee: return CountTypes.Impostor; case CustomRoles.Huntsman: return CountTypes.Huntsman; case CustomRoles.Glitch: return CountTypes.Glitch; case CustomRoles.Spiritcaller: return CountTypes.Spiritcaller; case CustomRoles.RuthlessRomantic: return CountTypes.RuthlessRomantic; case CustomRoles.SchrodingersCat: return CountTypes.None; case CustomRoles.Solsticer: return CountTypes.None; default: return role.IsImpostorTeam() ? CountTypes.Impostor : CountTypes.Crew; } } public static CustomWinner GetNeutralCustomWinnerFromRole(this CustomRoles role) { return role switch { CustomRoles.Jester => CustomWinner.Jester, CustomRoles.Terrorist => CustomWinner.Terrorist, CustomRoles.Lovers => CustomWinner.Lovers, CustomRoles.Executioner => CustomWinner.Executioner, CustomRoles.Arsonist => CustomWinner.Arsonist, CustomRoles.Pyromaniac => CustomWinner.Pyromaniac, CustomRoles.Agitater => CustomWinner.Agitater, CustomRoles.Revolutionist => CustomWinner.Revolutionist, CustomRoles.Jackal => CustomWinner.Jackal, CustomRoles.Sidekick => CustomWinner.Sidekick, CustomRoles.God => CustomWinner.God, CustomRoles.Vector => CustomWinner.Vector, CustomRoles.Innocent => CustomWinner.Innocent, CustomRoles.Pelican => CustomWinner.Pelican, CustomRoles.Youtuber => CustomWinner.Youtuber, CustomRoles.Egoist => CustomWinner.Egoist, CustomRoles.Demon => CustomWinner.Demon, CustomRoles.Stalker => CustomWinner.Stalker, CustomRoles.Workaholic => CustomWinner.Workaholic, CustomRoles.Solsticer => CustomWinner.Solsticer, CustomRoles.Collector => CustomWinner.Collector, CustomRoles.BloodKnight => CustomWinner.BloodKnight, CustomRoles.Poisoner => CustomWinner.Poisoner, CustomRoles.HexMaster => CustomWinner.HexMaster, CustomRoles.Cultist => CustomWinner.Cultist, CustomRoles.Wraith => CustomWinner.Wraith, CustomRoles.Bandit => CustomWinner.Bandit, CustomRoles.Pirate => CustomWinner.Pirate, CustomRoles.SerialKiller => CustomWinner.SerialKiller, CustomRoles.Quizmaster => CustomWinner.Quizmaster, CustomRoles.Werewolf => CustomWinner.Werewolf, CustomRoles.Necromancer => CustomWinner.Necromancer, CustomRoles.Huntsman => CustomWinner.Huntsman, CustomRoles.Juggernaut => CustomWinner.Juggernaut, CustomRoles.Infectious => CustomWinner.Infectious, CustomRoles.Virus => CustomWinner.Virus, CustomRoles.Specter => CustomWinner.Specter, CustomRoles.Jinx => CustomWinner.Jinx, CustomRoles.CursedSoul => CustomWinner.CursedSoul, CustomRoles.PotionMaster => CustomWinner.PotionMaster, CustomRoles.Pickpocket => CustomWinner.Pickpocket, CustomRoles.Traitor => CustomWinner.Traitor, CustomRoles.Vulture => CustomWinner.Vulture, CustomRoles.Pestilence => CustomWinner.Pestilence, CustomRoles.Medusa => CustomWinner.Medusa, CustomRoles.Spiritcaller => CustomWinner.Spiritcaller, CustomRoles.Glitch => CustomWinner.Glitch, CustomRoles.PlagueBearer => CustomWinner.Plaguebearer, CustomRoles.PunchingBag => CustomWinner.PunchingBag, CustomRoles.Doomsayer => CustomWinner.Doomsayer, CustomRoles.Shroud => CustomWinner.Shroud, CustomRoles.Seeker => CustomWinner.Seeker, CustomRoles.SoulCollector => CustomWinner.SoulCollector, CustomRoles.RuthlessRomantic => CustomWinner.RuthlessRomantic, CustomRoles.Mini => CustomWinner.NiceMini, CustomRoles.Doppelganger => CustomWinner.Doppelganger, _ => throw new NotImplementedException(), }; } public static CustomRoles GetNeutralCustomRoleFromCountType(this CountTypes type) { return type switch { CountTypes.OutOfGame => CustomRoles.GM, CountTypes.Jackal => CustomRoles.Jackal, CountTypes.Doppelganger => CustomRoles.Doppelganger, CountTypes.Bandit => CustomRoles.Bandit, CountTypes.Poisoner => CustomRoles.Poisoner, CountTypes.Pelican => CustomRoles.Pelican, CountTypes.Demon => CustomRoles.Demon, CountTypes.BloodKnight => CustomRoles.BloodKnight, CountTypes.Cultist => CustomRoles.Cultist, CountTypes.HexMaster => CustomRoles.HexMaster, CountTypes.Necromancer => CustomRoles.Necromancer, CountTypes.Shroud => CustomRoles.Shroud, CountTypes.Werewolf => CustomRoles.Werewolf, CountTypes.Wraith => CustomRoles.Wraith, CountTypes.Pestilence => CustomRoles.Pestilence, CountTypes.PlagueBearer => CustomRoles.PlagueBearer, CountTypes.Agitater => CustomRoles.Agitater, CountTypes.SerialKiller => CustomRoles.SerialKiller, CountTypes.Quizmaster => CustomRoles.Quizmaster, CountTypes.Juggernaut => CustomRoles.Juggernaut, CountTypes.Jinx => CustomRoles.Jinx, CountTypes.Infectious => CustomRoles.Infectious, CountTypes.Pyromaniac => CustomRoles.Pyromaniac, CountTypes.Virus => CustomRoles.Virus, CountTypes.PotionMaster => CustomRoles.PotionMaster, CountTypes.Pickpocket => CustomRoles.Pickpocket, CountTypes.Traitor => CustomRoles.Traitor, CountTypes.Medusa => CustomRoles.Medusa, CountTypes.Huntsman => CustomRoles.Huntsman, CountTypes.Glitch => CustomRoles.Glitch, CountTypes.Stalker => CustomRoles.Stalker, CountTypes.Spiritcaller => CustomRoles.Spiritcaller, CountTypes.Arsonist => CustomRoles.Arsonist, CountTypes.RuthlessRomantic => CustomRoles.RuthlessRomantic, _ => throw new NotImplementedException(), }; } public static bool HasSubRole(this PlayerControl pc) { return Main.PlayerStates[pc.PlayerId].SubRoles.Any(); } } public enum Custom_Team { Crewmate, Impostor, Neutral, Addon } public enum Custom_RoleType { ImpostorVanilla, ImpostorKilling, ImpostorSupport, ImpostorConcealing, ImpostorHindering, ImpostorGhosts, Madmate, CrewmateVanilla, CrewmateVanillaGhosts, CrewmateBasic, CrewmateSupport, CrewmateKilling, CrewmatePower, CrewmateGhosts, NeutralBenign, NeutralEvil, NeutralChaos, NeutralKilling, None } public enum CountTypes { OutOfGame, None, Crew, Impostor, Jackal, Doppelganger, Bandit, Pelican, PlagueDoctor, Demon, BloodKnight, Poisoner, Charmed, Cultist, HexMaster, Wraith, SerialKiller, Juggernaut, Infectious, Virus, Stalker, Jinx, PotionMaster, Pickpocket, Traitor, Medusa, Spiritcaller, Pestilence, Quizmaster, PlagueBearer, Glitch, Arsonist, Huntsman, Pyromaniac, Shroud, Werewolf, Agitater, RuthlessRomantic, Necromancer } public class CustomRpcSender { public delegate void onSendDelegateType(); public enum State { BeforeInit, Ready, InRootMessage, InRpc, Finished } public MessageWriter stream; public readonly string name; public readonly SendOption sendOption; public bool isUnsafe; public onSendDelegateType onSendDelegate; private State currentState; private int currentRpcTarget; public State CurrentState { get { return currentState; } set { if (isUnsafe) { currentState = value; } else { Logger.Warn("CurrentStateはisUnsafeがtrueの時のみ上書きできます", "CustomRpcSender", escapeCRLF: true, 24, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } } } private CustomRpcSender() { } public CustomRpcSender(string name, SendOption sendOption, bool isUnsafe) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) stream = MessageWriter.Get(sendOption); this.name = name; this.sendOption = sendOption; this.isUnsafe = isUnsafe; currentRpcTarget = -2; onSendDelegate = delegate { Logger.Info(this.name + "'s onSendDelegate =>", "CustomRpcSender", escapeCRLF: true, 43, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); }; currentState = State.Ready; Logger.Info("\"" + name + "\" is ready", "CustomRpcSender", escapeCRLF: true, 46, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } public static CustomRpcSender Create(string name = "No Name Sender", SendOption sendOption = 0, bool isUnsafe = false) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new CustomRpcSender(name, sendOption, isUnsafe); } public CustomRpcSender StartMessage(int targetClientId = -1) { if (currentState != State.Ready) { string text = "Messageを開始しようとしましたが、StateがReadyではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 61, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } if (targetClientId < 0) { stream.StartMessage((byte)5); stream.Write(((InnerNetClient)AmongUsClient.Instance).GameId); } else { stream.StartMessage((byte)6); stream.Write(((InnerNetClient)AmongUsClient.Instance).GameId); stream.WritePacked(targetClientId); } currentRpcTarget = targetClientId; currentState = State.InRootMessage; return this; } public CustomRpcSender EndMessage() { if (currentState != State.InRootMessage) { string text = "Messageを終了しようとしましたが、StateがInRootMessageではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 93, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } stream.EndMessage(); currentRpcTarget = -2; currentState = State.Ready; return this; } public CustomRpcSender StartRpc(uint targetNetId, RpcCalls rpcCall) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected I4, but got Unknown return StartRpc(targetNetId, (byte)(int)rpcCall); } public CustomRpcSender StartRpc(uint targetNetId, byte callId) { if (currentState != State.InRootMessage) { string text = "RPCを開始しようとしましたが、StateがInRootMessageではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } stream.StartMessage((byte)2); stream.WritePacked(targetNetId); stream.Write(callId); currentState = State.InRpc; return this; } public CustomRpcSender EndRpc() { if (currentState != State.InRpc) { string text = "RPCを終了しようとしましたが、StateがInRpcではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } stream.EndMessage(); currentState = State.InRootMessage; return this; } public CustomRpcSender AutoStartRpc(uint targetNetId, byte callId, int targetClientId = -1) { if (targetClientId == -2) { targetClientId = -1; } State state = currentState; if (state != State.Ready && state != State.InRootMessage) { string text = "RPCを自動で開始しようとしましたが、StateがReadyまたはInRootMessageではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 153, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } if (currentRpcTarget != targetClientId) { if (currentState == State.InRootMessage) { EndMessage(); } StartMessage(targetClientId); } StartRpc(targetNetId, callId); return this; } public void SendMessage() { if (currentState == State.InRootMessage) { EndMessage(); } if (currentState != State.Ready) { string text = "Attempted to send RPC, but State is not Ready (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 174, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } ((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(stream); onSendDelegate(); currentState = State.Finished; Logger.Info("\"" + name + "\" is finished", "CustomRpcSender", escapeCRLF: true, 182, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); stream.Recycle(); } public CustomRpcSender Write(float val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(string val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(ulong val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(int val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(uint val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(ushort val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(byte val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(sbyte val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(bool val) { return Write((Action)delegate(MessageWriter w) { w.Write(val); }); } public CustomRpcSender Write(Il2CppStructArray bytes) { return Write((Action)delegate(MessageWriter w) { w.Write(bytes); }); } public CustomRpcSender Write(Il2CppStructArray bytes, int offset, int length) { return Write((Action)delegate(MessageWriter w) { w.Write(bytes, offset, length); }); } public CustomRpcSender WriteBytesAndSize(Il2CppStructArray bytes) { return Write((Action)delegate(MessageWriter w) { w.WriteBytesAndSize(bytes); }); } public CustomRpcSender WritePacked(int val) { return Write((Action)delegate(MessageWriter w) { w.WritePacked(val); }); } public CustomRpcSender WritePacked(uint val) { return Write((Action)delegate(MessageWriter w) { w.WritePacked(val); }); } public CustomRpcSender WriteNetObject(InnerNetObject obj) { return Write((Action)delegate(MessageWriter w) { MessageExtensions.WriteNetObject(w, obj); }); } public CustomRpcSender WriteMessageType(byte val) { return Write((Action)delegate(MessageWriter w) { w.StartMessage(val); }); } public CustomRpcSender WriteEndMessage() { return Write((Action)delegate(MessageWriter w) { w.EndMessage(); }); } private CustomRpcSender Write(Action action) { if (currentState != State.InRpc) { string text = "RPCを書き込もうとしましたが、StateがWrite(書き込み中)ではありません (in: \"" + name + "\")"; if (!isUnsafe) { throw new InvalidOperationException(text); } Logger.Warn(text, "CustomRpcSender.Warn", escapeCRLF: true, 213, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomRpcSender.cs"); } action(stream); return this; } } public static class CustomRpcSenderExtensions { public static void RpcSetRole(this CustomRpcSender sender, PlayerControl player, RoleTypes role, int targetClientId = -1) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected I4, but got Unknown sender.AutoStartRpc(((InnerNetObject)player).NetId, 44, targetClientId).Write((ushort)(int)role).Write(val: false) .EndRpc(); } public static void RpcMurderPlayerV3(this CustomRpcSender sender, PlayerControl player, PlayerControl target, int targetClientId = -1) { sender.AutoStartRpc(((InnerNetObject)player).NetId, 12, targetClientId).WriteNetObject((InnerNetObject)(object)target).Write(1) .EndRpc(); } } public static class CustomWinnerHolder { public static CustomWinner WinnerTeam; public static HashSet AdditionalWinnerTeams; public static HashSet WinnerRoles; public static HashSet WinnerIds; public static void Reset() { WinnerTeam = CustomWinner.Default; AdditionalWinnerTeams = new HashSet(); WinnerRoles = new HashSet(); WinnerIds = new HashSet(); } public static void ClearWinners() { WinnerRoles.Clear(); WinnerIds.Clear(); } public static void SetWinnerOrAdditonalWinner(CustomWinner winner) { if (WinnerTeam == CustomWinner.Default) { WinnerTeam = winner; } else { AdditionalWinnerTeams.Add((AdditionalWinners)winner); } } public static void ShiftWinnerAndSetWinner(CustomWinner winner) { if (WinnerTeam != CustomWinner.Default) { AdditionalWinnerTeams.Add((AdditionalWinners)WinnerTeam); } WinnerTeam = winner; } public static void ResetAndSetWinner(CustomWinner winner) { Reset(); WinnerTeam = winner; } public static bool CheckForConvertedWinner(byte playerId) { CustomRoles[] array = Utils.GetPlayerById(playerId).GetCustomSubRoles().ToArray(); foreach (CustomRoles customRoles in array) { if (customRoles == CustomRoles.Madmate || customRoles == CustomRoles.Admired || customRoles.IsConverted()) { switch (customRoles) { case CustomRoles.Admired: ResetAndSetWinner(CustomWinner.Crewmate); return true; case CustomRoles.Madmate: ResetAndSetWinner(CustomWinner.Impostor); return true; case CustomRoles.Recruit: ResetAndSetWinner(CustomWinner.Jackal); return true; case CustomRoles.Charmed: ResetAndSetWinner(CustomWinner.Cultist); return true; case CustomRoles.Infectious: ResetAndSetWinner(CustomWinner.Infectious); return true; case CustomRoles.Contagious: ResetAndSetWinner(CustomWinner.Virus); return true; } } } return false; } public static MessageWriter WriteTo(MessageWriter writer) { writer.WritePacked((int)WinnerTeam); writer.WritePacked(AdditionalWinnerTeams.Count); foreach (AdditionalWinners additionalWinnerTeam in AdditionalWinnerTeams) { writer.WritePacked((int)additionalWinnerTeam); } writer.WritePacked(WinnerRoles.Count); foreach (CustomRoles winnerRole in WinnerRoles) { writer.WritePacked((int)winnerRole); } writer.WritePacked(WinnerIds.Count); foreach (byte winnerId in WinnerIds) { writer.Write(winnerId); } return writer; } public static void ReadFrom(MessageReader reader) { WinnerTeam = (CustomWinner)reader.ReadPackedInt32(); AdditionalWinnerTeams = new HashSet(); int num = reader.ReadPackedInt32(); for (int i = 0; i < num; i++) { AdditionalWinnerTeams.Add((AdditionalWinners)reader.ReadPackedInt32()); } WinnerRoles = new HashSet(); int num2 = reader.ReadPackedInt32(); for (int j = 0; j < num2; j++) { WinnerRoles.Add((CustomRoles)reader.ReadPackedInt32()); } WinnerIds = new HashSet(); int num3 = reader.ReadPackedInt32(); for (int k = 0; k < num3; k++) { WinnerIds.Add(reader.ReadByte()); } } } public class dbConnect { private enum FailedConnectReason { Build_Not_Specified, API_Token_Is_Empty, Error_Getting_User_Role_Table, Error_Getting_EAC_List } private static bool InitOnce = false; private static Dictionary userType = new Dictionary(); private const string oldApiUrl = "https://api.tohre.dev"; private const string newApiUrl = "https://api.weareten.ca"; public static IEnumerator Init() { Logger.Info("Begin dbConnect Login flow", "dbConnect.init", escapeCRLF: true, 23, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); if (!InitOnce) { yield return GetRoleTable(); if (!Main.devRelease && !Main.canaryRelease && !Main.fullRelease) { HandleFailure(FailedConnectReason.Build_Not_Specified); yield break; } string token = GetToken(); if ((token == "" || token == null) ? true : false) { HandleFailure(FailedConnectReason.API_Token_Is_Empty); yield break; } if (userType.Count < 1) { HandleFailure(FailedConnectReason.Error_Getting_User_Role_Table); yield break; } yield return GetEACList(); if (BanManager.EACDict.Count < 1) { HandleFailure(FailedConnectReason.Error_Getting_EAC_List); yield break; } } else { yield return GetRoleTable(); yield return GetEACList(); } if (!InitOnce) { Logger.Info("Finished first init flow.", "dbConnect.init", escapeCRLF: true, 62, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); InitOnce = true; } else { Logger.Info("Finished Sync flow.", "dbConnect.init", escapeCRLF: true, 67, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); } } private static void HandleFailure(FailedConnectReason errorReason) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) Logger.Error(errorReason switch { FailedConnectReason.Build_Not_Specified => "Build not specified", FailedConnectReason.API_Token_Is_Empty => "API token is empty", FailedConnectReason.Error_Getting_User_Role_Table => "Error in fetching roletable", FailedConnectReason.Error_Getting_EAC_List => "Error in fetching EAC list", _ => "Reason not specified", }, "dbConnect.init", escapeCRLF: true, 82, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); bool flag; if (Main.devRelease) { flag = true; } else if (Main.canaryRelease || Main.fullRelease) { flag = false; if (GameStates.IsLobby || GameStates.InGame) { DestroyableSingleton.Instance.ShowPopUp(Translator.GetString("dbConnect.InitFailure")); } else { DestroyableSingleton.Instance.ShowCustom(Translator.GetString("dbConnect.InitFailure")); } } else { flag = true; } if (flag) { if ((int)((InnerNetClient)AmongUsClient.Instance).mode != 0) { AmongUsClient.Instance.ExitGame((DisconnectReasons)0); } DataManager.Player.Account.LoginStatus = (AccountLoginStatus)0; ((AbstractSaveData)DataManager.Player).Save(); DestroyableSingleton.Instance.ShowCustom(Translator.GetString("dbConnect.InitFailure")); } } private static string GetToken() { string text = ""; Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = "TOHE.token.env"; using (Stream stream = executingAssembly.GetManifestResourceStream(name)) { if (stream != null) { using StreamReader streamReader = new StreamReader(stream); text = streamReader.ReadToEnd().Replace("API_TOKEN=", string.Empty).Trim(); } if (stream == null || text == "") { Logger.Warn("Embedded resource not found.", "apiToken.error", escapeCRLF: true, 147, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); } } return text; } private static IEnumerator GetRoleTable() { Dictionary tempUserType = new Dictionary(); string apiToken = GetToken(); if (apiToken == "") { Logger.Warn("Embedded resource not found.", "GetRoleTable.error", escapeCRLF: true, 158, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); yield return null; } DateTime dateTime = new DateTime(2024, 8, 21); string text = ((!(DateTime.UtcNow < dateTime)) ? "https://api.weareten.ca" : "https://api.tohre.dev"); string text2 = text + "/userInfo?token=" + apiToken; UnityWebRequest webRequest = UnityWebRequest.Get(text2); yield return webRequest.SendWebRequest(); if ((int)webRequest.result != 1) { Logger.Error("Error in fetching the User List: " + webRequest.error, "GetRoleTable.error", escapeCRLF: true, 176, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); yield return null; } try { foreach (Dictionary item in JsonSerializer.Deserialize>>(webRequest.downloadHandler.text)) { if (!item["friendcode"].ToString().IsDevUser()) { DevManager.DevUserList.Add(new DevUser(item["friendcode"].ToString(), item["color"].ToString(), tag: ToAutoTranslate(item["overhead_tag"]), userType: item["type"].ToString(), isUp: item["isUP"].GetInt32() == 1, isDev: item["isDev"].GetInt32() == 1, deBug: item["debug"].GetInt32() == 1, colorCmd: item["colorCmd"].GetInt32() == 1, nameCmd: false, upName: item["name"].ToString())); } tempUserType[item["friendcode"].ToString()] = item["type"].ToString(); } if (tempUserType.Count > 1) { userType = tempUserType; } else if (!InitOnce) { Logger.Error("Incoming RoleTable is null, cannot init!", "GetRoleTable.error", escapeCRLF: true, 205, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); } } catch (Exception ex) { Logger.Error("Error processing response: " + ex.Message, "GetRoleTable.error", escapeCRLF: true, 210, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); } finally { webRequest.Dispose(); } } private static string ToAutoTranslate(JsonElement tag) { string text = tag.ToString(); switch (text) { case "Contributor": text = Translator.GetString("Contributor"); break; case "Translator": text = Translator.GetString("Translator"); break; case "Sponsor": text = Translator.GetString("Sponsor"); break; } return text; } public static bool IsBooster(string friendcode) { if (!userType.ContainsKey(friendcode)) { return false; } return userType[friendcode] == "s_bo"; } private static IEnumerator GetEACList() { string token = GetToken(); if (token == "") { Logger.Warn("Embedded resource not found.", "GetEACList.error", escapeCRLF: true, 248, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); yield break; } DateTime dateTime = new DateTime(2024, 8, 21); string text = ((!(DateTime.UtcNow < dateTime)) ? "https://api.weareten.ca" : "https://api.tohre.dev"); string text2 = text + "/eac?token=" + token; UnityWebRequest webRequest = UnityWebRequest.Get(text2); yield return webRequest.SendWebRequest(); if ((int)webRequest.result != 1) { Logger.Error("Error in fetching the EAC List: " + webRequest.error, "GetEACList.error", escapeCRLF: true, 268, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); yield break; } try { List> list = JsonSerializer.Deserialize>>(webRequest.downloadHandler.text); List> eACDict = BanManager.EACDict; List> list2 = list; List> list3 = new List>(eACDict.Count + list2.Count); foreach (Dictionary item in eACDict) { list3.Add(item); } foreach (Dictionary item2 in list2) { list3.Add(item2); } BanManager.EACDict = list3; } catch (JsonException ex) { Logger.Error("Error deserializing JSON: " + ex.Message, "GetEACList.error", escapeCRLF: true, 280, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); } finally { webRequest.Dispose(); } } private static bool CanAccessDev(string friendCode) { if (!userType.ContainsKey(friendCode)) { Logger.Error("no user found, with friendcode " + friendCode, "CanAccessDev", escapeCRLF: true, 292, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); return false; } if (userType[friendCode] == "s_bo" || userType[friendCode] == "s_it" || userType[friendCode].StartsWith("t_")) { Logger.Error("Error : Dev access denied to user " + friendCode + ", type = " + userType[friendCode], "CanAccessDev", escapeCRLF: true, 298, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\dbConnect.cs"); return false; } return true; } } internal class Webhook { public static void Send(string text) { if (!(Main.WebhookURL.Value == "none")) { new HttpClient().PostAsync(content: new FormUrlEncodedContent(new Dictionary { { "content", text }, { "username", "TOHE-Debugger" }, { "avatar_url", "https://npm.elemecdn.com/hexo-static@1.0.1/img/avatar.webp" } }), requestUri: Main.WebhookURL.Value).GetAwaiter().GetResult(); } } } internal class Logger { public static bool IsEnable; public static List DisableList = new List(); public static List SendToGameList = new List(); private static readonly HashSet NowDetailedErrorLog = new HashSet(); public static bool isDetail = false; public static bool isAlsoInGame = false; public static void Enable() { IsEnable = true; } public static void Disable() { IsEnable = false; } public static void Enable(string tag, bool toGame = false) { DisableList.Remove(tag); if (toGame && !SendToGameList.Contains(tag)) { SendToGameList.Add(tag); } else { SendToGameList.Remove(tag); } } public static void Disable(string tag) { if (!DisableList.Contains(tag)) { DisableList.Add(tag); } } public static void SendInGame(string text) { if (IsEnable && Object.op_Implicit((Object)(object)DestroyableSingleton._instance)) { DestroyableSingleton.Instance.Notifier.AddDisconnectMessage(text); } } private static void SendToFile(string text, LogLevel level = 16, string tag = "", bool escapeCRLF = true, int lineNumber = 0, string fileName = "", bool multiLine = false) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Invalid comparison between Unknown and I4 //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Invalid comparison between Unknown and I4 //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Expected I4, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Invalid comparison between Unknown and I4 //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Invalid comparison between Unknown and I4 if (!IsEnable || DisableList.Contains(tag)) { return; } ManualLogSource logger = Main.Logger; if (SendToGameList.Contains(tag) || isAlsoInGame) { SendInGame("[" + tag + "]" + text); } bool flag = ((level - 1 <= 1 || (int)level == 4) ? true : false); string text2; if (flag && !multiLine && !NowDetailedErrorLog.Contains(tag)) { string value = DateTime.Now.ToString("HH:mm:ss"); StackFrame stackFrame = new StackFrame(2); string value2 = stackFrame.GetMethod()?.ReflectedType?.Name; string value3 = stackFrame.GetMethod()?.Name; text2 = $"[{value}][{value2}.{value3}({Path.GetFileName(fileName)}:{lineNumber})][{tag}]{text}"; NowDetailedErrorLog.Add(tag); new LateTask(delegate { NowDetailedErrorLog.Remove(tag); }, 3f, "No Name Task", shoudLog: false); } else { if (escapeCRLF) { text = text.Replace("\r", "\\r").Replace("\n", "\\n"); } string value4 = DateTime.Now.ToString("HH:mm:ss"); text2 = $"[{value4}][{tag}]{text}"; } if ((int)level <= 8) { switch (level - 1) { default: if ((int)level != 8) { break; } logger.LogMessage((object)text2); return; case 3: logger.LogWarning((object)text2); return; case 1: logger.LogError((object)text2); return; case 0: logger.LogFatal((object)text2); return; case 2: break; } } else { if ((int)level == 16) { logger.LogInfo((object)text2); return; } if ((int)level == 32) { logger.LogFatal((object)text2); return; } } logger.LogWarning((object)"Error:Invalid LogLevel"); logger.LogInfo((object)text2); } public static void Test(object content, string tag = "======= Test =======", bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(content.ToString(), (LogLevel)32, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Info(string text, string tag, bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(text, (LogLevel)16, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Warn(string text, string tag, bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(text, (LogLevel)4, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Error(string text, string tag, bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(text, (LogLevel)2, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Fatal(string text, string tag, bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(text, (LogLevel)1, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Msg(string text, string tag, bool escapeCRLF = true, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "", bool multiLine = false) { SendToFile(text, (LogLevel)8, tag, escapeCRLF, lineNumber, fileName, multiLine); } public static void Exception(Exception ex, string tag, [CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "") { SendToFile(ex.ToString(), (LogLevel)2, tag, escapeCRLF: false, lineNumber, fileName); } public static void CurrentMethod([CallerLineNumber] int lineNumber = 0, [CallerFilePath] string fileName = "") { StackFrame stackFrame = new StackFrame(1); Msg($"\"{stackFrame.GetMethod().ReflectedType.Name}.{stackFrame.GetMethod().Name}\" Called in \"{Path.GetFileName(fileName)}({lineNumber})\"", "Method", escapeCRLF: true, 122, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Debugger.cs"); } public static LogHandler Handler(string tag) { return new LogHandler(tag); } } public static class DebugModeManager { public static OptionItem EnableDebugMode; public static bool AmDebugger { get; private set; } public static bool IsDebugMode { get { if (AmDebugger && EnableDebugMode != null) { return EnableDebugMode.GetBool(); } return false; } } public static void Auth(HashAuth auth, string input) { AmDebugger = AmDebugger || auth.CheckString(input); } public static void SetupCustomOption() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) EnableDebugMode = BooleanOptionItem.Create(2, "EnableDebugMode", defaultValue: false, TabGroup.SystemSettings, isSingleValue: true).SetHeader(value: true).SetColor(Color.green) .SetHeader(value: true) .SetHidden(!AmDebugger); } } public class DevUser { public string Code { get; set; } public string Color { get; set; } public string UserType { get; set; } public string Tag { get; set; } public bool IsUp { get; set; } public bool IsDev { get; set; } public bool DeBug { get; set; } public bool ColorCmd { get; set; } public bool NameCmd { get; set; } public string UpName { get; set; } public DevUser(string code = "", string color = "null", string userType = "null", string tag = "null", bool isUp = false, bool isDev = false, bool deBug = false, bool colorCmd = false, bool nameCmd = false, string upName = "未认证用户") { Code = code; Color = color; UserType = userType; Tag = tag; IsUp = isUp; IsDev = isDev; DeBug = deBug; ColorCmd = colorCmd; NameCmd = nameCmd; UpName = upName; base..ctor(); } public bool HasTag() { return Tag != "null"; } public string GetTag() { string path = "./TOHE-DATA/Tags/SPONSOR_TAGS/" + Code + ".txt"; if (Color == "null" || Color == string.Empty) { return "" + Tag + "\r\n"; } string value = Color.TrimStart('#'); if (File.Exists(path)) { string text = File.ReadAllText(path); if (Utils.CheckColorHex(text)) { value = text; } } string value2 = ((Tag == "#Dev") ? Translator.GetString("Developer") : Tag); return $"{value2}\r\r\n"; } } public static class DevManager { private static readonly DevUser DefaultDevUser = new DevUser(); public static readonly List DevUserList = new List(); public static void Init() { DevUserList.Add(new DevUser("actorour#0029", "#ffc0cb", "s_cr", "Original Developer", isUp: true, isDev: true, deBug: true, colorCmd: true, nameCmd: false, "KARPED1EM")); DevUserList.Add(new DevUser("pinklaze#1776", "#30548e", "s_cr", "#Dev", isUp: true, isDev: true, deBug: true, colorCmd: false, nameCmd: false, "NCSIMON")); DevUserList.Add(new DevUser("sofaagile#3120", "null", "s_cr", "null", isUp: false, isDev: true, deBug: true, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("icingposh#6469", "#9e2424", "s_cr", "discord.gg/tohe", isUp: true, isDev: true, deBug: true, colorCmd: true, nameCmd: false, "ryuk2")); DevUserList.Add(new DevUser("bestanswer#3360", "#00ff1d", "s_cr", "绿色游戏", isUp: true, isDev: true, deBug: true, colorCmd: true, nameCmd: false, null)); DevUserList.Add(new DevUser("happypride#3747", "#00ff1d", "s_cr", "绿色游戏", isUp: true, isDev: true, deBug: true, colorCmd: true, nameCmd: false, null)); DevUserList.Add(new DevUser("truantwarm#9165", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "萧暮不姓萧")); DevUserList.Add(new DevUser("drilldinky#1386", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "爱玩AU的河豚")); DevUserList.Add(new DevUser("farardour#6818", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "-提米SaMa-")); DevUserList.Add(new DevUser("vealused#8192", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "lag丶xy")); DevUserList.Add(new DevUser("storyeager#0815", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "航娜丽莎")); DevUserList.Add(new DevUser("versegame#3885", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "柴唔cw")); DevUserList.Add(new DevUser("closegrub#6217", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "警长不会玩")); DevUserList.Add(new DevUser("frownnatty#7935", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "鬼灵official")); DevUserList.Add(new DevUser("veryscarf#5368", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "小武同学102")); DevUserList.Add(new DevUser("sparklybee#0275", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "--红包SaMa--")); DevUserList.Add(new DevUser("endingyon#3175", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "游侠开摆")); DevUserList.Add(new DevUser("firmine#0232", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "YH永恒_")); DevUserList.Add(new DevUser("fellowsand#1003", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "C-Faust")); DevUserList.Add(new DevUser("jetsafe#8512", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "Hoream是好人")); DevUserList.Add(new DevUser("spoonkey#0792", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "没好康的")); DevUserList.Add(new DevUser("busethical#4134", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "茄-au")); DevUserList.Add(new DevUser("marlymoor#2246", "null", "null", "null", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "落Yan")); DevUserList.Add(new DevUser("neatnet#5851", "#FFFF00", "null", "The 200IQ guy", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "The 200IQ guy")); DevUserList.Add(new DevUser("heavyclod#2286", "#FFFF00", "null", "小叨.exe已停止运行", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "小叨院长")); DevUserList.Add(new DevUser("storeroan#0331", "#FF0066", "null", "Night_瓜", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "Night_瓜")); DevUserList.Add(new DevUser("teamelder#5856", "#1379bf", "null", "屑Slok(没信誉的鸽子)", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "Slok7565")); DevUserList.Add(new DevUser("freepit#9942", "#00FFFF", "null", "古明地白糖", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "古明地白糖")); DevUserList.Add(new DevUser("radarright#2509", "null", "null", "null", isUp: false, isDev: false, deBug: true, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("recentduct#6068", "#FF00FF", "null", "高冷男模法师", isUp: false, isDev: false, deBug: true, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("canneddrum#2370", "#fffcbe", "null", "我是喜唉awa", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("dovefitted#5329", "#1379bf", "null", "不要首刀我", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("luckylogo#7352", "#f30000", "null", "林@林", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("axefitful#8788", "#8e8171", "null", "寄才是真理", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("raftzonal#8893", "#8e8171", "null", "寄才是真理", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("twainrobin#8089", "#0000FF", "null", "啊哈修maker", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("mallcasual#6075", "#f89ccb", "null", "波奇酱", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("beamelfin#9478", "#6495ED", "null", "Amaster-1111", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("lordcosy#8966", "#FFD6EC", "null", "HostTOHE", isUp: false, isDev: false, deBug: false, colorCmd: false, nameCmd: false, null)); DevUserList.Add(new DevUser("honestsofa#2870", "#D381D9", "null", "Discord: SolarFlare#0700", isUp: true, isDev: false, deBug: false, colorCmd: false, nameCmd: false, "SolarFlare")); } public static bool IsDevUser(this string code) { return DevUserList.Any((DevUser x) => x.Code == code); } public static DevUser GetDevUser(this string code) { if (!code.IsDevUser()) { return DefaultDevUser; } return DevUserList.Find((DevUser x) => x.Code == code); } public static string GetUserType(this DevUser user) { string result = "Crewmate"; if (user.UserType != "null" && user.UserType != string.Empty) { switch (user.UserType) { case "s_cr": result = "Contributor"; break; case "s_bo": result = "Booster"; break; case "s_tr": result = "Tester"; break; case "s_jc": result = "Junior Contributor"; break; default: if (user.UserType.StartsWith("s_")) { result = "Sponsor"; } else if (user.UserType.StartsWith("t_")) { result = "Translator"; } break; } } return result; } } internal class DisableDevice { private static readonly HashSet DesyncComms = new HashSet(); private static int frame = 0; public static readonly Dictionary DevicePos = new Dictionary { ["SkeldAdmin"] = new Vector2(3.48f, -8.62f), ["SkeldCamera"] = new Vector2(-13.06f, -2.45f), ["MiraHQAdmin"] = new Vector2(21.02f, 19.09f), ["MiraHQDoorLog"] = new Vector2(16.22f, 5.82f), ["PolusLeftAdmin"] = new Vector2(22.8f, -21.52f), ["PolusRightAdmin"] = new Vector2(24.66f, -21.52f), ["PolusCamera"] = new Vector2(2.96f, -12.74f), ["PolusVital"] = new Vector2(26.7f, -15.94f), ["DleksAdmin"] = new Vector2(-3.48f, -8.62f), ["DleksCamera"] = new Vector2(13.06f, -2.45f), ["AirshipCockpitAdmin"] = new Vector2(-22.32f, 0.91f), ["AirshipRecordsAdmin"] = new Vector2(19.89f, 12.6f), ["AirshipCamera"] = new Vector2(8.1f, -9.63f), ["AirshipVital"] = new Vector2(25.24f, -7.94f), ["FungleCamera"] = new Vector2(6.2f, 0.1f), ["FungleVital"] = new Vector2(-2.5f, -9.8f) }; public static bool DoDisable => Options.DisableDevices.GetBool(); public static float UsableDistance(MapNames Map) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected I4, but got Unknown return (int)Map switch { 0 => 1.8f, 1 => 2.4f, 2 => 1.8f, 3 => 1.5f, 4 => 1.8f, 5 => 1.8f, _ => 0f, }; } public static void FixedUpdate() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_040e: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) frame = ((frame != 3) ? (++frame) : 0); if (frame != 0 || !DoDisable) { return; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { try { if (val.IsModClient()) { continue; } bool flag = false; Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position); bool flag2 = (Options.DisableDevicesIgnoreImpostors.GetBool() && val.Is(Custom_Team.Impostor)) || (Options.DisableDevicesIgnoreNeutrals.GetBool() && val.Is(Custom_Team.Neutral)) || (Options.DisableDevicesIgnoreCrewmates.GetBool() && val.Is(Custom_Team.Crewmate)) || (Options.DisableDevicesIgnoreAfterAnyoneDied.GetBool() && GameStates.AlreadyDied); byte activeMapId = Utils.GetActiveMapId(); MapNames map = (MapNames)activeMapId; if (val.IsAlive() && !Utils.IsActive((SystemTypes)14)) { switch (activeMapId) { case 0: if (Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["SkeldAdmin"]) <= UsableDistance(map); } if (Options.DisableSkeldCamera.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["SkeldCamera"]) <= UsableDistance(map); } break; case 1: if (Options.DisableMiraHQAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["MiraHQAdmin"]) <= UsableDistance(map); } if (Options.DisableMiraHQDoorLog.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["MiraHQDoorLog"]) <= UsableDistance(map); } break; case 2: if (Options.DisablePolusAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["PolusLeftAdmin"]) <= UsableDistance(map); flag |= Vector2.Distance(val2, DevicePos["PolusRightAdmin"]) <= UsableDistance(map); } if (Options.DisablePolusCamera.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["PolusCamera"]) <= UsableDistance(map); } if (Options.DisablePolusVital.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["PolusVital"]) <= UsableDistance(map); } break; case 3: if (Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["DleksAdmin"]) <= UsableDistance(map); } if (Options.DisableSkeldCamera.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["DleksCamera"]) <= UsableDistance(map); } break; case 4: if (Options.DisableAirshipCockpitAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["AirshipCockpitAdmin"]) <= UsableDistance(map); } if (Options.DisableAirshipRecordsAdmin.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["AirshipRecordsAdmin"]) <= UsableDistance(map); } if (Options.DisableAirshipCamera.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["AirshipCamera"]) <= UsableDistance(map); } if (Options.DisableAirshipVital.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["AirshipVital"]) <= UsableDistance(map); } break; case 5: if (Options.DisableFungleBinoculars.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["FungleCamera"]) <= UsableDistance(map); } if (Options.DisableFungleVital.GetBool()) { flag |= Vector2.Distance(val2, DevicePos["FungleVital"]) <= UsableDistance(map); } break; } } if (flag && !flag2 && !val.inVent) { if (!DesyncComms.Contains(val.PlayerId)) { DesyncComms.Add(val.PlayerId); } val.RpcDesyncUpdateSystem((SystemTypes)14, 128); } else if (!Utils.IsActive((SystemTypes)14) && DesyncComms.Contains(val.PlayerId)) { DesyncComms.Remove(val.PlayerId); val.RpcDesyncUpdateSystem((SystemTypes)14, 16); if ((activeMapId == 1 || activeMapId == 5) ? true : false) { val.RpcDesyncUpdateSystem((SystemTypes)14, 17); } } } catch (Exception ex) { Logger.Exception(ex, "DisableDevice", 137, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DisableDevice.cs"); } } } } [HarmonyPatch(typeof(ShipStatus), "Start")] public class RemoveDisableDevicesPatch { public static void Postfix() { if (Options.DisableDevices.GetBool()) { UpdateDisableDevices(); } } public static void UpdateDisableDevices() { PlayerControl localPlayer = PlayerControl.LocalPlayer; bool ignore = localPlayer.Is(CustomRoles.GM) || !localPlayer.IsAlive() || (Options.DisableDevicesIgnoreImpostors.GetBool() && localPlayer.Is(Custom_Team.Impostor)) || (Options.DisableDevicesIgnoreNeutrals.GetBool() && localPlayer.Is(Custom_Team.Neutral)) || (Options.DisableDevicesIgnoreCrewmates.GetBool() && localPlayer.Is(Custom_Team.Crewmate)) || (Options.DisableDevicesIgnoreAfterAnyoneDied.GetBool() && GameStates.AlreadyDied); Il2CppArrayBase val = Object.FindObjectsOfType(true); Il2CppArrayBase val2 = Object.FindObjectsOfType(true); if (val == null || val2 == null) { return; } switch (Utils.GetActiveMapId()) { case 0: case 3: if (Options.DisableSkeldAdmin.GetBool()) { ((Behaviour)((Component)val[0]).gameObject.GetComponent()).enabled = ignore; } if (Options.DisableSkeldCamera.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "SurvConsole"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } break; case 1: if (Options.DisableMiraHQAdmin.GetBool()) { ((Behaviour)((Component)val[0]).gameObject.GetComponent()).enabled = ignore; } if (Options.DisableMiraHQDoorLog.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "SurvLogConsole"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } break; case 2: if (Options.DisablePolusAdmin.GetBool()) { CollectionExtensions.Do((IEnumerable)val, (Action)delegate(MapConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } if (Options.DisablePolusCamera.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "Surv_Panel"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } if (Options.DisablePolusVital.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "panel_vitals"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } break; case 4: CollectionExtensions.Do((IEnumerable)val, (Action)delegate(MapConsole x) { if ((Options.DisableAirshipCockpitAdmin.GetBool() && ((Object)x).name == "panel_cockpit_map") || (Options.DisableAirshipRecordsAdmin.GetBool() && ((Object)x).name == "records_admin_map")) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; } }); if (Options.DisableAirshipCamera.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "task_cams"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } if (Options.DisableAirshipVital.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "panel_vitals"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } break; case 5: if (Options.DisableFungleBinoculars.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "BinocularsSecurityConsole"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } if (Options.DisableFungleVital.GetBool()) { CollectionExtensions.DoIf((IEnumerable)val2, (Func)((SystemConsole x) => ((Object)x).name == "VitalsConsole"), (Action)delegate(SystemConsole x) { ((Behaviour)((Component)x).gameObject.GetComponent()).enabled = ignore; }); } break; } } } internal static class DoubleTrigger { public static readonly HashSet PlayerIdList = new HashSet(); public static readonly Dictionary FirstTriggerTimer = new Dictionary(); public static readonly Dictionary FirstTriggerTarget = new Dictionary(); public static readonly Dictionary FirstTriggerAction = new Dictionary(); public static void Init() { PlayerIdList.Clear(); FirstTriggerTimer.Clear(); FirstTriggerAction.Clear(); } public static void AddDoubleTrigger(this PlayerControl killer) { PlayerIdList.Add(killer.PlayerId); } private static bool CanDoubleTrigger(this PlayerControl killer) { return PlayerIdList.Contains(killer.PlayerId); } public static bool CheckDoubleTrigger(this PlayerControl killer, PlayerControl target, Action firstAction) { if (FirstTriggerTimer.ContainsKey(killer.PlayerId)) { if (FirstTriggerTarget[killer.PlayerId] != target.PlayerId) { return false; } Logger.Info(((Object)killer).name + " DoDoubleAction", "DoubleTrigger", escapeCRLF: true, 41, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DoubleTrigger.cs"); FirstTriggerTimer.Remove(killer.PlayerId); FirstTriggerTarget.Remove(killer.PlayerId); FirstTriggerAction.Remove(killer.PlayerId); return true; } CheckMurderPatch.TimeSinceLastKill.Remove(killer.PlayerId); FirstTriggerTimer.Add(killer.PlayerId, 1f); FirstTriggerTarget.Add(killer.PlayerId, target.PlayerId); FirstTriggerAction.Add(killer.PlayerId, firstAction); return false; } public static void OnFixedUpdate(PlayerControl player) { if (!player.CanDoubleTrigger()) { return; } if (!GameStates.IsInTask) { FirstTriggerTimer.Clear(); FirstTriggerTarget.Clear(); FirstTriggerAction.Clear(); return; } byte playerId = player.PlayerId; if (FirstTriggerTimer.ContainsKey(playerId)) { FirstTriggerTimer[playerId] -= Time.fixedDeltaTime; if (FirstTriggerTimer[playerId] <= 0f) { Logger.Info(((Object)player).name + " Do single action", "DoubleTrigger", escapeCRLF: true, 72, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DoubleTrigger.cs"); FirstTriggerAction[playerId](); FirstTriggerTimer.Remove(playerId); FirstTriggerTarget.Remove(playerId); FirstTriggerAction.Remove(playerId); } } } } internal class EAC { public static int DeNum = 0; private static List LobbyDeadBodies = new List(); public static Dictionary OriginalRoles = new Dictionary(); public static Dictionary ReportTimes = new Dictionary(); public static void Init() { DeNum = 0; OriginalRoles = new Dictionary(); ReportTimes = new Dictionary(); LobbyDeadBodies = new List(); } public static void WarnHost(int denum = 1) { DeNum += denum; if ((Object)(object)ErrorText.Instance != (Object)null) { ErrorText.Instance.CheatDetected = DeNum > 3; ErrorText.Instance.SBDetected = DeNum > 10; if (ErrorText.Instance.CheatDetected) { ErrorText.Instance.AddError(ErrorText.Instance.SBDetected ? ErrorCode.SBDetected : ErrorCode.CheatDetected); } else { ErrorText.Instance.Clear(); } } } public static bool PlayerControlReceiveRpc(PlayerControl pc, byte callId, MessageReader reader) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Invalid comparison between Unknown and I4 if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (RoleBasisChanger.IsChangeInProgress) { return false; } if ((Object)(object)pc == (Object)null || reader == null) { return false; } try { MessageReader val = MessageReader.Get(reader); RpcCalls val2 = (RpcCalls)callId; if ((int)val2 <= 47) { switch (val2 - 5) { default: { if ((int)val2 != 46) { if ((int)val2 != 47 || !GameStates.IsLobby) { break; } WarnHost(); Report(pc, "CheckMurder in Lobby"); HandleCheat(pc, "CheckMurder in Lobby"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法检查击杀,已驳回", "EAC", escapeCRLF: true, 150, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } Report(pc, "Directly Shapeshift"); MessageWriter val4 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)pc).NetId, (byte)46, (SendOption)1, -1); MessageExtensions.WriteNetObject(val4, (InnerNetObject)(object)pc); val4.Write(false); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val4); HandleCheat(pc, "Directly Shapeshift"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】直接变形,已驳回", "EAC", escapeCRLF: true, 190, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } case 0: if (!GameStates.IsLobby) { WarnHost(); Report(pc, "CheckName out of Lobby"); HandleCheat(pc, "CheckName out of Lobby"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】CheckName out of lobby,已驳回", "EAC", escapeCRLF: true, 53, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 8: { string text = val.ReadString(); if (text.Contains('░') || text.Contains('▄') || text.Contains('█') || text.Contains('▌') || text.Contains('▒') || text.Contains("习近平")) { Report(pc, "非法消息"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送非法消息,已驳回", "EAC", escapeCRLF: true, 86, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; } case 9: WarnHost(); Report(pc, "Bad StartMeeting"); HandleCheat(pc, "Bad StartMeeting"); Logger.Fatal($"非法设置玩家【{pc.GetClientId()}:{pc.GetRealName()}】的游戏名称,已驳回", "EAC", escapeCRLF: true, 95, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; case 6: { byte item = val.ReadByte(); if (!GameStates.IsInGame) { if (!LobbyDeadBodies.Contains(item)) { WarnHost(); Report(pc, "Report body out of game A"); HandleCheat(pc, "Report body out of game A"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非游戏内开会,已驳回", "EAC", escapeCRLF: true, 106, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } Report(pc, "Try to Report body out of game B (May be false)"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】尝试举报可能被非法击杀的尸体,已驳回", "EAC", escapeCRLF: true, 112, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } if (ReportTimes.TryGetValue(pc.PlayerId, out var value) && value > 14) { WarnHost(); Report(pc, "Spam report bodies A"); HandleCheat(pc, "Spam report bodies A"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】刷报告尸体满14次,已驳回", "EAC", escapeCRLF: true, 122, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; } case 2: if (!GameStates.IsLobby) { WarnHost(); Report(pc, "CheckColor out of Lobby"); HandleCheat(pc, "CheckColor out of Lobby"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】check color out of lobby,已驳回", "EAC", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 3: Report(pc, "Directly SetColor"); HandleCheat(pc, "Directly SetColor"); Logger.Fatal($"Directly SetColor【{pc.GetClientId()}:{pc.GetRealName()}】已驳回", "EAC", escapeCRLF: true, 142, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; case 7: { PlayerControl val3 = MessageExtensions.ReadNetObject(val); if (GameStates.IsLobby) { Report(pc, "Directly Murder Player In Lobby"); HandleCheat(pc, "Directly Murder Player In Lobby"); if ((Object)(object)val3 != (Object)null && !LobbyDeadBodies.Contains(val3.PlayerId)) { LobbyDeadBodies.Add(val3.PlayerId); } Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】大厅直接击杀,已驳回", "EAC", escapeCRLF: true, 165, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } Report(pc, "Directly Murder Player"); HandleCheat(pc, "Directly Murder Player"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】直接击杀,已驳回", "EAC", escapeCRLF: true, 170, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } case 11: Report(pc, "Directly Send ChatNote"); HandleCheat(pc, "Directly Send ChatNote"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】直接Send ChatNote,已驳回", "EAC", escapeCRLF: true, 211, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; case 1: case 4: case 5: case 10: break; } } else if ((int)val2 != 55) { if ((int)val2 == 63 || (int)val2 == 65) { string text2 = "Directly Phantom Rpcs " + ((object)(RpcCalls)(ref val2)).ToString(); Report(pc, text2); MessageWriter val5 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)pc).NetId, (byte)65, (SendOption)1, -1); val5.Write(false); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val5); HandleCheat(pc, text2); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()} {text2},已驳回", "EAC", escapeCRLF: true, 204, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } } else if (GameStates.IsLobby) { Report(pc, "Lobby Check Shapeshift"); HandleCheat(pc, "Lobby Check Shapeshift"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】大厅直接变形,已驳回", "EAC", escapeCRLF: true, 177, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } switch (callId) { case 101: try { string value2 = val.ReadString(); string value3 = val.ReadString(); val.ReadInt32(); if (!string.IsNullOrEmpty(value2) || !string.IsNullOrEmpty(value3)) { Report(pc, "Aum Chat RPC"); HandleCheat(pc, "Aum Chat RPC"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送AUM聊天,已驳回", "EAC", escapeCRLF: true, 229, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } } catch { } break; case 85: try { if (val.ReadByte() == pc.PlayerId) { Report(pc, "Aum RPC"); HandleCheat(pc, "Aum RPC"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送AUM RPC,已驳回", "EAC", escapeCRLF: true, 247, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } } catch { } break; case 164: if (val.BytesRemaining == 0) { Report(pc, "Sicko RPC"); HandleCheat(pc, "Sicko RPC"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送Sicko RPC,已驳回", "EAC", escapeCRLF: true, 261, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 7: case 8: if (!GameStates.IsLobby) { WarnHost(); Report(pc, "非法设置颜色"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法设置颜色,已驳回", "EAC", escapeCRLF: true, 271, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 5: val.ReadString(); if (GameStates.IsInGame) { WarnHost(); Report(pc, "非法设置游戏名称"); Logger.Fatal($"非法修改玩家【{pc.GetClientId()}:{pc.GetRealName()}】的游戏名称,已驳回", "EAC", escapeCRLF: true, 281, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 47: if (GameStates.IsLobby) { WarnHost(); Report(pc, "非法击杀"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】非法击杀,已驳回", "EAC", escapeCRLF: true, 290, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 38: if (GameStates.IsInGame) { WarnHost(); Report(pc, "Set level in game"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】游戏内改等级,已驳回", "EAC", escapeCRLF: true, 299, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; case 39: case 40: case 41: case 42: case 43: if (GameStates.IsInGame) { WarnHost(); Report(pc, "Change skin in game"); Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】游戏内改皮肤,已驳回", "EAC", escapeCRLF: true, 326, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } break; } } catch (Exception ex) { Logger.Exception(ex, "EAC", 334, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } WarnHost(-1); return false; } public static void LogAllRoles() { PlayerControl[] array = Main.AllPlayerControls.ToArray(); foreach (PlayerControl val in array) { try { OriginalRoles.Add(val.PlayerId, val.GetCustomRole()); } catch (Exception ex) { Logger.Fatal(ex.ToString(), "EAC.LogAllRoles", escapeCRLF: true, 351, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } } } public static bool RpcUpdateSystemCheck(PlayerControl player, SystemTypes systemType, byte amount) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Invalid comparison between Unknown and I4 //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Invalid comparison between Unknown and I4 //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Invalid comparison between Unknown and I4 //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Invalid comparison between Unknown and I4 //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Invalid comparison between Unknown and I4 //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 byte activeMapId = Utils.GetActiveMapId(); Logger.Info("Check sabotage RPC, PlayerName: " + player.GetNameWithRole() + ", SabotageType: " + ((object)(SystemTypes)(ref systemType)).ToString() + ", amount: " + amount, "EAC", escapeCRLF: true, 359, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if ((Object)(object)player == (Object)null) { Logger.Warn("PlayerControl is null", "EAC RpcUpdateSystemCheck", escapeCRLF: true, 364, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } if ((int)systemType != 17) { if ((int)systemType == 8) { if ((activeMapId == 0 || activeMapId == 1 || activeMapId == 3) && (amount == 64 || amount == 65)) { goto IL_01b3; } } else if ((int)systemType == 14) { if (amount == 0) { if (activeMapId != 1 && activeMapId != 5) { goto IL_01b3; } } else if ((amount == 64 || amount == 65 || amount == 32 || amount == 33 || amount == 16 || amount == 17) && (activeMapId == 1 || activeMapId == 5)) { goto IL_01b3; } } else if ((int)systemType == 7) { if (activeMapId != 5 && amount < 5) { goto IL_01b3; } } else if ((int)systemType == 21) { if (activeMapId == 2 && (amount == 64 || amount == 65 || amount == 32 || amount == 33)) { goto IL_01b3; } } else if ((int)systemType == 3) { if (activeMapId != 2 && activeMapId != 4 && (amount == 64 || amount == 65 || amount == 32 || amount == 33)) { goto IL_01b3; } } else if ((int)systemType == 58) { if (activeMapId == 4 && (amount == 64 || amount == 65 || amount == 16 || amount == 17 || amount == 32 || amount == 33)) { goto IL_01b3; } } else if ((int)systemType != 57) { goto IL_01b3; } WarnHost(); Report(player, "Bad Sabotage C : Hack send RPC"); HandleCheat(player, "Bad Sabotage C"); Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage C,已驳回", "EAC", escapeCRLF: true, 444, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } goto IL_01b3; IL_01b3: if ((GameStates.IsMeeting && (int)MeetingHud.Instance.state != 0) || GameStates.IsExilling) { WarnHost(); Report(player, "Bad Sabotage D : In Meeting"); Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】Bad Sabotage D,已驳回", "EAC", escapeCRLF: true, 432, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } return false; } public static bool RpcReportDeadBodyCheck(PlayerControl player, NetworkedPlayerInfo target) { if (!ReportTimes.ContainsKey(player.PlayerId)) { ReportTimes.Add(player.PlayerId, 0); } if ((Object)(object)target == (Object)null || !Main.OverDeadPlayerList.Contains(target.PlayerId)) { ReportTimes[player.PlayerId]++; } if (!GameStates.IsInGame) { WarnHost(); Report(player, "Report body out of game"); HandleCheat(player, "Report body out of game"); Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】非游戏内开会,已驳回", "EAC", escapeCRLF: true, 467, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } if (ReportTimes[player.PlayerId] >= 14) { WarnHost(); Report(player, "Spam report bodies"); HandleCheat(player, "Spam report bodies"); Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】刷报告尸体满14次,已驳回", "EAC", escapeCRLF: true, 478, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } if (GameStates.IsMeeting) { Logger.Info($"玩家【{player.GetClientId()}:{player.GetRealName()}】在会议期间开会,已驳回", "EAC", escapeCRLF: true, 484, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } return false; } public static bool PlayerPhysicsRpcCheck(PlayerPhysics __instance, byte callId, MessageReader reader) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Invalid comparison between Unknown and I4 //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Invalid comparison between Unknown and I4 //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Invalid comparison between Unknown and I4 //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Invalid comparison between Unknown and I4 if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } RpcCalls val = (RpcCalls)callId; MessageReader val2 = MessageReader.Get(reader); PlayerControl myPlayer = __instance.myPlayer; if (!Object.op_Implicit((Object)(object)myPlayer)) { Logger.Warn("Received Physics RPC without a player", "EAC_PlayerPhysics", escapeCRLF: true, 508, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } if (GameStates.IsLobby && (int)val != 49 && (int)val != 50) { WarnHost(); Report(myPlayer, $"Physics {val} in lobby (can be spoofed by others)"); HandleCheat(myPlayer, $"Physics {val} in lobby (can be spoofed by others)"); Logger.Fatal($"【{myPlayer.GetClientId()}:{myPlayer.GetRealName()}】 attempted to {val} in lobby.", "EAC_physics", escapeCRLF: true, 517, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } if ((int)val <= 31) { if (val - 19 > 1) { if ((int)val == 31) { if (!hasLadder(val2.ReadPackedInt32())) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { WarnHost(); Report(myPlayer, "climb null ladder (can be spoofed by others)"); HandleCheat(myPlayer, "climb null ladder (can be spoofed by others)"); Logger.Fatal($"【{myPlayer.GetClientId()}:{myPlayer.GetRealName()}】 attempted to climb a unexisting ladder.", "EAC_physics", escapeCRLF: true, 596, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } return true; } if (((InnerNetObject)myPlayer).AmOwner) { Logger.Fatal("Got climb ladder for my self, this is impossible", "EAC_physics", escapeCRLF: true, 602, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } } } else { int num = val2.ReadPackedInt32(); if (!hasVent(num)) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { WarnHost(); Report(myPlayer, "Vent null vent (can be spoofed by others)"); HandleCheat(myPlayer, "Vent null vent (can be spoofed by others)"); Logger.Fatal($"【{myPlayer.GetClientId()}:{myPlayer.GetRealName()}】 attempted to enter a unexisting vent. {num}", "EAC_physics", escapeCRLF: true, 533, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } else { Logger.Warn($"【{myPlayer.GetClientId()}:{myPlayer.GetRealName()}】 attempted to enter a unexisting vent. {num}", "EAC_physics", escapeCRLF: true, 538, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); if ((int)val == 20) { myPlayer.Visible = true; myPlayer.inVent = false; myPlayer.moveable = true; myPlayer.NetTransform.SetPaused(false); } } return true; } } } else if ((int)val != 34) { if ((int)val == 49 && ((InnerNetObject)myPlayer).AmOwner) { Logger.Fatal("Got pet pet for my self, this is impossible", "EAC_physics", escapeCRLF: true, 610, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return true; } } else { WarnHost(); Report(myPlayer, "Got boot from vent from clients, can be spoofed"); HandleCheat(myPlayer, "Got boot from vent from clients, can be spoofed"); Logger.Fatal($"【{myPlayer.GetClientId()}:{myPlayer.GetRealName()}】 sent boot from vent, can be spoofed.", "EAC_physics", escapeCRLF: true, 584, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); } return false; static bool hasLadder(int ladderId) { return ((IEnumerable)ShipStatus.Instance.Ladders).Any((Ladder l) => l.Id == ladderId); } static bool hasVent(int ventId) { return ((IEnumerable)ShipStatus.Instance.AllVents).Any((Vent v) => v.Id == ventId); } } public static void Report(PlayerControl pc, string reason) { if ((Object)(object)pc == (Object)null) { Logger.Warn("Report PlayerControl is null", "EAC Report", escapeCRLF: true, 625, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return; } string text = $"{pc.GetClientId()}|{pc.FriendCode}|{pc.Data.PlayerName}|{pc.GetClient().GetHashedPuid()}|{reason}"; Logger.Fatal("EAC报告:" + text, "EAC Cloud", escapeCRLF: true, 631, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); if (Options.CheatResponses.GetInt() != 5) { string @string = Translator.GetString("Message.NoticeByEAC"); object obj; if (pc == null) { obj = null; } else { NetworkedPlayerInfo data = pc.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.SendInGame(string.Format(@string, (string?)obj + " | " + pc.GetClient().GetHashedPuid(), reason)); } } public static void HandleCheat(PlayerControl pc, string text) { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pc == (Object)null) { Logger.Warn("Target PlayerControl is null", "EAC HandleCheat", escapeCRLF: true, 639, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); return; } switch (Options.CheatResponses.GetInt()) { case 0: { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(pc.GetClientId(), true); string string5 = Translator.GetString("Message.BannedByEAC"); PlayerControl obj5 = pc; object arg5; if (obj5 == null) { arg5 = null; } else { NetworkedPlayerInfo data5 = obj5.Data; arg5 = ((data5 != null) ? data5.PlayerName : null); } string text4 = string.Format(string5, arg5, text); Logger.Warn(text4, "EAC", escapeCRLF: true, 648, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); Logger.SendInGame(text4); break; } case 1: { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(pc.GetClientId(), false); string string2 = Translator.GetString("Message.KickedByEAC"); PlayerControl obj2 = pc; object arg2; if (obj2 == null) { arg2 = null; } else { NetworkedPlayerInfo data2 = obj2.Data; arg2 = ((data2 != null) ? data2.PlayerName : null); } string text3 = string.Format(string2, arg2, text); Logger.Warn(text3, "EAC", escapeCRLF: true, 654, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); Logger.SendInGame(text3); break; } case 2: { string string3 = Translator.GetString("Message.NoticeByEAC"); PlayerControl obj3 = pc; object arg3; if (obj3 == null) { arg3 = null; } else { NetworkedPlayerInfo data3 = obj3.Data; arg3 = ((data3 != null) ? data3.PlayerName : null); } Utils.SendMessage(string.Format(string3, arg3, text), PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), Translator.GetString("MessageFromEAC"))); break; } case 3: { PlayerControl[] array = Main.AllPlayerControls.Where(delegate(PlayerControl x) { byte playerId = x.PlayerId; PlayerControl obj6 = pc; byte? obj7; if (obj6 == null) { obj7 = null; } else { NetworkedPlayerInfo data6 = obj6.Data; obj7 = ((data6 != null) ? new byte?(data6.PlayerId) : null); } return playerId != obj7; }).ToArray(); for (int i = 0; i < array.Length; i++) { _ = array[i]; string string4 = Translator.GetString("Message.NoticeByEAC"); PlayerControl obj4 = pc; object arg4; if (obj4 == null) { arg4 = null; } else { NetworkedPlayerInfo data4 = obj4.Data; arg4 = ((data4 != null) ? data4.PlayerName : null); } Utils.SendMessage(string.Format(string4, arg4, text), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), Translator.GetString("MessageFromEAC"))); } break; } case 4: { if (!BanManager.TempBanWhiteList.Contains(pc.GetClient().GetHashedPuid())) { BanManager.TempBanWhiteList.Add(pc.GetClient().GetHashedPuid()); } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(pc.GetClientId(), true); string @string = Translator.GetString("Message.TempBannedByEAC"); PlayerControl obj = pc; object arg; if (obj == null) { arg = null; } else { NetworkedPlayerInfo data = obj.Data; arg = ((data != null) ? data.PlayerName : null); } string text2 = string.Format(@string, arg, text); Logger.Warn(text2, "EAC", escapeCRLF: true, 669, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); Logger.SendInGame(text2); break; } case 5: Logger.Info("No Handle Cheat", "MalumMenu_On_Top", escapeCRLF: true, 673, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\EAC.cs"); break; } } } public class ErrorText : MonoBehaviour { public class ErrorData { public readonly ErrorCode Code; public readonly int ErrorType1; public readonly int ErrorType2; public readonly int ErrorLevel; public float Timer { get; private set; } public string Message => Translator.GetString(ToString()); public ErrorData(ErrorCode code) { Code = code; ErrorType1 = (int)code / 10000; ErrorType2 = (int)code / 10 - ErrorType1 * 1000; ErrorLevel = (int)(code - (int)code / 10 * 10); Timer = 0f; } public override string ToString() { return $"ERR-{ErrorType1:000}-{ErrorType2:000}-{ErrorLevel:0}"; } public void IncreaseTimer() { Timer += Time.deltaTime; } } private static ErrorText _instance; public TextMeshPro Text; public Camera Camera; public List AllErrors = new List(); public Vector3 TextOffset = new Vector3(0f, 0.3f, -1000f); public bool HnSFlag; public bool CheatDetected; public bool SBDetected; public static ErrorText Instance => _instance; private void Awake() { if ((Object)(object)_instance != (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _instance = this; Object.DontDestroyOnLoad((Object)(object)this); } public static void Create(TextMeshPro baseText) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) TextMeshPro val = Object.Instantiate(baseText); ErrorText errorText = ((Component)val).gameObject.AddComponent(); errorText.Text = val; ((Object)errorText).name = "ErrorText"; ((Behaviour)val).enabled = false; ((TMP_Text)val).text = "NO ERROR"; ((Graphic)val).color = Color.red; ((TMP_Text)val).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)val).alignment = (TextAlignmentOptions)258; } public void Update() { ErrorData[] array = AllErrors.ToArray(); for (int i = 0; i < array.Length; i++) { array[i].IncreaseTimer(); } IEnumerable ToRemove = AllErrors.Where((ErrorData err) => err.ErrorLevel <= 1 && 30f < err.Timer); if (ToRemove.Any()) { AllErrors.RemoveAll((ErrorData err) => ToRemove.Contains(err)); UpdateText(); if (HnSFlag) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public void LateUpdate() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (((Behaviour)Text).enabled) { if ((Object)(object)Camera == (Object)null) { Camera = ((!DestroyableSingleton.InstanceExists) ? Camera.main : ((Component)DestroyableSingleton.Instance.PlayerCam).GetComponent()); } if ((Object)(object)Camera != (Object)null) { ((Component)this).transform.position = AspectPosition.ComputeWorldPosition(Camera, (EdgeAlignments)8, TextOffset); } } } public void AddError(ErrorCode code) { ErrorData errorData = new ErrorData(code); if (0 < errorData.ErrorLevel) { Logger.Error($"エラー発生: {errorData}: {errorData.Message}", "ErrorText", escapeCRLF: true, 80, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ErrorText.cs"); } if (!AllErrors.Any((ErrorData e) => e.Code == code)) { AllErrors.Add(errorData); } UpdateText(); } public void UpdateText() { string text = ""; int num = 0; ErrorData[] array = AllErrors.ToArray(); foreach (ErrorData errorData in array) { text += $"{errorData}: {errorData.Message}\n"; if (num < errorData.ErrorLevel) { num = errorData.ErrorLevel; } } if (num == 0) { ((Behaviour)Text).enabled = false; } else { if (!HnSFlag) { text += Translator.GetString($"ErrorLevel{num}"); } if (CheatDetected) { text = (SBDetected ? Translator.GetString("EAC.CheatDetected.HighLevel") : Translator.GetString("EAC.CheatDetected.LowLevel")); } ((Behaviour)Text).enabled = true; } if (GameStates.IsInGame && num != 3 && !CheatDetected) { text = text + "\n" + Translator.GetString("TerminateCommand") + ": Shift+L+Enter"; } ((TMP_Text)Text).text = text; } public void Clear() { AllErrors.RemoveAll((ErrorData err) => err.ErrorLevel != 3); UpdateText(); } } public enum ErrorCode { Main_DictionaryError = 10003, UnsupportedVersion = 20001, NoError = 0, TestError0 = 9000, TestError1 = 9101, TestError2 = 9202, TestError3 = 9303, HnsUnload = 8041, CheatDetected = 6662, SBDetected = 6661 } internal static class ExtendedPlayerControl { private static readonly LogHandler logger = Logger.Handler("KnowRoleTarget"); public const MurderResultFlags ResultFlags = 1; public static void SetRole(this PlayerControl player, RoleTypes role, bool canOverride = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)player).StartCoroutine(player.CoSetRole(role, canOverride)); } public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role) { if (role < CustomRoles.NotAssigned) { Main.PlayerStates[player.PlayerId].SetMainRole(role); } else if (role >= CustomRoles.NotAssigned) { if (Cleanser.CantGetAddon() && player.Is(CustomRoles.Cleansed)) { return; } if (role == CustomRoles.Cleansed) { Main.PlayerStates[player.PlayerId].SetSubRole(role, AllReplace: false, player); } else { Main.PlayerStates[player.PlayerId].SetSubRole(role); } } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)105, (SendOption)1, -1); val.Write(player.PlayerId); val.WritePacked((int)role); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSetCustomRole(byte PlayerId, CustomRoles role) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)105, (SendOption)1, -1); val.Write(PlayerId); val.WritePacked((int)role); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcExile(this PlayerControl player) { RPC.ExileAsync(player); } public static ClientData GetClient(this PlayerControl player) { try { return ((IEnumerable)((InnerNetClient)AmongUsClient.Instance).allClients.ToArray()).FirstOrDefault((Func)((ClientData cd) => cd.Character.PlayerId == player.PlayerId)); } catch { return null; } } public static int GetClientId(this PlayerControl player) { if ((Object)(object)player == (Object)null) { return -1; } ClientData client = player.GetClient(); if (client != null) { return client.Id; } return -1; } public static CustomRoles GetCustomRole(this NetworkedPlayerInfo player) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player.Object == (Object)null)) { return player.Object.GetCustomRole(); } return CustomRoles.Crewmate; } public static CustomRoles GetCustomRole(this PlayerControl player) { if ((Object)(object)player == (Object)null) { MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); Logger.Warn(string.Concat(str2: method.Name, str0: method.DeclaringType.FullName, str1: ".", str3: " tried to retrieve CustomRole, but the target was null"), "GetCustomRole", escapeCRLF: true, 93, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); return CustomRoles.Crewmate; } if (!Main.PlayerStates.TryGetValue(player.PlayerId, out var value)) { return CustomRoles.Crewmate; } return value.MainRole; } public static List GetCustomSubRoles(this PlayerControl player) { if ((Object)(object)player == (Object)null) { MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); Logger.Warn(string.Concat(str2: method.Name, str0: method.DeclaringType.FullName, str1: ".", str3: " tried to get CustomSubRole, but the target was null"), "GetCustomRole", escapeCRLF: true, 107, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); return new List(1) { CustomRoles.NotAssigned }; } if (!Main.PlayerStates.TryGetValue(player.PlayerId, out var value)) { return new List(1) { CustomRoles.NotAssigned }; } return value.SubRoles; } public static CountTypes GetCountTypes(this PlayerControl player) { if ((Object)(object)player == (Object)null) { MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); Logger.Warn(string.Concat(str2: method.Name, str0: method.DeclaringType.FullName, str1: ".", str3: " tried to get CountTypes, but the target was null"), "GetCountTypes", escapeCRLF: true, 120, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); return CountTypes.None; } if (!Main.PlayerStates.TryGetValue(player.PlayerId, out var value)) { return CountTypes.None; } return value.countTypes; } public static void RpcSetNameEx(this PlayerControl player, string name) { PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { Main.LastNotifyNames[(player.PlayerId, val.PlayerId)] = name; } HudManagerPatch.LastSetNameDesyncCount++; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(13, 2); defaultInterpolatedStringHandler.AppendLiteral("Set:"); object value; if (player == null) { value = null; } else { NetworkedPlayerInfo data = player.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(name); defaultInterpolatedStringHandler.AppendLiteral(" for All"); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "RpcSetNameEx", escapeCRLF: true, 134, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); player.RpcSetName(name); } public static void RpcSetNamePrivate(this PlayerControl player, string name, PlayerControl seer = null, bool force = false) { if ((Object)(object)player == (Object)null || name == null || !((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if ((Object)(object)seer == (Object)null) { seer = player; } if (force || !(Main.LastNotifyNames[(player.PlayerId, seer.PlayerId)] == name)) { Main.LastNotifyNames[(player.PlayerId, seer.PlayerId)] = name; HudManagerPatch.LastSetNameDesyncCount++; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(10, 3); defaultInterpolatedStringHandler.AppendLiteral("Set:"); object value; if (player == null) { value = null; } else { NetworkedPlayerInfo data = player.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(name); defaultInterpolatedStringHandler.AppendLiteral(" for "); defaultInterpolatedStringHandler.AppendFormatted(seer.GetNameWithRole().RemoveHtmlTags()); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "RpcSetNamePrivate", escapeCRLF: true, 152, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); if (!((Object)(object)seer == (Object)null) && !((Object)(object)player == (Object)null)) { int clientId = seer.GetClientId(); CustomRpcSender customRpcSender = CustomRpcSender.Create("SetNamePrivate", (SendOption)0); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 6, clientId).Write(((InnerNetObject)seer.Data).NetId).Write(name) .EndRpc(); customRpcSender.SendMessage(); } } } public static void RpcEnterVentDesync(this PlayerPhysics physics, int ventId, PlayerControl seer) { if (!((Object)(object)physics == (Object)null)) { int clientId = seer.GetClientId(); if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { ((MonoBehaviour)physics).StopAllCoroutines(); ((MonoBehaviour)physics).StartCoroutine(physics.CoEnterVent(ventId)); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)physics).NetId, (byte)19, (SendOption)1, seer.GetClientId()); val.WritePacked(ventId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } } public static void RpcExitVentDesync(this PlayerPhysics physics, int ventId, PlayerControl seer) { if (!((Object)(object)physics == (Object)null)) { int clientId = seer.GetClientId(); if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { ((MonoBehaviour)physics).StopAllCoroutines(); ((MonoBehaviour)physics).StartCoroutine(physics.CoExitVent(ventId)); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)physics).NetId, (byte)20, (SendOption)1, seer.GetClientId()); val.WritePacked(ventId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } } public static void RpcBootFromVentDesync(this PlayerPhysics physics, int ventId, PlayerControl seer) { if (!((Object)(object)physics == (Object)null)) { int clientId = seer.GetClientId(); if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { physics.BootFromVent(ventId); return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)physics).NetId, (byte)34, (SendOption)1, seer.GetClientId()); val.WritePacked(ventId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSetRoleDesync(this PlayerControl player, RoleTypes role, bool canOverride, int clientId) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected I4, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { player.SetRole(role, canOverride); return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)44, (SendOption)1, clientId); val.Write((ushort)(int)role); val.Write(canOverride); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcGuardAndKill(this PlayerControl killer, PlayerControl target = null, bool forObserver = false, bool fromSetKCD = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); string name = method.Name; string fullName = method.DeclaringType.FullName; Logger.Warn("Modded non-host client activated RpcGuardAndKill from " + fullName + "." + name, "RpcGuardAndKill", escapeCRLF: true, 231, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); return; } if ((Object)(object)target == (Object)null) { target = killer; } if (Observer.HasEnabled && !forObserver && !MeetingStates.FirstMeeting) { Observer.ActivateGuardAnimation(killer.PlayerId, target); } if (((InnerNetObject)killer).AmOwner) { killer.MurderPlayer(target, (MurderResultFlags)4); } if (!((InnerNetObject)(object)killer).OwnedByHost()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)killer).NetId, (byte)12, (SendOption)1, killer.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(4); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } if (!fromSetKCD) { killer.SetKillTimer(half: true); } } public static void SetKillCooldownV2(this PlayerControl player, float time = -1f) { if (!((Object)(object)player == (Object)null) && player.CanUseKillButton()) { player.SetKillTimer(half: false, time); if (time >= 0f) { Main.AllPlayerKillCooldown[player.PlayerId] = time * 2f; } else { Main.AllPlayerKillCooldown[player.PlayerId] *= 2f; } player.SyncSettings(); player.RpcGuardAndKill(null, forObserver: false, fromSetKCD: true); player.ResetKillCooldown(); } } public static void SetKillCooldown(this PlayerControl player, float time = -1f, PlayerControl target = null, bool forceAnime = false) { if ((Object)(object)player == (Object)null || !player.HasImpKillButton(considerVanillaShift: true) || (player.HasImpKillButton() && !player.CanUseKillButton())) { return; } player.SetKillTimer(half: false, time); if ((Object)(object)target == (Object)null) { target = player; } if (time >= 0f) { Main.AllPlayerKillCooldown[player.PlayerId] = time * 2f; } else { Main.AllPlayerKillCooldown[player.PlayerId] *= 2f; } if (player.GetRoleClass() is Glitch glitch) { glitch.LastKill = Utils.GetTimeStamp() + ((int)(time / 2f) - Glitch.KillCooldown.GetInt()); glitch.KCDTimer = (int)(time / 2f); } else if (forceAnime || !player.IsModClient() || !Options.DisableShieldAnimations.GetBool()) { player.SyncSettings(); player.RpcGuardAndKill(target, forObserver: false, fromSetKCD: true); } else { time = Main.AllPlayerKillCooldown[player.PlayerId] / 2f; if (((InnerNetObject)player).AmOwner) { PlayerControl.LocalPlayer.SetKillTimer(time); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)109, (SendOption)1, player.GetClientId()); val.Write(time); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } if (Observer.HasEnabled) { Observer.ActivateGuardAnimation(target.PlayerId, target); } } player.ResetKillCooldown(); } public static void SetKillCooldownV3(this PlayerControl player, float time = -1f, PlayerControl target = null, bool forceAnime = false) { if ((Object)(object)player == (Object)null || !player.CanUseKillButton()) { return; } player.SetKillTimer(half: false, time); if ((Object)(object)target == (Object)null) { target = player; } if (time >= 0f) { Main.AllPlayerKillCooldown[player.PlayerId] = time * 2f; } else { Main.AllPlayerKillCooldown[player.PlayerId] *= 2f; } if (forceAnime || !player.IsModClient() || !Options.DisableShieldAnimations.GetBool()) { player.SyncSettings(); player.RpcGuardAndKill(target, forObserver: false, fromSetKCD: true); } else { time = Main.AllPlayerKillCooldown[player.PlayerId] / 2f; if (((InnerNetObject)player).AmOwner) { PlayerControl.LocalPlayer.SetKillTimer(time); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)109, (SendOption)1, player.GetClientId()); val.Write(time); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } if (Observer.HasEnabled) { Observer.ActivateGuardAnimation(target.PlayerId, target); } } player.ResetKillCooldown(); } public static void RpcSpecificShapeshift(this PlayerControl player, PlayerControl target, bool shouldAnimate) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (((InnerNetObject)(object)player).OwnedByHost()) { player.Shapeshift(target, shouldAnimate); return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)46, (SendOption)1, player.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(shouldAnimate); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSpecificRejectShapeshift(this PlayerControl player, PlayerControl target, bool shouldAnimate) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if ((Object)(object)val != (Object)(object)player) { MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)56, (SendOption)1, val.GetClientId()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); } else { player.RpcSpecificShapeshift(target, shouldAnimate); } } } public static void RpcSetSpecificScanner(this PlayerControl target, PlayerControl seer, bool IsActive) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { PlayerControl localPlayer = PlayerControl.LocalPlayer; byte b2 = (localPlayer.scannerCount += 1); byte b3 = b2; MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)target).NetId, (byte)15, (SendOption)1, seer.GetClientId()); val.Write(IsActive); val.Write(b3); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSpecificVanish(this PlayerControl player, PlayerControl seer) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)63, (SendOption)0, seer.GetClientId()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSpecificAppear(this PlayerControl player, PlayerControl seer, bool shouldAnimate) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)65, (SendOption)0, seer.GetClientId()); val.Write(shouldAnimate); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcSpecificMurderPlayer(this PlayerControl killer, PlayerControl target, PlayerControl seer) { if (((InnerNetObject)seer).AmOwner) { killer.MurderPlayer(target, (MurderResultFlags)1); return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)killer).NetId, (byte)12, (SendOption)0, seer.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(1); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } [Obsolete] public static void RpcSpecificProtectPlayer(this PlayerControl killer, PlayerControl target = null, int colorId = 0) { if (((InnerNetClient)AmongUsClient.Instance).AmClient) { killer.ProtectPlayer(target, colorId); } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)killer).NetId, (byte)45, (SendOption)1, killer.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(colorId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void RpcResetAbilityCooldown(this PlayerControl target) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } Logger.Info($"Ability cooldown reset: {((Object)target).name}({target.PlayerId})", "RpcResetAbilityCooldown", escapeCRLF: true, 435, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); if (target.GetRoleClass() is Glitch glitch) { glitch.LastHack = Utils.GetTimeStamp(); glitch.LastMimic = Utils.GetTimeStamp(); glitch.MimicCDTimer = 10; glitch.HackCDTimer = 10; return; } if ((Object)(object)PlayerControl.LocalPlayer == (Object)(object)target && !target.GetCustomRole().IsGhostRole() && !target.IsAnySubRole((CustomRoles x) => x.IsGhostRole())) { PlayerControl.LocalPlayer.Data.Role.SetCooldown(); return; } try { if ((Object)(object)PlayerControl.LocalPlayer == (Object)(object)target) { target.MarkDirtySettings(); } } catch (Exception value) { Logger.Warn($"{value}", "RpcResetAbilityCooldown.HostAbility", escapeCRLF: true, 452, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)target).NetId, (byte)45, (SendOption)0, target.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(0); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void RpcDesyncUpdateSystem(this PlayerControl target, SystemTypes systemType, int amount) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, but got Unknown MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)ShipStatus.Instance).NetId, (byte)35, (SendOption)1, target.GetClientId()); val.Write((byte)(int)systemType); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write((byte)amount); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static bool OwnedByHost(this InnerNetObject innerObject) { return innerObject.OwnerId == ((InnerNetClient)AmongUsClient.Instance).HostId; } public static void MarkDirtySettings(this PlayerControl player) { PlayerGameOptionsSender.SetDirty(player.PlayerId); } public static void SyncSettings(this PlayerControl player) { PlayerGameOptionsSender.SetDirty(player.PlayerId); GameOptionsSender.SendAllGameOptions(); } public static TaskState GetPlayerTaskState(this PlayerControl player) { return Main.PlayerStates[player.PlayerId].TaskState; } public static string GetDisplayRoleAndSubName(this PlayerControl seer, PlayerControl target, bool notShowAddOns = false) { return Utils.GetDisplayRoleAndSubName(seer.PlayerId, target.PlayerId, notShowAddOns); } public static string GetSubRoleName(this PlayerControl player, bool forUser = false) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return string.Empty; } CustomRoles[] array = Main.PlayerStates[player.PlayerId].SubRoles.ToArray(); if (array.Length == 0) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); CustomRoles[] array2 = array; foreach (CustomRoles customRoles in array2) { if (customRoles != CustomRoles.NotAssigned) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(0, 2, stringBuilder2); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.white), " + ")); handler.AppendFormatted(Utils.GetRoleName(customRoles, forUser)); stringBuilder2.Append(ref handler); } } return stringBuilder.ToString(); } public static string GetAllRoleName(this PlayerControl player, bool forUser = true) { if (!Object.op_Implicit((Object)(object)player)) { return null; } return Utils.GetRoleName(player.GetCustomRole(), forUser) + player.GetSubRoleName(forUser); } public static string GetNameWithRole(this PlayerControl player, bool forUser = false) { if (!forUser) { return player.GetRealName(); } object obj; if (player == null) { obj = null; } else { NetworkedPlayerInfo data = player.Data; obj = ((data != null) ? data.PlayerName : null); } return (string?)obj + ((GameStates.IsInGame && Options.CurrentGameMode != CustomGameMode.FFA) ? ("(" + player?.GetAllRoleName(forUser) + ")") : string.Empty); } public static string GetRoleColorCode(this PlayerControl player) { return Utils.GetRoleColorCode(player.GetCustomRole()); } public static Color GetRoleColor(this PlayerControl player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return Utils.GetRoleColor(player.GetCustomRole()); } public static void ResetPlayerCam(this PlayerControl pc, float delay = 0f) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pc == (Object)null || !((InnerNetClient)AmongUsClient.Instance).AmHost || ((InnerNetObject)pc).AmOwner || pc.IsModClient()) { return; } SystemTypes systemtypes = Utils.GetCriticalSabotageSystemType(); new LateTask(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) pc.RpcDesyncUpdateSystem(systemtypes, 128); }, 0f + delay, "Reactor Desync"); new LateTask(delegate { pc.RpcSpecificMurderPlayer(pc, pc); }, 0.2f + delay, "Murder To Reset Cam"); new LateTask(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) pc.RpcDesyncUpdateSystem(systemtypes, 16); if (GameStates.AirshipIsActive) { pc.RpcDesyncUpdateSystem(systemtypes, 17); } }, 0.4f + delay, "Fix Desync Reactor"); } public static void ReactorFlash(this PlayerControl pc, float delay = 0f) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pc == (Object)null) { return; } SystemTypes systemtypes = Utils.GetCriticalSabotageSystemType(); float @float = Options.KillFlashDuration.GetFloat(); pc.RpcDesyncUpdateSystem(systemtypes, 128); new LateTask(delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) pc.RpcDesyncUpdateSystem(systemtypes, 16); if (GameStates.AirshipIsActive) { pc.RpcDesyncUpdateSystem(systemtypes, 17); } }, @float + delay, "Fix Desync Reactor"); } public static string GetRealName(this PlayerControl player, bool isMeeting = false, bool clientData = false) { if (clientData) { ClientData client = player.GetClient(); if (client != null) { if (Main.AllClientRealNames.TryGetValue(client.Id, out var value)) { return value; } return player.GetClient().PlayerName; } } if (!isMeeting && !((Object)(object)player == (Object)null)) { if (player == null) { return null; } return ((Object)player).name; } if (player == null) { return null; } NetworkedPlayerInfo data = player.Data; if (data == null) { return null; } return data.PlayerName; } public static bool CanUseKillButton(this PlayerControl pc) { if (GameStates.IsLobby) { return false; } if (!pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) { return false; } if (DollMaster.IsDoll(pc.PlayerId)) { return false; } if (pc.Is(CustomRoles.Killer) || Mastermind.PlayerIsManipulated(pc)) { return true; } RoleBase roleClass = pc.GetRoleClass(); if (roleClass != null && roleClass.CanUseKillButton(pc)) { return true; } return false; } public static bool HasKillButton(this PlayerControl pc) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 if ((Object)(object)pc == (Object)null) { return false; } if (!pc.IsAlive() || (int)pc.Data.Role.Role == 4 || Pelican.IsEaten(pc.PlayerId)) { return false; } CustomRoles customRole = pc.GetCustomRole(); if (!customRole.IsImpostor()) { return (int)customRole.GetDYRole() == 1; } return customRole.GetVNRole() switch { CustomRoles.Impostor => true, CustomRoles.Shapeshifter => true, CustomRoles.Phantom => true, _ => false, }; } public static bool CanUseImpostorVentButton(this PlayerControl pc) { if (!pc.IsAlive()) { return false; } if (GameStates.IsHideNSeek) { return true; } if (DollMaster.IsDoll(pc.PlayerId) || Circumvent.CantUseVent(pc)) { return false; } if (Object.op_Implicit((Object)(object)Necromancer.Killer) && !pc.Is(CustomRoles.Necromancer)) { return false; } if (pc.Is(CustomRoles.Killer) || pc.Is(CustomRoles.Nimble)) { return true; } if (Amnesiac.PreviousAmnesiacCanVent(pc)) { return true; } RoleBase roleClass = pc.GetRoleClass(); if (roleClass != null && roleClass.CanUseImpostorVentButton(pc)) { return true; } return false; } public static bool CanUseSabotage(this PlayerControl pc) { if (pc.Is(Custom_Team.Impostor) && !pc.IsAlive() && Options.DeadImpCantSabotage.GetBool()) { return false; } RoleBase roleClass = pc.GetRoleClass(); if (roleClass != null && roleClass.CanUseSabotage(pc)) { return true; } return false; } public static void ResetKillCooldown(this PlayerControl player) { Main.AllPlayerKillCooldown[player.PlayerId] = Options.DefaultKillCooldown; if (player.Is(CustomRoles.Killer)) { Main.AllPlayerKillCooldown[player.PlayerId] = FFAManager.FFA_KCD.GetFloat(); } else { player.GetRoleClass()?.SetKillCooldown(player.PlayerId); } List customSubRoles = player.GetCustomSubRoles(); if (customSubRoles.Any()) { using List.Enumerator enumerator = customSubRoles.GetEnumerator(); while (enumerator.MoveNext()) { switch (enumerator.Current) { case CustomRoles.LastImpostor: if (player.PlayerId == LastImpostor.currentId) { LastImpostor.SetKillCooldown(); } break; case CustomRoles.Mare: Main.AllPlayerKillCooldown[player.PlayerId] = Mare.KillCooldownInLightsOut.GetFloat(); break; case CustomRoles.Overclocked: Main.AllPlayerKillCooldown[player.PlayerId] -= Main.AllPlayerKillCooldown[player.PlayerId] * (Overclocked.OverclockedReduction.GetFloat() / 100f); break; case CustomRoles.Diseased: Diseased.IncreaseKCD(player); break; case CustomRoles.Antidote: Antidote.ReduceKCD(player); break; } } } if (!player.HasImpKillButton()) { Main.AllPlayerKillCooldown[player.PlayerId] = 300f; } if (player.GetRoleClass() is Chronomancer chronomancer) { chronomancer.realcooldown = Main.AllPlayerKillCooldown[player.PlayerId]; chronomancer.SetCooldown(); } if (Main.AllPlayerKillCooldown[player.PlayerId] == 0f) { Main.AllPlayerKillCooldown[player.PlayerId] = 0.3f; } } public static bool IsNonCrewSheriff(this PlayerControl sheriff) { if (!sheriff.Is(CustomRoles.Madmate) && !sheriff.Is(CustomRoles.Charmed) && !sheriff.Is(CustomRoles.Infected) && !sheriff.Is(CustomRoles.Contagious)) { return sheriff.Is(CustomRoles.Egoist); } return true; } public static bool ShouldBeDisplayed(this CustomRoles subRole) { if (subRole != CustomRoles.LastImpostor && subRole != CustomRoles.Madmate && subRole != CustomRoles.Charmed && subRole != CustomRoles.Recruit && subRole != CustomRoles.Admired && subRole != CustomRoles.Soulless && subRole != CustomRoles.Lovers && subRole != CustomRoles.Infected) { return subRole != CustomRoles.Contagious; } return false; } public static void RpcExileV2(this PlayerControl player) { if (player.Is(CustomRoles.Susceptible)) { Susceptible.CallEnabledAndChange(player); } player.Exiled(); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)4, (SendOption)0, -1); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void RpcMurderPlayer(this PlayerControl killer, PlayerControl target) { if ((Object)(object)DollMaster.SwapPlayerInfo(target) != (Object)(object)target) { DollMaster.CheckMurderAsPossessed(killer, target); } else { killer.RpcMurderPlayer(target, true); } } public static void AddInSwitchAddons(PlayerControl Killed, PlayerControl target, CustomRoles Addon = CustomRoles.NotAssigned, CustomRoles? IsAddon = CustomRoles.NotAssigned) { if (Addon == CustomRoles.NotAssigned) { Addon = IsAddon ?? CustomRoles.NotAssigned; } switch (Addon) { case CustomRoles.Tired: Tired.Remove(Killed.PlayerId); Tired.Add(target.PlayerId); break; case CustomRoles.Bewilder: Bewilder.Add(); break; case CustomRoles.Lucky: Lucky.Remove(Killed.PlayerId); Lucky.Add(target.PlayerId); break; case CustomRoles.Clumsy: Clumsy.Remove(Killed.PlayerId); Clumsy.Add(target.PlayerId); break; case CustomRoles.Statue: Statue.Remove(Killed.PlayerId); Statue.Add(target.PlayerId); break; case CustomRoles.Glow: Glow.Remove(Killed.PlayerId); Glow.Add(target.PlayerId); break; case CustomRoles.Radar: Radar.Remove(Killed.PlayerId); Radar.Add(target.PlayerId); break; } } public static bool RpcCheckAndMurder(this PlayerControl killer, PlayerControl target, bool check = false) { MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); string name = method.Name; string fullName = method.DeclaringType.FullName; Logger.Msg("RpcCheckAndMurder activated from: " + fullName + "." + name, "RpcCheckAndMurder", escapeCRLF: true, 794, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); return CheckMurderPatch.RpcCheckAndMurder(killer, target, check); } public static bool CheckForInvalidMurdering(this PlayerControl killer, PlayerControl target, bool checkCanUseKillButton = false) { return CheckMurderPatch.CheckForInvalidMurdering(killer, target, checkCanUseKillButton); } public static void NoCheckStartMeeting(this PlayerControl reporter, NetworkedPlayerInfo target, bool force = false) { if (!Options.DisableMeeting.GetBool() || force) { SetUpRoleTextPatch.IsInIntro = false; ReportDeadBodyPatch.AfterReportTasks(reporter, target); MeetingRoomManager.Instance.AssignSelf(reporter, target); DestroyableSingleton.Instance.OpenMeetingRoom(reporter); reporter.RpcStartMeeting(target); } } public static bool IsModClient(this PlayerControl player) { return Main.playerVersion.ContainsKey(player.GetClientId()); } public static List GetPlayersInAbilityRangeSorted(this PlayerControl player, bool ignoreColliders = false) { return player.GetPlayersInAbilityRangeSorted((PlayerControl pc) => true, ignoreColliders); } public static List GetPlayersInAbilityRangeSorted(this PlayerControl player, Predicate predicate, bool ignoreColliders = false) { List tempPlayerList = RoleBehaviour.GetTempPlayerList(); List list = new List(); player.Data.Role.GetPlayersInAbilityRangeSorted(tempPlayerList, ignoreColliders); foreach (PlayerControl item in tempPlayerList.ToArray()) { if (predicate(item)) { list.Add(item); } } return list; } public static bool IsNeutralKiller(this PlayerControl player) { return player.GetCustomRole().IsNK(); } public static bool IsNeutralBenign(this PlayerControl player) { return player.GetCustomRole().IsNB(); } public static bool IsNeutralEvil(this PlayerControl player) { return player.GetCustomRole().IsNE(); } public static bool IsNeutralChaos(this PlayerControl player) { return player.GetCustomRole().IsNC(); } public static bool IsNonNeutralKiller(this PlayerControl player) { return player.GetCustomRole().IsNonNK(); } public static bool KnowDeathReason(this PlayerControl seer, PlayerControl target) { if ((!Options.EveryoneCanSeeDeathReason.GetBool() && !seer.Is(CustomRoles.Doctor) && !seer.Is(CustomRoles.Autopsy) && (!seer.Data.IsDead || !Options.GhostCanSeeDeathReason.GetBool())) || !target.Data.IsDead) { if (target.Is(CustomRoles.Gravestone)) { return target.Data.IsDead; } return false; } return true; } public static bool KnowDeadTeam(this PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Necroview)) { return target.Data.IsDead; } return false; } public static bool KnowLivingTeam(this PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Visionary)) { return !target.Data.IsDead; } return false; } public static bool KnowRoleTarget(PlayerControl seer, PlayerControl target, bool isVanilla = false) { if (Options.CurrentGameMode == CustomGameMode.FFA || GameEndCheckerForNormal.ShowAllRolesWhenGameEnd) { if (isVanilla) { logger.Info($"IsFFA {Options.CurrentGameMode == CustomGameMode.FFA} or Game End {GameEndCheckerForNormal.ShowAllRolesWhenGameEnd}"); } return true; } if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value)) { if (isVanilla) { logger.Info($"Is GM {seer.Is(CustomRoles.GM)} or {target.Is(CustomRoles.GM)} or GodMode {PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value}"); } return true; } if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) { if (isVanilla) { logger.Info("Is dead and can see other roles"); } return true; } if (Options.SeeEjectedRolesInMeeting.GetBool() && Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote) { if (isVanilla) { logger.Info("See Ejected Roles In Meeting"); } return true; } if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) { if (isVanilla) { logger.Info("Roles == and IsNK"); } return true; } if (Options.LoverKnowRoles.GetBool() && seer.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) { if (isVanilla) { logger.Info("Lover Know Roles"); } return true; } if (Options.ImpsCanSeeEachOthersRoles.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) { if (isVanilla) { logger.Info("Imps Can See Each Others Roles"); } return true; } if (Madmate.MadmateKnowWhosImp.GetBool() && seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor)) { if (isVanilla) { logger.Info("Madmate Know Whos Imp"); } return true; } if (Madmate.ImpKnowWhosMadmate.GetBool() && target.Is(CustomRoles.Madmate) && seer.Is(Custom_Team.Impostor)) { if (isVanilla) { logger.Info("Imp Know Whos Madmate"); } return true; } if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) { if (isVanilla) { logger.Info("Impostor see Imp Ghost Role"); } return true; } if (target.GetRoleClass().KnowRoleTarget(seer, target)) { if (isVanilla) { logger.Info($"target {target.GetCustomRole()} GetRoleClass().KnowRoleTarget"); } return true; } if (seer.GetRoleClass().KnowRoleTarget(seer, target)) { if (isVanilla) { logger.Info($"seer {seer.GetCustomRole()} GetRoleClass().KnowRoleTarget"); } return true; } if (Solsticer.OtherKnowSolsticer(target)) { if (isVanilla) { logger.Info("Solsticer Other Know Solsticer"); } return true; } if (Overseer.IsRevealedPlayer(seer, target) && !target.Is(CustomRoles.Trickster)) { if (isVanilla) { logger.Info("Overseer.IsRevealedPlayer"); } return true; } if (Gravestone.EveryoneKnowRole(target)) { if (isVanilla) { logger.Info("Gravestone.EveryoneKnowRole"); } return true; } if (Mimic.CanSeeDeadRoles(seer, target)) { if (isVanilla) { logger.Info("Mimic.CanSeeDeadRoles"); } return true; } if (Workaholic.OthersKnowWorka(target)) { if (isVanilla) { logger.Info("Workaholic Others Know Worka"); } return true; } if (Jackal.JackalKnowRole(seer, target)) { if (isVanilla) { logger.Info("Jackal Know Role"); } return true; } if (Cultist.KnowRole(seer, target)) { if (isVanilla) { logger.Info("Cultist Know Role"); } return true; } if (Infectious.KnowRole(seer, target)) { if (isVanilla) { logger.Info("Infectious Know Role"); } return true; } if (Virus.KnowRole(seer, target)) { if (isVanilla) { logger.Info("Virus Know Role"); } return true; } return false; } public static bool ShowSubRoleTarget(this PlayerControl seer, PlayerControl target, CustomRoles subRole = CustomRoles.NotAssigned) { if ((Object)(object)seer == (Object)null) { return false; } if ((Object)(object)target == (Object)null) { target = seer; } if (seer.PlayerId == target.PlayerId) { return true; } if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || seer.Is(CustomRoles.God) || (((InnerNetObject)seer).AmOwner && Main.GodMode.Value)) { return true; } if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) { return true; } if (Options.ImpsCanSeeEachOthersAddOns.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !subRole.IsBetrayalAddon()) { return true; } bool flag; switch (subRole) { case CustomRoles.Sidekick: case CustomRoles.Admired: case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Egoist: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Recruit: flag = true; break; default: flag = false; break; } if (flag && KnowSubRoleTarget(seer, target)) { return true; } return false; } public static bool KnowSubRoleTarget(PlayerControl seer, PlayerControl target) { if (seer.Is(Custom_Team.Impostor)) { if (target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) { return true; } if (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool()) { return true; } } else { if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) { return true; } if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) { return true; } if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) { return true; } if (Virus.HasEnabled && Virus.KnowRole(seer, target)) { return true; } if (Jackal.HasEnabled) { if (seer.Is(CustomRoles.Jackal) || seer.Is(CustomRoles.Recruit)) { if (!target.Is(CustomRoles.Sidekick)) { return target.Is(CustomRoles.Recruit); } return true; } if (seer.Is(CustomRoles.Sidekick)) { if (!target.Is(CustomRoles.Recruit)) { return target.Is(CustomRoles.Sidekick); } return true; } } } return false; } public static bool CanBeTeleported(this PlayerControl player) { if ((Object)(object)player.Data == (Object)null || Main.MeetingIsStarted || !player.IsAlive() || player.inVent || player.walkingToVent || player.inMovingPlat || player.MyPhysics.Animations.IsPlayingEnterVentAnimation() || player.onLadder || player.MyPhysics.Animations.IsPlayingAnyLadderAnimation() || Pelican.IsEaten(player.PlayerId)) { return false; } return true; } public static Vector2 GetCustomPosition(this PlayerControl player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) return new Vector2(((Component)player).transform.position.x, ((Component)player).transform.position.y); } public static Vector2 GetBlackRoomPosition() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) return (Vector2)(Utils.GetActiveMapId() switch { 0 => new Vector2(-27f, 3.3f), 1 => new Vector2(-11.4f, 8.2f), 2 => new Vector2(42.6f, -19.9f), 3 => new Vector2(27f, 3.3f), 4 => new Vector2(-16.8f, -6.2f), 5 => new Vector2(10.2f, 18.1f), _ => throw new NotImplementedException(), }); } public static void RpcTeleportAllPlayers(Vector2 location) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; for (int i = 0; i < allAlivePlayerControls.Length; i++) { allAlivePlayerControls[i].RpcTeleport(location); } } public static void RpcDesyncTeleport(this PlayerControl player, Vector2 position, PlayerControl seer) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { CustomNetworkTransform netTransform = player.NetTransform; int clientId = seer.GetClientId(); ushort num = (ushort)(GameStates.IsLocalGame ? 4 : 40); if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { netTransform.SnapTo(position, (ushort)(netTransform.lastSequenceId + num)); return; } ushort num2 = (ushort)(netTransform.lastSequenceId + num); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)netTransform).NetId, (byte)21, (SendOption)1, clientId); NetHelpers.WriteVector2(position, val); val.Write(num2); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RpcTeleport(this PlayerControl player, Vector2 position, bool isRandomSpawn = false, bool sendInfoInLogs = true) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) if (sendInfoInLogs) { Logger.Info($" {player.GetNameWithRole().RemoveHtmlTags()} => {position}", "RpcTeleport", escapeCRLF: true, 1104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); Logger.Info($" Player Id: {player.PlayerId}", "RpcTeleport", escapeCRLF: true, 1105, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); } if (!isRandomSpawn) { bool flag = false; if (player.inVent || player.MyPhysics.Animations.IsPlayingEnterVentAnimation()) { Logger.Info("Target: (" + player.GetNameWithRole().RemoveHtmlTags() + ") in vent", "RpcTeleport", escapeCRLF: true, 1115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); flag = true; } else if (player.onLadder || player.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { Logger.Warn("Teleporting canceled - Target: (" + player.GetNameWithRole().RemoveHtmlTags() + ") is in on Ladder", "RpcTeleport", escapeCRLF: true, 1120, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); flag = true; } else if (player.inMovingPlat) { Logger.Warn("Teleporting canceled - Target: (" + player.GetNameWithRole().RemoveHtmlTags() + ") use moving platform (Airship/Fungle)", "RpcTeleport", escapeCRLF: true, 1125, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); flag = true; } if (flag) { player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), Translator.GetString("ErrorTeleport"))); return; } } CustomNetworkTransform netTransform = player.NetTransform; if (((InnerNetClient)AmongUsClient.Instance).AmClient) { netTransform.SnapTo(position, (ushort)(netTransform.lastSequenceId + 328)); } ushort num = (ushort)(netTransform.lastSequenceId + 8); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)netTransform).NetId, (byte)21, (SendOption)1, -1); NetHelpers.WriteVector2(position, val); val.Write(num); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void RpcRandomVentTeleport(this PlayerControl player) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) Vent val = ((IList)ShipStatus.Instance.AllVents).RandomElement(); Logger.Info($" {((Component)val).transform.position}", "RpcVentTeleportPosition", escapeCRLF: true, 1156, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); player.RpcTeleport(new Vector2(((Component)val).transform.position.x, ((Component)val).transform.position.y + 0.3636f)); } public static int GetPlayerVentId(this PlayerControl player) { ISystemType val = default(ISystemType); if (ShipStatus.Instance.Systems.TryGetValue((SystemTypes)37, ref val)) { VentilationSystem val2 = ((Il2CppObjectBase)val).TryCast(); if (val2 != null) { byte result = default(byte); if (!val2.PlayersInsideVents.TryGetValue(player.PlayerId, ref result)) { return 99; } return result; } } return 99; } public static string GetRoleInfo(this PlayerControl player, bool InfoLong = false) { CustomRoles customRole = player.GetCustomRole(); if ((customRole == CustomRoles.Crewmate || customRole == CustomRoles.Impostor) ? true : false) { InfoLong = false; } string text = customRole.ToString(); string text2 = ""; if (!InfoLong && customRole == CustomRoles.Nemesis) { text2 = (Nemesis.CheckCanUseKillButton() ? "After" : "Before"); } string text3 = (customRole.IsVanilla() ? "Blurb" : "Info"); if (InfoLong) { return customRole.GetInfoLong(); } return Translator.GetString(text2 + text + text3); } public static void SetRealKiller(this PlayerControl target, PlayerControl killer, bool NotOverRide = false) { if ((Object)(object)target == (Object)null) { Logger.Info("target=null", "SetRealKiller", escapeCRLF: true, 1186, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ExtendedPlayerControl.cs"); } else if (!(Main.PlayerStates[target.PlayerId].RealKiller.Item1 != DateTime.MinValue && NotOverRide)) { byte killerId = (((Object)(object)killer == (Object)null) ? byte.MaxValue : killer.PlayerId); RPC.SetRealKiller(target.PlayerId, killerId); } } public static PlayerControl GetRealKiller(this PlayerControl target) { byte realKiller = Main.PlayerStates[target.Data.PlayerId].GetRealKiller(); if (realKiller != byte.MaxValue) { return Utils.GetPlayerById(realKiller); } return null; } public static PlayerControl GetRealKillerById(this byte targetId) { byte realKiller = Main.PlayerStates[targetId].GetRealKiller(); if (realKiller != byte.MaxValue) { return Utils.GetPlayerById(realKiller); } return null; } public static PlainShipRoom GetPlainShipRoom(this PlayerControl pc) { if (!pc.IsAlive() || Pelican.IsEaten(pc.PlayerId)) { return null; } PlainShipRoom[] array = ((IEnumerable)ShipStatus.Instance.AllRooms).ToArray(); if (array == null) { return null; } PlainShipRoom[] array2 = array; foreach (PlainShipRoom val in array2) { if (Object.op_Implicit((Object)(object)val.roomArea) && pc.Collider.IsTouching(val.roomArea)) { return val; } } return null; } public static void SetDeathReason(this PlayerControl target, PlayerState.DeathReason reason) { target.PlayerId.SetDeathReason(reason); } public static void SetDeathReason(this byte targetId, PlayerState.DeathReason reason) { Main.PlayerStates[targetId].deathReason = reason; } public static bool Is(this PlayerControl target, CustomRoles role) { if (role <= CustomRoles.NotAssigned) { return target.GetCustomRole() == role; } return target.GetCustomSubRoles().Contains(role); } public static bool Is(this PlayerControl target, Custom_Team type) { return target.GetCustomRole().GetCustomRoleTeam() == type; } public static bool Is(this PlayerControl target, RoleTypes type) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return target.GetCustomRole().GetRoleTypes() == type; } public static bool Is(this PlayerControl target, CountTypes type) { return target.GetCountTypes() == type; } public static bool IsAnySubRole(this PlayerControl target, Func predicate) { if ((Object)(object)target != (Object)null && target.GetCustomSubRoles().Any()) { return target.GetCustomSubRoles().Any(predicate); } return false; } public static bool IsAlive(this PlayerControl target) { if (GameStates.IsLobby && !GameStates.IsInGame) { return true; } if ((Object)(object)target == (Object)null) { return false; } if (Main.PlayerStates.TryGetValue(target.PlayerId, out var value)) { return !value.IsDead; } return true; } public static bool IsDisconnected(this PlayerControl target) { if (GameStates.IsLobby && !GameStates.IsInGame) { return false; } if ((Object)(object)target == (Object)null) { return true; } if (Main.PlayerStates.TryGetValue(target.PlayerId, out var value)) { return value.Disconnected; } return true; } public static bool IsExiled(this PlayerControl target) { if (!GameStates.InGame) { if ((Object)(object)target != (Object)null) { return Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote; } return false; } return true; } public static bool IsProtected(this PlayerControl self) { return self.protectedByGuardianId > -1; } } public static class CollectionExtensions { public static TKey GetKeyByValue(this Dictionary dictionary, TValue value) { foreach (KeyValuePair item in dictionary) { if (item.Value.Equals(value)) { return item.Key; } } return default(TKey); } public static T RandomElement(this IList collection) { if (collection.Count == 0) { return default(T); } return collection[IRandom.Instance.Next(collection.Count)]; } public static IEnumerable CombineWith(this IEnumerable firstCollection, params IEnumerable[] collections) { return firstCollection.Concat(collections.SelectMany((IEnumerable x) => x)); } public static IEnumerable Shuffle(this IEnumerable collection, IRandom random) { List list = collection.ToList(); int num = list.Count; while (num > 1) { num--; int num2 = random.Next(num + 1); List list2 = list; int index = num; List list3 = list; int index2 = num2; T value = list[num2]; T value2 = list[num]; list2[index] = value; list3[index2] = value2; } return list; } public static HashSet FilterDuplicates(this IEnumerable collection) where TDelegate : Delegate { return (from d in collection where d.Target != null group d by d.Target.GetType() into g select g.First()).Concat(collection.Where((TDelegate x) => x.Target == null)).ToHashSet(); } public static byte First(this HashSet source) { return source.ToArray().First(); } } public class PlayerState { public enum DeathReason { Kill = 0, Vote = 1, Suicide = 2, Spell = 3, Curse = 4, Hex = 5, FollowingSuicide = 6, Bite = 7, Poison = 8, Bombed = 9, Misfire = 10, Torched = 11, Sniped = 12, Revenge = 13, Execution = 14, Fall = 15, Gambled = 16, Eaten = 17, Sacrifice = 18, Quantization = 19, Overtired = 20, Ashamed = 21, PissedOff = 22, Dismembered = 23, LossOfHead = 24, Trialed = 25, Infected = 26, Jinx = 27, Hack = 28, Pirate = 29, Shrouded = 30, Mauled = 31, Drained = 32, Shattered = 33, Trap = 34, Targeted = 35, Retribution = 36, Slice = 37, BloodLet = 38, WrongAnswer = 39, etc = -1 } public readonly byte PlayerId; public RoleBase RoleClass; public CustomRoles MainRole; public List SubRoles; public CountTypes countTypes; public TaskState taskState; public (DateTime, byte) RealKiller; public PlainShipRoom LastRoom; public Dictionary TargetColorData; public PlayerOutfit NormalOutfit; public bool IsDead { get; set; } public bool Disconnected { get; set; } public DeathReason deathReason { get; set; } public bool IsBlackOut { get; set; } public bool HasSpawned { get; set; } public bool IsSuicide => deathReason == DeathReason.Suicide; public TaskState TaskState => taskState; public PlayerState(byte playerId) { PlayerId = playerId; RoleClass = new DefaultSetup(); MainRole = CustomRoles.NotAssigned; SubRoles = new List(); deathReason = DeathReason.etc; taskState = new TaskState(); RealKiller = (DateTime.MinValue, byte.MaxValue); TargetColorData = new Dictionary(); base..ctor(); } public void SetMainRole(CustomRoles role) { MainRole = role; countTypes = role.GetCountTypes(); RoleClass = role.CreateRoleClass(); PlayerControl playerById = Utils.GetPlayerById(PlayerId); if (role == CustomRoles.Opportunist && ((InnerNetClient)AmongUsClient.Instance).AmHost && !playerById.HasImpKillButton(considerVanillaShift: true)) { TaskState playerTaskState = playerById.GetPlayerTaskState(); if (playerTaskState != null) { playerById.Data.RpcSetTasks(new Il2CppStructArray(0L)); playerTaskState.CompletedTasksCount = 0; playerTaskState.AllTasksCount = playerById.Data.Tasks.Count; playerTaskState.hasTasks = true; } } if (playerById.Is(CustomRoles.Madmate)) { countTypes = Madmate.MadmateCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Impostor, 2 => countTypes, _ => throw new NotImplementedException(), }; } if (playerById.Is(CustomRoles.Charmed)) { countTypes = Cultist.CharmedCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Cultist, 2 => countTypes, _ => throw new NotImplementedException(), }; } if (playerById.Is(CustomRoles.Recruit)) { countTypes = Jackal.SidekickCountMode.GetInt() switch { 0 => CountTypes.Jackal, 1 => CountTypes.OutOfGame, 2 => countTypes, _ => throw new NotImplementedException(), }; } if (playerById.Is(CustomRoles.Infected)) { countTypes = CountTypes.Infectious; } if (playerById.Is(CustomRoles.Contagious)) { countTypes = Virus.ContagiousCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Virus, 2 => countTypes, _ => throw new NotImplementedException(), }; } if (playerById.Is(CustomRoles.Admired)) { countTypes = CountTypes.Crew; } if (playerById.Is(CustomRoles.Soulless)) { countTypes = CountTypes.OutOfGame; } } public void SetSubRole(CustomRoles role, bool AllReplace = false, PlayerControl pc = null) { if (role == CustomRoles.Cleansed) { if ((Object)(object)pc != (Object)null) { countTypes = pc.GetCustomRole().GetCountTypes(); } AllReplace = true; } if (AllReplace) { bool flag = false; CustomRoles[] array = SubRoles.ToArray(); foreach (CustomRoles item in array) { if (pc.Is(CustomRoles.Flash)) { Flash.SetSpeed(pc.PlayerId, clearAddOn: true); flag = true; } SubRoles.Remove(item); if (flag) { Utils.MarkEveryoneDirtySettings(); } } } if (!SubRoles.Contains(role)) { SubRoles.Add(role); } if (role.IsConverted()) { SubRoles.RemoveAll((CustomRoles AddON) => AddON != role && AddON.IsConverted()); SubRoles.Remove(CustomRoles.Rascal); SubRoles.Remove(CustomRoles.Loyal); SubRoles.Remove(CustomRoles.Admired); } switch (role) { case CustomRoles.LastImpostor: SubRoles.Remove(CustomRoles.Mare); break; case CustomRoles.Madmate: countTypes = Madmate.MadmateCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Impostor, 2 => countTypes, _ => throw new NotImplementedException(), }; break; case CustomRoles.Charmed: countTypes = Cultist.CharmedCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Cultist, 2 => countTypes, _ => throw new NotImplementedException(), }; break; case CustomRoles.Recruit: countTypes = Jackal.SidekickCountMode.GetInt() switch { 0 => CountTypes.Jackal, 1 => CountTypes.OutOfGame, 2 => countTypes, _ => throw new NotImplementedException(), }; break; case CustomRoles.Infected: countTypes = CountTypes.Infectious; break; case CustomRoles.Contagious: countTypes = Virus.ContagiousCountMode.GetInt() switch { 0 => CountTypes.OutOfGame, 1 => CountTypes.Virus, 2 => countTypes, _ => throw new NotImplementedException(), }; break; case CustomRoles.Nimble: SubRoles.Remove(CustomRoles.Circumvent); break; case CustomRoles.Admired: countTypes = CountTypes.Crew; SubRoles.RemoveAll((CustomRoles AddON) => AddON != role && AddON.IsConverted()); SubRoles.Remove(CustomRoles.Rascal); SubRoles.Remove(CustomRoles.Loyal); break; case CustomRoles.Soulless: countTypes = CountTypes.OutOfGame; break; } } public void RemoveSubRole(CustomRoles role) { if (SubRoles.Contains(role)) { SubRoles.Remove(role); } } public void SetDead() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Invalid comparison between Unknown and I4 MethodBase? method = new StackFrame(1, needFileInfo: false).GetMethod(); string name = method.Name; string fullName = method.DeclaringType.FullName; Logger.Msg($"Player {PlayerId} was dead, activated from: {fullName}.{name}", "PlayerState.SetDead()", escapeCRLF: true, 227, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameState.cs"); IsDead = true; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { RPC.SendDeathReason(PlayerId, deathReason); bool flag = GameStates.IsMeeting; if (flag) { VoteStates state = MeetingHud.Instance.state; bool flag2 = state - 1 <= 2; flag = flag2; } if (flag) { MeetingHud.Instance.CheckForEndVoting(); } } } public void InitTask(PlayerControl player) { taskState.Init(player); } public void UpdateTask(PlayerControl player) { taskState.Update(player); } public byte GetRealKiller() { if (!IsDead || !(RealKiller.Item1 != DateTime.MinValue)) { return byte.MaxValue; } return RealKiller.Item2; } public int GetKillCount(bool ExcludeSelfKill = false) { int num = 0; PlayerState[] array = Main.PlayerStates.Values.ToArray(); foreach (PlayerState playerState in array) { if ((!ExcludeSelfKill || playerState.PlayerId != PlayerId) && playerState.GetRealKiller() == PlayerId) { num++; } } return num; } } public class TaskState { public static int InitialTotalTasks; public int AllTasksCount; public int CompletedTasksCount; public bool hasTasks; public int RemainingTasksCount => AllTasksCount - CompletedTasksCount; public bool DoExpose { get { if (RemainingTasksCount <= Options.SnitchExposeTaskLeft) { return hasTasks; } return false; } } public bool IsTaskFinished { get { if (RemainingTasksCount <= 0) { return hasTasks; } return false; } } public TaskState() { AllTasksCount = -1; CompletedTasksCount = 0; hasTasks = false; } public static string GetTaskState() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) KeyValuePair[] array = Main.PlayerStates.Where((KeyValuePair a) => a.Value.TaskState.hasTasks).ToArray(); if (array.Length == 0) { return "\r\n"; } TaskState taskState = array.RandomElement().Value.TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = ((Camouflager.AbilityActivated || Camouflage.IsCamouflage) ? Color.gray : val); string value = ((Camouflager.AbilityActivated || Camouflage.IsCamouflage) ? "?" : $"{taskState.CompletedTasksCount}"); return $" " + Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})") + "\r\n"; } public void Init(PlayerControl player) { Logger.Info(player.GetNameWithRole().RemoveHtmlTags() + ": InitTask", "TaskState.Init", escapeCRLF: true, 346, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameState.cs"); if (!((Object)(object)player == (Object)null) && !((Object)(object)player.Data == (Object)null) && player.Data.Tasks != null) { if (!Utils.HasTasks(player.Data, ForRecompute: false)) { AllTasksCount = 0; return; } hasTasks = true; AllTasksCount = player.Data.Tasks.Count; Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()}: TaskCounts = {CompletedTasksCount}/{AllTasksCount}", "TaskState.Init", escapeCRLF: true, 359, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameState.cs"); } } public void Update(PlayerControl player) { Logger.Info(player.GetNameWithRole().RemoveHtmlTags() + ": UpdateTask", "TaskState.Update", escapeCRLF: true, 363, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameState.cs"); if (AllTasksCount == -1) { Init(player); } if (hasTasks && CompletedTasksCount < AllTasksCount && (!player.Is(CustomRoles.Solsticer) || ((InnerNetClient)AmongUsClient.Instance).AmHost)) { CompletedTasksCount++; CompletedTasksCount = Math.Min(AllTasksCount, CompletedTasksCount); Logger.Info($"{player.GetNameWithRole().RemoveHtmlTags()}: TaskCounts = {CompletedTasksCount}/{AllTasksCount}", "TaskState.Update", escapeCRLF: true, 380, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameState.cs"); } } } public class PlayerVersion { public readonly Version version; public readonly string tag; public readonly string forkId; public PlayerVersion(Version ver, string tag_str, string forkId) { version = ver; tag = tag_str; this.forkId = forkId; base..ctor(); } [Obsolete] public PlayerVersion(string ver, string tag_str) : this(Version.Parse(ver), tag_str, string.Empty) { } [Obsolete] public PlayerVersion(Version ver, string tag_str) : this(ver, tag_str, string.Empty) { } public PlayerVersion(string ver, string tag_str, string forkId) : this(Version.Parse(ver), tag_str, forkId) { } public bool IsEqual(PlayerVersion pv) { if (pv.version == version) { return pv.tag == tag; } return false; } } public static class GameStates { public static bool InGame; public static bool AlreadyDied; public static bool IsModHost => Main.playerVersion.ContainsKey(((InnerNetClient)AmongUsClient.Instance).HostId); public static bool IsNormalGame { get { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 GameModes gameMode = GameOptionsManager.Instance.CurrentGameOptions.GameMode; if ((int)gameMode == 1 || (int)gameMode == 3) { return true; } return false; } } public static bool IsHideNSeek { get { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 GameModes gameMode = GameOptionsManager.Instance.CurrentGameOptions.GameMode; if ((int)gameMode == 2 || (int)gameMode == 4) { return true; } return false; } } public static bool SkeldIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 0; public static bool MiraHQIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 1; public static bool PolusIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 2; public static bool DleksIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 3; public static bool AirshipIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 4; public static bool FungleIsActive => GameOptionsManager.Instance.CurrentGameOptions.MapId == 5; public static bool IsLobby => (int)((InnerNetClient)AmongUsClient.Instance).GameState == 1; public static bool IsInGame => InGame; public static bool IsEnded => (int)((InnerNetClient)AmongUsClient.Instance).GameState == 3; public static bool IsNotJoined => (int)((InnerNetClient)AmongUsClient.Instance).GameState == 0; public static bool IsOnlineGame => (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 1; public static bool IsVanillaServer { get { if (!IsOnlineGame) { return false; } IRegionInfo currentRegion = DestroyableSingleton.Instance.CurrentRegion; StaticHttpRegionInfo val = ((currentRegion != null) ? ((Il2CppObjectBase)currentRegion).TryCast() : null); if (val != null && val.PingServer.EndsWith("among.us", StringComparison.Ordinal)) { return ((IEnumerable)val.Servers).All((ServerInfo serverInfo) => serverInfo.Ip.EndsWith("among.us", StringComparison.Ordinal)); } return false; } } public static bool IsLocalGame => (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 0; public static bool IsFreePlay => (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 2; public static bool IsInTask { get { if (InGame) { return !Object.op_Implicit((Object)(object)MeetingHud.Instance); } return false; } } public static bool IsMeeting { get { if (InGame) { return Object.op_Implicit((Object)(object)MeetingHud.Instance); } return false; } } public static bool IsVoting { get { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 bool flag = IsMeeting; if (flag) { VoteStates state = MeetingHud.Instance.state; bool flag2 = state - 2 <= 1; flag = flag2; } return flag; } } public static bool IsProceeding { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (IsMeeting) { return (int)MeetingHud.Instance.state == 5; } return false; } } public static bool IsExilling { get { if ((Object)(object)ExileController.Instance != (Object)null) { if (AirshipIsActive && (Object)(object)Minigame.Instance != (Object)null) { return !((Behaviour)Minigame.Instance).isActiveAndEnabled; } return true; } return false; } } public static bool IsCountDown { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (DestroyableSingleton.InstanceExists) { return (int)DestroyableSingleton.Instance.startState == 1; } return false; } } public static bool IsShip => (Object)(object)ShipStatus.Instance != (Object)null; public static bool IsCanMove { get { PlayerControl localPlayer = PlayerControl.LocalPlayer; return ((localPlayer != null) ? new bool?(localPlayer.CanMove) : null) ?? false; } } public static bool IsDead { get { PlayerControl localPlayer = PlayerControl.LocalPlayer; bool? obj; if (localPlayer == null) { obj = null; } else { NetworkedPlayerInfo data = localPlayer.Data; obj = ((data != null) ? new bool?(data.IsDead) : null); } return obj ?? false; } } } public static class MeetingStates { public static DeadBody[] DeadBodies = null; public static NetworkedPlayerInfo ReportTarget = null; public static bool MeetingCalled = false; public static bool FirstMeeting = true; public static bool IsEmergencyMeeting => (Object)(object)ReportTarget == (Object)null; public static bool IsExistDeadBody => DeadBodies.Any(); } public static class GuessManager { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { if (Options.GuesserMode.GetBool()) { if (PlayerControl.LocalPlayer.IsAlive() && (PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) || PlayerControl.LocalPlayer.GetCustomRole().IsMadmate()) && Options.ImpostorsCanGuess.GetBool()) { CreateGuesserButton(__instance); } else if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.EvilGuesser && !Options.ImpostorsCanGuess.GetBool()) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.GetCustomRole().IsCrewmate() && Options.CrewmatesCanGuess.GetBool()) { CreateGuesserButton(__instance); } else if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.NiceGuesser && !Options.CrewmatesCanGuess.GetBool()) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.GetCustomRole().IsNK() && Options.NeutralKillersCanGuess.GetBool()) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.GetCustomRole().IsNonNK() && Options.PassiveNeutralsCanGuess.GetBool()) { CreateGuesserButton(__instance); } else if (PlayerControl.LocalPlayer.GetCustomRole() == CustomRoles.Doomsayer && !Options.PassiveNeutralsCanGuess.GetBool() && !Doomsayer.CheckCantGuess) { CreateGuesserButton(__instance); } } else { if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.EvilGuesser)) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.NiceGuesser)) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Doomsayer) && !Doomsayer.CheckCantGuess) { CreateGuesserButton(__instance); } if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Guesser)) { CreateGuesserButton(__instance); } } } } [HarmonyPatch(typeof(MeetingHud), "OnDestroy")] private class MeetingHudOnDestroyGuesserUIClose { public static void Postfix(MeetingHud __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)textTemplate == (Object)null)) { Object.Destroy((Object)(object)((Component)textTemplate).gameObject); } } } public static readonly Dictionary GuesserGuessed = new Dictionary(); public const int MaxOneScreenRole = 40; public static int Page; public static PassiveButton ExitButton; public static GameObject guesserUI; private static Dictionary> RoleButtons; private static Dictionary RoleSelectButtons; private static List PageButtons; public static Custom_Team currentTeamType; public static TextMeshPro textTemplate; public static string GetFormatString() { string text = Translator.GetString("PlayerIdList"); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl obj in allAlivePlayerControls) { string text2 = obj.PlayerId.ToString(); string realName = obj.GetRealName(); text = text + "\n" + text2 + " → " + realName; } return text; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg == "/" + text) { return true; } } else if (msg.StartsWith("/" + text)) { msg = msg.Replace("/" + text, string.Empty); return true; } } return false; } public static byte GetColorFromMsg(string msg) { if (ComfirmIncludeMsg(msg, "红|紅|red")) { return 0; } if (ComfirmIncludeMsg(msg, "蓝|藍|深蓝|blue")) { return 1; } if (ComfirmIncludeMsg(msg, "绿|綠|深绿|green")) { return 2; } if (ComfirmIncludeMsg(msg, "粉红|粉紅|pink")) { return 3; } if (ComfirmIncludeMsg(msg, "橘|橘|orange")) { return 4; } if (ComfirmIncludeMsg(msg, "黄|黃|yellow")) { return 5; } if (ComfirmIncludeMsg(msg, "黑|黑|black")) { return 6; } if (ComfirmIncludeMsg(msg, "白|白|white")) { return 7; } if (ComfirmIncludeMsg(msg, "紫|紫|perple")) { return 8; } if (ComfirmIncludeMsg(msg, "棕|棕|brown")) { return 9; } if (ComfirmIncludeMsg(msg, "青|青|cyan")) { return 10; } if (ComfirmIncludeMsg(msg, "黄绿|黃綠|浅绿|lime")) { return 11; } if (ComfirmIncludeMsg(msg, "红褐|紅褐|深红|maroon")) { return 12; } if (ComfirmIncludeMsg(msg, "玫红|玫紅|浅粉|rose")) { return 13; } if (ComfirmIncludeMsg(msg, "焦黄|焦黃|淡黄|banana")) { return 14; } if (ComfirmIncludeMsg(msg, "灰|灰|gray")) { return 15; } if (ComfirmIncludeMsg(msg, "茶|茶|tan")) { return 16; } if (ComfirmIncludeMsg(msg, "珊瑚|珊瑚|coral")) { return 17; } return byte.MaxValue; } private static bool ComfirmIncludeMsg(string msg, string key) { string[] array = key.Split('|'); foreach (string value in array) { if (msg.Contains(value)) { return true; } } return false; } public static void ShowInfoMessage(this PlayerControl player, bool isUI, string message, string title = "") { if (isUI) { player.ShowPopUp(message, title); } else { Utils.SendMessage(message, player.PlayerId, title); } } public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) { //IL_0632: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_05ee: Unknown result type (might be due to invalid IL or missing references) //IL_0ad8: Unknown result type (might be due to invalid IL or missing references) //IL_0add: Unknown result type (might be due to invalid IL or missing references) string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null || GameStates.IsExilling) { return false; } if (!pc.Is(CustomRoles.NiceGuesser) && !pc.Is(CustomRoles.EvilGuesser) && !pc.Is(CustomRoles.Doomsayer) && !pc.Is(CustomRoles.Judge) && !pc.Is(CustomRoles.Councillor) && !pc.Is(CustomRoles.Guesser) && !Options.GuesserMode.GetBool()) { return false; } int num = 0; msg = msg.ToLower().TrimStart().TrimEnd(); if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id||編號|玩家編號")) { num = 1; } else { if (!CheckCommond(ref msg, "shoot|guess|bet|st|gs|bt|猜|赌|賭", exact: false)) { return false; } num = 2; } Logger.Msg(msg, "Msg Guesser", escapeCRLF: true, 113, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); Logger.Msg($"{num}", "Operate", escapeCRLF: true, 114, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); if (!pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessDead")); return true; } if (!pc.Is(CustomRoles.NiceGuesser) && pc.GetCustomRole().IsCrewmate() && !Options.CrewmatesCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Judge)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (!pc.Is(CustomRoles.EvilGuesser) && (pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && !Options.ImpostorsCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Councillor)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (pc.GetCustomRole().IsNK() && !Options.NeutralKillersCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (pc.GetCustomRole().IsNonNK() && !Options.PassiveNeutralsCanGuess.GetBool() && !pc.Is(CustomRoles.Guesser) && !pc.Is(CustomRoles.Doomsayer)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } switch (num) { case 1: Utils.SendMessage(GetFormatString(), pc.PlayerId); return true; case 2: { if (NiceGuesser.NeedHideMsg(pc) || EvilGuesser.NeedHideMsg(pc) || Doomsayer.NeedHideMsg(pc) || (pc.Is(CustomRoles.Guesser) && Guesser.GTryHideMsg.GetBool()) || (Options.GuesserMode.GetBool() && Options.HideGuesserCommands.GetBool())) { TryHideMsg(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner && !isUI) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var id, out var role, out var error)) { pc.ShowInfoMessage(isUI, error); return true; } PlayerControl playerById = Utils.GetPlayerById(id); Logger.Msg($" {pc.PlayerId}", "Guesser - pc.PlayerId", escapeCRLF: true, 180, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); Logger.Msg($" {playerById.PlayerId}", "Guesser - target.PlayerId", escapeCRLF: true, 181, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); Logger.Msg($" {role}", "Guesser - role", escapeCRLF: true, 182, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); if (!((Object)(object)playerById != (Object)null)) { break; } GuessMaster.OnGuess(role); bool guesserSuicide = false; if (!GuesserGuessed.ContainsKey(pc.PlayerId)) { GuesserGuessed.Add(pc.PlayerId, 0); } if (pc.GetRoleClass().GuessCheck(isUI, pc, playerById, role, ref guesserSuicide)) { return true; } if (playerById.GetRoleClass().OnRoleGuess(isUI, playerById, pc, role, ref guesserSuicide)) { return true; } if (CopyCat.playerIdList.Contains(pc.PlayerId)) { Logger.Info($"Guess Disabled for this player {pc.PlayerId}", "GuessManager", escapeCRLF: true, 198, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); pc.ShowInfoMessage(isUI, Translator.GetString("GuessDisabled")); return true; } if (Jailer.IsTarget(pc.PlayerId) && role != CustomRoles.Jailer) { pc.ShowInfoMessage(isUI, Translator.GetString("JailedCanOnlyGuessJailer"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), Translator.GetString("JailerTitle"))); return true; } if (Jailer.IsTarget(playerById.PlayerId)) { pc.ShowInfoMessage(isUI, Translator.GetString("CantGuessJailed"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), Translator.GetString("JailerTitle"))); return true; } if (!Mundane.OnGuess(pc)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessedAsMundane")); return true; } if (Medic.ProtectList.Contains(playerById.PlayerId) && !Medic.GuesserIgnoreShield.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessShielded")); return true; } if (role == CustomRoles.Bait && playerById.Is(CustomRoles.Bait) && Bait.BaitNotification.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessNotifiedBait")); return true; } if (role == CustomRoles.Rainbow && playerById.Is(CustomRoles.Rainbow)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessRainbow")); return true; } bool flag; switch (role) { case CustomRoles.Cyber: case CustomRoles.Flash: case CustomRoles.Glow: case CustomRoles.LastImpostor: case CustomRoles.Mare: flag = true; break; default: flag = false; break; } if (flag) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessObviousAddon")); return true; } if (playerById.Is(CustomRoles.Onbound)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessOnbound")); return true; } if (role == CustomRoles.GM || playerById.Is(CustomRoles.GM)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessGM")); return true; } if (role.IsAdditionRole() && pc.Is(CustomRoles.Guesser) && !Guesser.GCanGuessAdt.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } if (Options.GuesserMode.GetBool() && role.IsAdditionRole() && !Options.CanGuessAddons.GetBool()) { if (Options.ImpostorsCanGuess.GetBool() && (pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && !pc.Is(CustomRoles.EvilGuesser) && !pc.Is(CustomRoles.Guesser)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } if (Options.CrewmatesCanGuess.GetBool() && pc.Is(Custom_Team.Crewmate) && !pc.Is(CustomRoles.NiceGuesser) && !pc.Is(CustomRoles.Guesser)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } if ((Options.NeutralKillersCanGuess.GetBool() || Options.PassiveNeutralsCanGuess.GetBool()) && pc.Is(Custom_Team.Neutral) && !pc.Is(CustomRoles.Doomsayer) && !pc.Is(CustomRoles.Guesser)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } } if (pc.PlayerId == playerById.PlayerId) { if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId)) { DoubleShot.IsActive.Add(pc.PlayerId); Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-1", escapeCRLF: true, 291, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); pc.ShowInfoMessage(isUI, Translator.GetString("GuessDoubleShot")); return true; } if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId)) { DoubleShot.IsActive.Remove(pc.PlayerId); } pc.ShowInfoMessage(isUI, Translator.GetString("LaughToWhoGuessSelf"), Utils.ColorString(Color32.op_Implicit(Color.cyan), Translator.GetString("MessageFromKPD"))); guesserSuicide = true; Logger.Msg($"Self guess: guesserSuicide - {guesserSuicide}", "GuesserSuicide", escapeCRLF: true, 303, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); } else if (!playerById.Is(role)) { if (pc.Is(CustomRoles.DoubleShot) && !DoubleShot.IsActive.Contains(pc.PlayerId)) { DoubleShot.IsActive.Add(pc.PlayerId); Logger.Msg($"{pc.PlayerId}", "GuesserDoubleShotIsActive-4", escapeCRLF: true, 312, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); pc.ShowInfoMessage(isUI, Translator.GetString("GuessDoubleShot")); return true; } if (pc.Is(CustomRoles.DoubleShot) && DoubleShot.IsActive.Contains(pc.PlayerId)) { DoubleShot.IsActive.Remove(pc.PlayerId); } guesserSuicide = true; Logger.Msg($"The guesser didn't guess the role: guesserSuicide - {guesserSuicide}", "GuesserSuicide", escapeCRLF: true, 323, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); } if (playerById.Is(role) && playerById.Is(CustomRoles.Rebound)) { guesserSuicide = true; Logger.Info(pc.GetNameWithRole() + " guessed " + playerById.GetNameWithRole() + ", guesser suicide because rebound", "GuessManager", escapeCRLF: true, 330, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); } Logger.Info(pc.GetNameWithRole().RemoveHtmlTags() + " guessed => " + playerById.GetNameWithRole().RemoveHtmlTags(), "Guesser", escapeCRLF: true, 333, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); PlayerControl dp = (guesserSuicide ? pc : playerById); playerById = dp; Logger.Info(" Player:" + playerById.GetNameWithRole().RemoveHtmlTags() + " was guessed", "Guesser", escapeCRLF: true, 338, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); GuesserGuessed[pc.PlayerId]++; if (pc.GetRoleClass().CheckMisGuessed(isUI, pc, playerById, role, ref guesserSuicide)) { return true; } string Name = dp.GetRealName(); if (!Options.DisableKillAnimationOnGuess.GetBool()) { CustomSoundsManager.RPCPlayCustomSoundAll("Gunfire"); } if (GameStates.IsProceeding) { break; } new LateTask(delegate { dp.SetDeathReason(PlayerState.DeathReason.Gambled); dp.SetRealKiller(pc); dp.RpcGuesserMurderPlayer(); if ((Object)(object)dp == (Object)(object)pc) { GuessMaster.OnGuess(role, isMisguess: true, dp); } Main.PlayersDiedInMeeting.Add(dp.PlayerId); MurderPlayerPatch.AfterPlayerDeathTasks(pc, dp, inMeeting: true); Utils.NotifyRoles(null, null, GameStates.IsMeeting, NoCache: true); new LateTask(delegate { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("GuessKill"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceGuesser)), Translator.GetString("GuessKillTitle")), logforChatManager: true); }, 0.6f, "Guess Msg"); List playerListByRole = CustomRoles.Doomsayer.GetPlayerListByRole(); if (Doomsayer.HasEnabled && playerListByRole != null && playerListByRole.Any() && playerListByRole != null) { CollectionExtensions.Do(playerListByRole.Select((PlayerControl x) => x.GetRoleClass()), (Action)delegate(RoleBase x) { if (x is Doomsayer doomsayer) { doomsayer.SendMessageAboutGuess(pc, dp, role); } }); } }, 0.2f, "Guesser Kill"); break; } } return true; } public static TextMeshPro NameText(this PlayerControl p) { return p.cosmetics.nameText; } public static TextMeshPro NameText(this PoolablePlayer p) { return p.cosmetics.nameText; } public static void RpcGuesserMurderPlayer(this PlayerControl pc) { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Invalid comparison between Unknown and I4 try { GameEndCheckerForNormal.ShouldNotCheck = true; bool amOwner = ((InnerNetObject)pc).AmOwner; pc.Data.IsDead = true; pc.RpcExileV2(); Main.PlayerStates[pc.PlayerId].SetDead(); MeetingHud instance = MeetingHud.Instance; HudManager hudManager = DestroyableSingleton.Instance; SoundManager.Instance.PlaySound(pc.KillSfx, false, 0.8f, (AudioMixerGroup)null); if (!Options.DisableKillAnimationOnGuess.GetBool()) { hudManager.KillOverlay.ShowKillAnimation(pc.Data, pc.Data); } if (amOwner) { ((Component)hudManager.ShadowQuad).gameObject.SetActive(false); ((Renderer)((Component)pc.NameText()).GetComponent()).material.SetInt("_Mask", 0); pc.RpcSetScanner(false); ((Component)new GameObject("_Player").AddComponent()).transform.SetParent(((Component)AmongUsClient.Instance).transform, false); instance.SetForegroundForDead(); } PlayerVoteArea val = ((IEnumerable)MeetingHud.Instance.playerStates).First((PlayerVoteArea x) => x.TargetPlayerId == pc.PlayerId); if ((Object)(object)val == (Object)null) { return; } if (val.DidVote) { val.UnsetVote(); } val.AmDead = true; ((Component)val.Overlay).gameObject.SetActive(true); val.Overlay.color = Color.white; ((Component)val.XMark).gameObject.SetActive(true); ((Component)val.XMark).transform.localScale = Vector3.one; foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)instance.playerStates) { if (item.VotedFor == pc.PlayerId) { item.UnsetVote(); if (((InnerNetObject)Utils.GetPlayerById(item.TargetPlayerId)).AmOwner) { instance.ClearVote(); } } } Swapper.CheckSwapperTarget(pc.PlayerId); VoteStates state = instance.state; if (state - 1 <= 2) { instance.CheckForEndVoting(); } new LateTask(delegate { hudManager.SetHudActive(false); }, 0.3f, "SetHudActive in GuesserMurderPlayer", shoudLog: false); MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)117, (SendOption)1, -1); val2.Write(pc.PlayerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); GameEndCheckerForNormal.ShouldNotCheck = false; } catch (Exception value) { Logger.Error($"Error after guesser murder: {value}", "RpcGuesserMurderPlayer", escapeCRLF: true, 435, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); GameEndCheckerForNormal.ShouldNotCheck = false; } } public static void RpcClientGuess(PlayerControl pc) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) bool amOwner = ((InnerNetObject)pc).AmOwner; MeetingHud instance = MeetingHud.Instance; HudManager hudManager = DestroyableSingleton.Instance; SoundManager.Instance.PlaySound(pc.KillSfx, false, 0.8f, (AudioMixerGroup)null); hudManager.KillOverlay.ShowKillAnimation(pc.Data, pc.Data); if (amOwner) { ((Component)hudManager.ShadowQuad).gameObject.SetActive(false); ((Renderer)((Component)pc.NameText()).GetComponent()).material.SetInt("_Mask", 0); pc.RpcSetScanner(false); ((Component)new GameObject("_Player").AddComponent()).transform.SetParent(((Component)AmongUsClient.Instance).transform, false); instance.SetForegroundForDead(); } PlayerVoteArea val = ((IEnumerable)MeetingHud.Instance.playerStates).First((PlayerVoteArea x) => x.TargetPlayerId == pc.PlayerId); if ((Object)(object)val == (Object)null) { return; } if (val.DidVote) { val.UnsetVote(); } val.AmDead = true; ((Component)val.Overlay).gameObject.SetActive(true); val.Overlay.color = Color.white; ((Component)val.XMark).gameObject.SetActive(true); ((Component)val.XMark).transform.localScale = Vector3.one; PlayerVoteArea[] array = ((IEnumerable)instance.playerStates).ToArray(); foreach (PlayerVoteArea val2 in array) { if (val2.VotedFor == pc.PlayerId) { val2.UnsetVote(); if (((InnerNetObject)Utils.GetPlayerById(val2.TargetPlayerId)).AmOwner) { instance.ClearVote(); } } } hudManager.SetHudActive(false); new LateTask(delegate { hudManager.SetHudActive(false); }, 0.3f, "SetHudActive in ClientGuess", shoudLog: false); } private static bool MsgToPlayerAndRole(string msg, out byte id, out CustomRoles role, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } MatchCollection matchCollection = new Regex("\\d+").Matches(msg); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { text += matchCollection[i]; } if (int.TryParse(text, out var result)) { id = Convert.ToByte(result); PlayerControl playerById = Utils.GetPlayerById(id); if ((Object)(object)playerById == (Object)null || playerById.Data.IsDead) { error = Translator.GetString("GuessNull"); role = CustomRoles.Crewmate; return false; } if (!ChatCommands.GetRoleByName(msg, out role)) { error = Translator.GetString("GuessHelp"); return false; } error = string.Empty; return true; } id = byte.MaxValue; error = Translator.GetString("GuessHelp"); role = CustomRoles.Crewmate; return false; } public static void TryHideMsg() { ChatUpdatePatch.DoBlockChat = true; CustomRoles[] collection = CustomRolesHelper.AllRoles.Where((CustomRoles x) => x != CustomRoles.NotAssigned).ToArray(); IRandom instance = IRandom.Instance; string[] array = new string[12] { "bet", "bt", "guess", "gs", "shoot", "st", "赌", "猜", "审判", "tl", "判", "审" }; for (int i = 0; i < 20; i++) { string text = "/"; if (instance.Next(1, 100) < 20) { text += "id"; } else { text += array[instance.Next(0, array.Length - 1)]; text += ((instance.Next(1, 100) < 50) ? string.Empty : " "); text += instance.Next(0, 15); text += ((instance.Next(1, 100) < 50) ? string.Empty : " "); CustomRoles role = collection.RandomElement(); text += ((instance.Next(1, 100) < 50) ? string.Empty : " "); text += Utils.GetRoleName(role); } PlayerControl val = Main.AllAlivePlayerControls.RandomElement(); DestroyableSingleton.Instance.Chat.AddChat(val, text, true); CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(text).EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } ChatUpdatePatch.DoBlockChat = false; } public static void CreateGuesserButton(MeetingHud __instance) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) PlayerVoteArea[] array = ((IEnumerable)__instance.playerStates).ToArray(); foreach (PlayerVoteArea pva in array) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.95f, 0.03f, -1.31f); obj.GetComponent().sprite = CustomButton.Get("TargetIcon"); PassiveButton component = obj.GetComponent(); ((UnityEventBase)component.OnClick).RemoveAllListeners(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { GuesserOnClick(pva.TargetPlayerId, __instance); })); } } } private static void GuesserSelectRole(Custom_Team Role, bool SetPage = true) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) currentTeamType = Role; if (SetPage) { Page = 1; } foreach (KeyValuePair> roleButton in RoleButtons) { int num = 0; Transform[] array = roleButton.Value.ToArray(); foreach (Transform val in array) { if (!((Object)(object)val == (Object)null)) { num++; if (num <= (Page - 1) * 40) { ((Component)val).gameObject.SetActive(false); } else if (Page * 40 < num) { ((Component)val).gameObject.SetActive(false); } else { ((Component)val).gameObject.SetActive(roleButton.Key == Role); } } } } foreach (KeyValuePair roleSelectButton in RoleSelectButtons) { if (!((Object)(object)roleSelectButton.Value == (Object)null)) { roleSelectButton.Value.color = new Color(0f, 0f, 0f, (roleSelectButton.Key == Role) ? 1f : 0.25f); } } } private static void GuesserOnClick(byte playerId, MeetingHud __instance) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0557: Unknown result type (might be due to invalid IL or missing references) //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_062d: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0a60: Unknown result type (might be due to invalid IL or missing references) //IL_0a6a: Unknown result type (might be due to invalid IL or missing references) PlayerControl pc = Utils.GetPlayerById(playerId); if ((Object)(object)pc == (Object)null || !pc.IsAlive() || (Object)(object)guesserUI != (Object)null || !GameStates.IsVoting) { return; } Transform container2; List info; Transform buttonTemplate; Transform maskTemplate; List buttons; Transform selectedButton; int ind; try { Page = 1; RoleButtons = new Dictionary>(); RoleSelectButtons = new Dictionary(); PageButtons = new List(); ((IEnumerable)__instance.playerStates).ToList().ForEach(delegate(PlayerVoteArea x) { ((Component)x).gameObject.SetActive(false); }); container2 = Object.Instantiate(GameObject.Find("PhoneUI").transform, ((Component)__instance).transform); ((Component)container2).transform.localPosition = new Vector3(0f, 0f, -200f); guesserUI = ((Component)container2).gameObject; info = new List(4) { 0, 0, 0, 0 }; buttonTemplate = ((Component)((Il2CppArrayBase)(object)__instance.playerStates)[0]).transform.FindChild("votePlayerBase"); maskTemplate = ((Component)((Il2CppArrayBase)(object)__instance.playerStates)[0]).transform.FindChild("MaskArea"); Transform val = ((Il2CppArrayBase)(object)__instance.playerStates)[0].Buttons.transform.Find("CancelButton"); ((Behaviour)textTemplate).enabled = true; if ((Object)(object)textTemplate.transform.FindChild("RoleTextMeeting") != (Object)null) { Object.Destroy((Object)(object)((Component)textTemplate.transform.FindChild("RoleTextMeeting")).gameObject); } Transform transform = new GameObject().transform; transform.SetParent(container2); Transform obj = Object.Instantiate(buttonTemplate, transform); ((Component)obj.FindChild("ControllerHighlight")).gameObject.SetActive(false); Transform obj2 = Object.Instantiate(maskTemplate, transform); ((Component)obj2).transform.localScale = new Vector3(2.88f, 0.8f, 1f); ((Component)obj2).transform.localPosition = new Vector3(0f, 0f, 1f); ((Component)obj).gameObject.GetComponent().sprite = ((Component)val).GetComponent().sprite; ((Component)transform).transform.localPosition = new Vector3(3.88f, 2.12f, -200f); ((Component)transform).transform.localScale = new Vector3(0.22f, 0.9f, 1f); ((Component)transform).transform.SetAsFirstSibling(); ((UnityEventBase)((Component)obj).GetComponent().OnClick).RemoveAllListeners(); ((UnityEvent)((Component)obj).GetComponent().OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { ((IEnumerable)__instance.playerStates).ToList().ForEach(delegate(PlayerVoteArea x) { ((Component)x).gameObject.SetActive(true); ((Component)x.Buttons.transform).gameObject.SetActive(false); }); Object.Destroy((Object)(object)((Component)container2).gameObject); })); ExitButton = ((Component)obj).GetComponent(); buttons = new List(); selectedButton = null; int num = 0; for (int i = 0; i < 4; i++) { if (PlayerControl.LocalPlayer.Is(CustomRoles.EvilGuesser)) { if (EvilGuesser.HideTabInGuesserUI(i)) { continue; } } else if (PlayerControl.LocalPlayer.Is(CustomRoles.NiceGuesser)) { if (NiceGuesser.HideTabInGuesserUI(i)) { continue; } } else if (PlayerControl.LocalPlayer.Is(CustomRoles.Doomsayer)) { if (Doomsayer.HideTabInGuesserUI(i)) { continue; } } else if (PlayerControl.LocalPlayer.Is(CustomRoles.Guesser)) { if (!Guesser.GCanGuessAdt.GetBool() && i == 3) { continue; } } else if (Options.GuesserMode.GetBool() && !PlayerControl.LocalPlayer.Is(CustomRoles.EvilGuesser) && !PlayerControl.LocalPlayer.Is(CustomRoles.NiceGuesser) && !PlayerControl.LocalPlayer.Is(CustomRoles.Doomsayer) && !PlayerControl.LocalPlayer.Is(CustomRoles.Guesser) && ((!Options.CrewCanGuessCrew.GetBool() && PlayerControl.LocalPlayer.Is(Custom_Team.Crewmate) && i == 0) || (!Options.ImpCanGuessImp.GetBool() && PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) && i == 1) || (!Options.CanGuessAddons.GetBool() && i == 3))) { continue; } Transform transform2 = new GameObject().transform; transform2.SetParent(container2); Transform val2 = Object.Instantiate(buttonTemplate, transform2); ((Component)val2.FindChild("ControllerHighlight")).gameObject.SetActive(false); Object.Instantiate(maskTemplate, transform2); TextMeshPro val3 = Object.Instantiate(textTemplate, val2); ((Component)val2).GetComponent().sprite = CustomButton.Get("GuessPlateWithKPD"); RoleSelectButtons.Add((Custom_Team)i, ((Component)val2).GetComponent()); transform2.localPosition = new Vector3(-3.1f + (float)num++ * 1.47f, 2.225f, -200f); transform2.localScale = new Vector3(0.53f, 0.53f, 1f); TextMeshPro val4 = val3; ((Graphic)val4).color = Color32.op_Implicit((Color32)((Custom_Team)i switch { Custom_Team.Crewmate => new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue), Custom_Team.Impostor => new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue), Custom_Team.Neutral => new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue), Custom_Team.Addon => new Color32(byte.MaxValue, (byte)154, (byte)206, byte.MaxValue), _ => throw new NotImplementedException(), })); Custom_Team custom_Team = (Custom_Team)i; ((TMP_Text)val3).text = Translator.GetString("Type" + custom_Team); ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; val3.transform.localPosition = new Vector3(0f, 0f, val3.transform.localPosition.z); Transform transform3 = val3.transform; transform3.localScale *= 1.6f; ((TMP_Text)val3).autoSizeTextContainer = true; if (PlayerControl.LocalPlayer.IsAlive()) { CreateTeamButton(val2, (Custom_Team)i); } } if (PlayerControl.LocalPlayer.IsAlive()) { CreatePage(IsNext: false, __instance, container2); CreatePage(IsNext: true, __instance, container2); } ind = 0; CustomRoles[] array = Array.Empty(); CustomRoles[] array2; if (Options.ShowOnlyEnabledRolesInGuesserUI.GetBool()) { List list = CustomRolesHelper.AllRoles.Where((CustomRoles role) => !role.IsGhostRole() && (role.IsEnable() || role.RoleExist(countDead: true))).ToList(); if (!list.Contains(CustomRoles.ImpostorTOHE)) { list.Add(CustomRoles.ImpostorTOHE); } if (!list.Contains(CustomRoles.ShapeshifterTOHE)) { list.Add(CustomRoles.ShapeshifterTOHE); } if (!list.Contains(CustomRoles.CrewmateTOHE)) { list.Add(CustomRoles.CrewmateTOHE); } if (!list.Contains(CustomRoles.ScientistTOHE)) { list.Add(CustomRoles.ScientistTOHE); } if (!list.Contains(CustomRoles.EngineerTOHE)) { list.Add(CustomRoles.EngineerTOHE); } if (!list.Contains(CustomRoles.Amnesiac)) { list.Add(CustomRoles.Amnesiac); } if (CustomRoles.Jackal.IsEnable() && !list.Contains(CustomRoles.Recruit)) { list.Add(CustomRoles.Recruit); } if (CustomRoles.Cultist.IsEnable() && !list.Contains(CustomRoles.Charmed)) { list.Add(CustomRoles.Charmed); } if (CustomRoles.Infectious.IsEnable() && !list.Contains(CustomRoles.Infected)) { list.Add(CustomRoles.Infected); } if (CustomRoles.Virus.IsEnable() && !list.Contains(CustomRoles.Contagious)) { list.Add(CustomRoles.Contagious); } if (CustomRoles.Admirer.IsEnable() && !list.Contains(CustomRoles.Admired)) { list.Add(CustomRoles.Admired); } int num2 = 0; array2 = new CustomRoles[list.Count]; foreach (CustomRoles item in list) { array2[num2] = item; num2++; } array = array2; } else { List list2 = new List(); foreach (CustomRoles item2 in CustomRolesHelper.AllRoles.Where((CustomRoles role) => !role.IsGhostRole())) { list2.Add(item2); } array = list2.ToArray(); } array2 = (from kv in array.ToDictionary((CustomRoles role) => role, (CustomRoles role) => Utils.GetRoleName(role)) orderby kv.Value select kv.Key).ToArray(); foreach (CustomRoles customRoles in array2) { if (!customRoles.IsVanilla()) { bool flag; switch (customRoles) { case CustomRoles.ChiefOfPolice: case CustomRoles.SpeedBooster: case CustomRoles.SuperStar: case CustomRoles.Solsticer: case CustomRoles.Mini: case CustomRoles.Killer: case CustomRoles.GM: case CustomRoles.NotAssigned: case CustomRoles.Cyber: case CustomRoles.Flash: case CustomRoles.LastImpostor: case CustomRoles.Mare: case CustomRoles.Oblivious: case CustomRoles.Onbound: case CustomRoles.Rebound: flag = true; break; default: flag = false; break; } if (!flag) { CreateRole(customRoles); } } } Transform transform4 = ((Component)container2).transform; transform4.localScale *= 0.75f; GuesserSelectRole(Custom_Team.Crewmate); ReloadPage(); } catch (Exception ex) { Logger.Exception(ex, "Guesser UI", 1002, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); return; } PlayerControl.LocalPlayer.RPCPlayCustomSound("Gunload"); static void CreatePage(bool IsNext, MeetingHud __instance, Transform container) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) Transform obj3 = ((Component)((Il2CppArrayBase)(object)__instance.playerStates)[0]).transform.FindChild("votePlayerBase"); Transform val6 = ((Component)((Il2CppArrayBase)(object)__instance.playerStates)[0]).transform.FindChild("MaskArea"); ((Il2CppArrayBase)(object)__instance.playerStates)[0].Buttons.transform.Find("CancelButton"); Transform transform7 = new GameObject().transform; transform7.SetParent(container); Transform val7 = Object.Instantiate(obj3, transform7); ((Component)val7.FindChild("ControllerHighlight")).gameObject.SetActive(false); Object.Instantiate(val6, transform7); TextMeshPro val8 = Object.Instantiate(textTemplate, val7); ((Component)val7).GetComponent().sprite = CustomButton.Get("GuessPlateWithKPD"); transform7.localPosition = (IsNext ? new Vector3(3.535f, -2.2f, -200f) : new Vector3(-3.475f, -2.2f, -200f)); transform7.localScale = new Vector3(0.55f, 0.55f, 1f); ((Graphic)val8).color = Color.white; ((TMP_Text)val8).text = Translator.GetString(IsNext ? "NextPage" : "PreviousPage"); ((TMP_Text)val8).alignment = (TextAlignmentOptions)514; val8.transform.localPosition = new Vector3(0f, 0f, val8.transform.localPosition.z); Transform transform8 = val8.transform; transform8.localScale *= 1.6f; ((TMP_Text)val8).autoSizeTextContainer = true; if (!IsNext && Page <= 1) { ((Component)val7).GetComponent().color = new Color(1f, 1f, 1f, 0.1f); } ((UnityEvent)((Component)val7).GetComponent().OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { ClickEvent(); })); PageButtons.Add(((Component)val7).GetComponent()); void ClickEvent() { if (IsNext) { Page++; } else { Page--; } if (Page < 1) { Page = 1; } ReloadPage(); } } void CreateRole(CustomRoles role) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) bool isEvilMini = Mini.IsEvilMini; if (role == CustomRoles.EvilMini) { Mini.IsEvilMini = true; } else if (role == CustomRoles.NiceMini) { Mini.IsEvilMini = false; } if (40 <= info[(int)role.GetCustomRoleTeam()]) { info[(int)role.GetCustomRoleTeam()] = 0; } Transform transform5 = new GameObject().transform; transform5.SetParent(container2); Transform button = Object.Instantiate(buttonTemplate, transform5); ((Component)button.FindChild("ControllerHighlight")).gameObject.SetActive(false); Object.Instantiate(maskTemplate, transform5); TextMeshPro val5 = Object.Instantiate(textTemplate, button); ((Component)button).GetComponent().sprite = CustomButton.Get("GuessPlate"); if (!RoleButtons.ContainsKey(role.GetCustomRoleTeam())) { RoleButtons.Add(role.GetCustomRoleTeam(), new List()); } RoleButtons[role.GetCustomRoleTeam()].Add(button); buttons.Add(button); int num3 = info[(int)role.GetCustomRoleTeam()] / 5; int num4 = info[(int)role.GetCustomRoleTeam()] % 5; transform5.localPosition = new Vector3(-3.47f + 1.75f * (float)num4, 1.5f - 0.45f * (float)num3, -200f); transform5.localScale = new Vector3(0.55f, 0.55f, 1f); ((TMP_Text)val5).text = Translator.GetString(role.ToString()); ((Graphic)val5).color = Utils.GetRoleColor(role); ((TMP_Text)val5).alignment = (TextAlignmentOptions)514; val5.transform.localPosition = new Vector3(0f, 0f, val5.transform.localPosition.z); Transform transform6 = val5.transform; transform6.localScale *= 1.6f; ((TMP_Text)val5).autoSizeTextContainer = true; ((UnityEventBase)((Component)button).GetComponent().OnClick).RemoveAllListeners(); if (PlayerControl.LocalPlayer.IsAlive()) { ((UnityEvent)((Component)button).GetComponent().OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 if ((Object)(object)selectedButton != (Object)(object)button) { selectedButton = button; buttons.ForEach(delegate(Transform x) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) ((Component)x).GetComponent().color = (((Object)(object)x == (Object)(object)selectedButton) ? Utils.GetRoleColor(PlayerControl.LocalPlayer.GetCustomRole()) : Color.white); }); } else if (((int)__instance.state == 3 || (int)__instance.state == 2) && PlayerControl.LocalPlayer.IsAlive()) { Logger.Msg($"Click: {pc.GetNameWithRole().RemoveHtmlTags()} => {role}", "Guesser UI", escapeCRLF: true, 975, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { GuesserMsg(PlayerControl.LocalPlayer, $"/bt {playerId} {Translator.GetString(role.ToString())}", isUI: true); } else { SendRPC(playerId, role); } ((IEnumerable)__instance.playerStates).ToList().ForEach(delegate(PlayerVoteArea x) { ((Component)x).gameObject.SetActive(true); ((Component)x.Buttons.transform).gameObject.SetActive(false); }); Object.Destroy((Object)(object)((Component)container2).gameObject); ((Behaviour)textTemplate).enabled = false; } })); } info[(int)role.GetCustomRoleTeam()]++; ind++; Mini.IsEvilMini = isEvilMini; } static void CreateTeamButton(Transform Teambutton, Custom_Team type) { ((UnityEvent)((Component)Teambutton).GetComponent().OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { GuesserSelectRole(type); ReloadPage(); })); } static void ReloadPage() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) PageButtons[0].color = new Color(1f, 1f, 1f, 1f); PageButtons[1].color = new Color(1f, 1f, 1f, 1f); if (RoleButtons[currentTeamType].Count / 40 + ((RoleButtons[currentTeamType].Count % 40 != 0) ? 1 : 0) < Page) { Page--; PageButtons[1].color = new Color(1f, 1f, 1f, 0.1f); } else if (RoleButtons[currentTeamType].Count / 40 + ((RoleButtons[currentTeamType].Count % 40 != 0) ? 1 : 0) < Page + 1) { PageButtons[1].color = new Color(1f, 1f, 1f, 0.1f); } if (Page <= 1) { Page = 1; PageButtons[0].color = new Color(1f, 1f, 1f, 0.1f); } GuesserSelectRole(currentTeamType, SetPage: false); } } private static void SendRPC(int playerId, CustomRoles role) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)119, (SendOption)1, -1); val.Write(playerId); val.Write((int)role); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader, PlayerControl pc) { Logger.Msg($"{pc}", "PlayerControl pc", escapeCRLF: true, 1034, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); int value = reader.ReadInt32(); Logger.Msg($"{value}", "Player Id", escapeCRLF: true, 1037, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); CustomRoles value2 = (CustomRoles)reader.ReadInt32(); Logger.Msg($"{value2}", "Role Int32", escapeCRLF: true, 1040, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); Logger.Msg(Translator.GetString(value2.ToString()) ?? "", "Role String", escapeCRLF: true, 1041, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GuessManager.cs"); GuesserMsg(pc, $"/bt {value} {Translator.GetString(value2.ToString())}", isUI: true); } } public class HashAuth { public readonly string HashValue; private readonly string salt; private readonly HashAlgorithm algorithm; public HashAuth(string hashValue, string salt = null, HashAlgorithm algorithm = null) { HashValue = hashValue; this.salt = salt; this.algorithm = algorithm ?? SHA256.Create(); base..ctor(); } public bool CheckString(string value) { string text = CalculateHash(value); return HashValue == text; } public string CalculateHash(string source) { return CalculateHash(source, salt, algorithm); } public static string CalculateHash(string source, string salt = null, HashAlgorithm algorithm = null) { if (algorithm == null) { algorithm = SHA256.Create(); } if (salt != null) { source += salt; } byte[] bytes = Encoding.UTF8.GetBytes(source); byte[] array = algorithm.ComputeHash(bytes); StringBuilder stringBuilder = new StringBuilder(); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("x2")); } return stringBuilder.ToString(); } public static HashAuth CreateByUnhashedValue(string value, string salt = null) { SHA256 sHA = SHA256.Create(); string text = CalculateHash(value, salt, sHA); Logger.Info($"ハッシュ値算出結果: {value} => {text} {((salt == null) ? "" : ("(salt: " + salt + ")"))}", "HashAuth", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\HashAuth.cs"); Logger.Warn("以上の値をソースコード上にペーストしてください。", "HashAuth", escapeCRLF: true, 55, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\HashAuth.cs"); return new HashAuth(text, salt, sHA); } } internal class LateTask { public string name; public float timer; public bool shouldLog; public Action action; public static List Tasks = new List(); public bool Run(float deltaTime) { timer -= deltaTime; if (timer <= 0f) { action(); return true; } return false; } public LateTask(Action action, float time, string name = "No Name Task", bool shoudLog = true) { this.action = action; timer = time; this.name = name; shouldLog = shoudLog; Tasks.Add(this); if (name != "" && shoudLog) { Logger.Info("\"" + name + "\" is created", "LateTask", escapeCRLF: true, 31, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LateTask.cs"); } } public static void Update(float deltaTime) { List list = new List(); LateTask[] array = Tasks.ToArray(); foreach (LateTask lateTask in array) { try { if (lateTask.Run(deltaTime)) { if (lateTask.name != "" && lateTask.shouldLog) { Logger.Info("\"" + lateTask.name + "\" is finished", "LateTask", escapeCRLF: true, 44, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LateTask.cs"); } list.Add(lateTask); } } catch (Exception ex) { Logger.Error($"{ex.GetType()}: {ex.Message} in \"{lateTask.name}\"\n{ex.StackTrace}", "LateTask.Error", escapeCRLF: false, 50, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LateTask.cs"); list.Add(lateTask); } } list.ForEach(delegate(LateTask task) { Tasks.Remove(task); }); } } internal static class LocateArrow { private class ArrowInfo { public byte From; public Vector3 To; public ArrowInfo(byte from, Vector3 to) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) From = from; To = to; base..ctor(); } public bool Equals(ArrowInfo obj) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (From == obj.From) { return To == obj.To; } return false; } public override string ToString() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) return $"(From:{From} To:{To})"; } } private static readonly Dictionary LocateArrows = new Dictionary(); private static readonly string[] Arrows = new string[9] { "↑", "↗", "→", "↘", "↓", "↙", "←", "↖", "・" }; public static void Init() { LocateArrows.Clear(); } public static void Add(byte seer, Vector3 locate) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ArrowInfo arrowInfo = new ArrowInfo(seer, locate); if (!LocateArrows.Any((KeyValuePair a) => a.Key.Equals(arrowInfo))) { LocateArrows[arrowInfo] = "・"; } } public static void Remove(byte seer, Vector3 locate) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ArrowInfo arrowInfo = new ArrowInfo(seer, locate); ArrowInfo[] array = new List(LocateArrows.Keys.Where((ArrowInfo k) => k.Equals(arrowInfo))).ToArray(); foreach (ArrowInfo key in array) { LocateArrows.Remove(key); } } public static void RemoveAllTarget(byte seer) { ArrowInfo[] array = new List(LocateArrows.Keys.Where((ArrowInfo k) => k.From == seer)).ToArray(); foreach (ArrowInfo key in array) { LocateArrows.Remove(key); } } public static string GetArrows(PlayerControl seer) { string text = ""; ArrowInfo[] array = LocateArrows.Keys.Where((ArrowInfo ai) => ai.From == seer.PlayerId).ToArray(); foreach (ArrowInfo key in array) { text += LocateArrows[key]; } return text; } public static bool HasLocateArrows(PlayerControl seer) { return LocateArrows.Keys.Any((ArrowInfo a) => a.From == seer.PlayerId); } public static void OnFixedUpdate(PlayerControl seer) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsInTask) { return; } _ = seer.PlayerId; bool flag = !seer.IsAlive(); List list = new List(LocateArrows.Keys.Where((ArrowInfo a) => a.From == seer.PlayerId)); if (list.Count == 0) { return; } bool flag2 = false; ArrowInfo[] array = list.ToArray(); foreach (ArrowInfo arrowInfo in array) { Vector3 to = arrowInfo.To; if (flag) { LocateArrows.Remove(arrowInfo); flag2 = true; continue; } Vector3 val = to - ((Component)seer).transform.position; int num = ((!(((Vector3)(ref val)).magnitude < 2f)) ? ((int)(((double)(Vector3.SignedAngle(Vector3.down, val, Vector3.back) + 180f) + 22.5) / 45.0) % 8) : 8); string text = Arrows[num]; if (LocateArrows[arrowInfo] != text) { LocateArrows[arrowInfo] = text; flag2 = true; } } if (flag2 && !((InnerNetObject)seer).AmOwner) { Utils.NotifyRoles(seer, null, isForMeeting: false, NoCache: false, ForceLoop: false); } } } public interface ICustomWriter { void Write(float val); void Write(string val); void Write(ulong val); void Write(int val); void Write(uint val); void Write(ushort val); void Write(byte val); void Write(sbyte val); void Write(bool val); void Write(Il2CppStructArray bytes); void Write(Il2CppStructArray bytes, int offset, int length); void WriteBytesAndSize(Il2CppStructArray bytes); void WritePacked(int val); void WritePacked(uint val); void WriteNetObject(InnerNetObject obj); } public class WriterProxy : ICustomWriter { public MessageWriter Writer { get; private set; } public WriterProxy(MessageWriter writer) { Writer = writer; base..ctor(); } public void Write(float val) { Writer.Write(val); } public void Write(string val) { Writer.Write(val); } public void Write(ulong val) { Writer.Write(val); } public void Write(int val) { Writer.Write(val); } public void Write(uint val) { Writer.Write(val); } public void Write(ushort val) { Writer.Write(val); } public void Write(byte val) { Writer.Write(val); } public void Write(sbyte val) { Writer.Write(val); } public void Write(bool val) { Writer.Write(val); } public void Write(Il2CppStructArray bytes) { Writer.Write(bytes); } public void Write(Il2CppStructArray bytes, int offset, int length) { Writer.Write(bytes, offset, length); } public void WriteBytesAndSize(Il2CppStructArray bytes) { Writer.WriteBytesAndSize(bytes); } public void WritePacked(int val) { Writer.WritePacked(val); } public void WritePacked(uint val) { Writer.WritePacked(val); } public void WriteNetObject(InnerNetObject obj) { MessageExtensions.WriteNetObject(Writer, obj); } } [HarmonyPatch] public class ModUpdater { private static readonly string URL_Github = "https://api.github.com/repos/0xDrMoe/TownofHost-Enhanced"; public static bool hasUpdate = false; public static bool forceUpdate = false; public static bool isBroken = false; public static bool isChecked = false; public static bool isFail = false; public static DateTime? latestVersion = null; public static string latestTitle = null; public static string downloadUrl = null; public static string notice = null; public static GenericPopup InfoPopup; public static PassiveButton updateButton; private static readonly object downloadLock = new object(); private static FileStream cachedfileStream; [HarmonyPatch(typeof(MainMenuManager), "Start")] [HarmonyPostfix] [HarmonyPriority(100)] public static void Start_Postfix() { ResetUpdateButton(); if (!isChecked) { Main.Instance.StartCoroutine(PrefixCoroutine()); } } public static IEnumerator PrefixCoroutine() { NewVersionCheck(); DeleteOldFiles(); InfoPopup = Object.Instantiate(DestroyableSingleton.Instance.TwitchPopup); ((Object)InfoPopup).name = "InfoPopup"; ((Component)InfoPopup.TextAreaTMP).GetComponent().sizeDelta = new Vector2(2.5f, 2f); if (!isChecked) { yield return CheckReleaseFromGithub(Main.BetaBuildURL.Value != ""); Logger.Warn("Check for updated results: " + !isFail, "CheckRelease", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); Logger.Info("hasupdate: " + hasUpdate, "CheckRelease", escapeCRLF: true, 55, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); Logger.Info("forceupdate: " + forceUpdate, "CheckRelease", escapeCRLF: true, 56, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); Logger.Info("downloadUrl: " + downloadUrl, "CheckRelease", escapeCRLF: true, 57, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); DateTime? dateTime = latestVersion; Logger.Info("latestVersionl: " + dateTime.ToString(), "CheckRelease", escapeCRLF: true, 58, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); ResetUpdateButton(); } } public static void ResetUpdateButton() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)updateButton == (Object)null) { updateButton = MainMenuManagerPatch.CreateButton("updateButton", new Vector3(3.68f, -2.68f, 1f), new Color32(byte.MaxValue, (byte)165, (byte)0, byte.MaxValue), new Color32(byte.MaxValue, (byte)200, (byte)0, byte.MaxValue), delegate { StartUpdate(downloadUrl); }, Translator.GetString("update")); ((Component)updateButton).transform.localScale = Vector3.one; } ((Component)updateButton).gameObject.SetActive(hasUpdate); } public static string Get(string url) { string text = ""; Stream stream = new HttpClient().GetAsync(url).Result.Content.ReadAsStream(); try { using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } finally { stream.Close(); } } public static IEnumerator CheckReleaseFromGithub(bool beta = false) { Logger.Warn("Start checking for updates from Github", "CheckRelease", escapeCRLF: true, 97, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); string text = URL_Github + "/releases/latest"; UnityWebRequest request = UnityWebRequest.Get(text); request.timeout = 15; request.SetRequestHeader("Connection", "Keep-Alive"); request.SetRequestHeader("User-Agent", "Mozilla/5.0"); request.chunkedTransfer = false; yield return request.SendWebRequest(); yield return (object)new WaitForSeconds(0.5f); if ((int)request.result != 1) { Logger.Error($"Request failed: {request.error}: {request.result}", "CheckRelease", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); isFail = true; yield break; } JObject val = JsonConvert.DeserializeObject(request.downloadHandler.text); if (beta) { latestTitle = ((Object)val["name"]).ToString(); downloadUrl = ((Object)val["url"]).ToString(); hasUpdate = latestTitle != "f6840257"; } else { JToken obj = val["published_at"]; string s = ((obj != null) ? ((Object)obj).ToString() : null); latestVersion = (DateTime.TryParse(s, out var result) ? result : DateTime.MinValue); latestTitle = $"Day: {latestVersion?.Day} Month: {latestVersion?.Month} Year: {latestVersion?.Year}"; JArray val2 = ((Il2CppObjectBase)val["assets"]).TryCast(); for (int i = 0; i < ((JContainer)val2).Count; i++) { if (((Object)val2[i][Object.op_Implicit("name")]).ToString().ToLower() == "tohe.dll") { downloadUrl = ((Object)val2[i][Object.op_Implicit("browser_download_url")]).ToString(); Logger.Info("Github downloadUrl is set to " + downloadUrl, "CheckRelease", escapeCRLF: true, 139, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); } } DateTime dateTime = DateTime.ParseExact("2024.0813.203.9999".Substring(5, 4), "MMdd", CultureInfo.InvariantCulture); int num = int.Parse("2024.0813.203.9999".Substring(0, 4)); dateTime = dateTime.AddYears(num - dateTime.Year); Logger.Info($"Day: {dateTime.Day} Month: {dateTime.Month} Year: {dateTime.Year}", "PluginVersion", escapeCRLF: true, 146, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); hasUpdate = latestVersion?.Date > dateTime.Date; } Logger.Info("hasupdate: " + hasUpdate, "Github", escapeCRLF: true, 150, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); Logger.Info("downloadUrl: " + downloadUrl, "Github", escapeCRLF: true, 151, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); DateTime? dateTime2 = latestVersion; Logger.Info("latestVersion: " + dateTime2.ToString(), "Github", escapeCRLF: true, 152, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); Logger.Info("latestTitle: " + latestTitle, "Github", escapeCRLF: true, 153, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); if (hasUpdate && (downloadUrl == null || downloadUrl == "")) { Logger.Error("Failed to get download address", "CheckRelease", escapeCRLF: true, 157, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); isFail = true; yield break; } isChecked = true; isBroken = false; request.Dispose(); isFail = false; } public static void StartUpdate(string url) { ShowPopup(Translator.GetString("updatePleaseWait"), (StringNames)149); Main.Instance.StartCoroutine(DownloadDLL(url)); } public static bool NewVersionCheck() { try { _ = Assembly.GetExecutingAssembly().Location; if (Directory.Exists("TOH_DATA") && File.Exists("./TOHE-DATA/BanWords.txt")) { new DirectoryInfo("TOH_DATA").Delete(recursive: true); Logger.Warn("Deleting old data:TOH_DATA", "NewVersionCheck", escapeCRLF: true, 186, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); } } catch (Exception ex) { Logger.Exception(ex, "NewVersionCheck", 191, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); return false; } return true; } public static void StopDownload() { cachedfileStream.Dispose(); Main.Instance.StopAllCoroutines(); Main.Instance.StartCoroutine(DeleteFilesAfterCancel()); } public static IEnumerator DeleteFilesAfterCancel() { ShowPopup(Translator.GetString("deletingFiles"), (StringNames)0); yield return (object)new WaitForSeconds(2f); InfoPopup.Close(); yield return (object)new WaitForSeconds(0.3f); DeleteOldFiles(); Application.targetFrameRate = (Main.UnlockFPS.Value ? 165 : 60); } public static void DeleteOldFiles() { string? directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string searchPattern = "TOHE.dll*"; string[] files = Directory.GetFiles(directoryName, searchPattern); try { string[] array = files; foreach (string text in array) { if (Path.GetFileName(text).EndsWith(".bak") || Path.GetFileName(text).EndsWith(".temp")) { Logger.Info(text + " will be deleted", "DeleteOldFiles", escapeCRLF: true, 223, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); File.Delete(text); } } } catch (Exception value) { Logger.Error($"Failed to clear update residue\n{value}", "DeleteOldFiles", escapeCRLF: true, 230, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); } } private static IEnumerator DownloadDLL(string url) { string savePath = "BepInEx/plugins/TOHE.dll.temp"; Application.targetFrameRate = -1; DeleteOldFiles(); UnityWebRequest request = UnityWebRequest.Get(url); request.timeout = 10; request.SetRequestHeader("Connection", "Keep-Alive"); request.SetRequestHeader("User-Agent", "Mozilla/5.0"); request.chunkedTransfer = false; yield return request.SendWebRequest(); if ((int)request.result != 1) { Logger.Error($"File retrieval failed with status code: {request.responseCode}", "DownloadDLL", escapeCRLF: false, 253, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ModUpdater.cs"); ShowPopup(Translator.GetString("updateManually"), (StringNames)2089, showButton: true, (Action)InfoPopup.Close); Application.targetFrameRate = (Main.UnlockFPS.Value ? 165 : 60); yield break; } ulong total = request.downloadedBytes; using (MemoryStream stream = new MemoryStream(Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)request.downloadHandler.data))) { using FileStream fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true); cachedfileStream = fileStream; byte[] buffer = new byte[1024]; long readLength = 0L; while (true) { int num; int length = (num = stream.Read(buffer, 0, buffer.Length)); if (num <= 0) { break; } yield return null; fileStream.Write(buffer, 0, length); readLength += length; double? num2 = Math.Round((double)readLength / (double)total * 100.0, 2, MidpointRounding.ToZero); lock (downloadLock) { DownloadCallBack(total, readLength, num2.GetValueOrDefault()); } } } string location = Assembly.GetExecutingAssembly().Location; File.Move(location, location + ".bak"); File.Move(savePath, location); ShowPopup(Translator.GetString("updateRestart"), (StringNames)2089, showButton: true, (Action)Application.Quit); } private static void DownloadCallBack(ulong total, long downloaded, double progress) { ShowPopup($"{Translator.GetString("updateInProgress")}\n{(float)downloaded / 1048576f:F2}/{(float)total / 1048576f:F2} MB ({progress}%)", (StringNames)149, showButton: true, StopDownload); } private static void ShowPopup(string message, StringNames buttonText, bool showButton = false, Action onClick = null) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown if (!((Object)(object)InfoPopup != (Object)null)) { return; } InfoPopup.Show(message); Transform val = ((Component)InfoPopup).transform.FindChild("ExitGame"); if (!((Object)(object)val != (Object)null)) { return; } ((Component)val).gameObject.SetActive(showButton); ((Component)val.GetChild(0)).GetComponent().TargetText = buttonText; ((Component)val.GetChild(0)).GetComponent().ResetText(); ((Component)val).GetComponent().OnClick = new ButtonClickedEvent(); if (onClick != null) { ((UnityEvent)((Component)val).GetComponent().OnClick).AddListener(UnityAction.op_Implicit(onClick)); return; } ((UnityEvent)((Component)val).GetComponent().OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { InfoPopup.Close(); })); } } public static class NameColorManager { public static string ApplyNameColorData(this string name, PlayerControl seer, PlayerControl target, bool isMeeting) { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted) { return name; } if (!TryGetData(seer, target, out var colorCode) && KnowTargetRoleColor(seer, target, isMeeting, out var color)) { colorCode = ((color == "") ? target.GetRoleColorCode() : color); } string text = ""; string text2 = ""; if (colorCode != "") { if (!colorCode.StartsWith('#')) { colorCode = "#" + colorCode; } text = ""; text2 = ""; } return text + name + text2; } private static bool KnowTargetRoleColor(PlayerControl seer, PlayerControl target, bool isMeeting, out string color) { if ((Object)(object)seer != (Object)(object)target) { target = DollMaster.SwapPlayerInfo(target); } color = seer.GetRoleClass()?.PlayerKnowTargetColor(seer, target); if (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) { color = ((seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool() && (Object)(object)seer != (Object)(object)target) ? Main.roleColors[CustomRoles.Egoist] : Main.roleColors[CustomRoles.Impostor]); } if (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool()) { color = Main.roleColors[CustomRoles.Impostor]; } if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) { color = Main.roleColors[CustomRoles.Madmate]; } if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) { color = Main.roleColors[CustomRoles.Madmate]; } if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool()) { color = Main.roleColors[CustomRoles.Madmate]; } if (Cultist.NameRoleColor(seer, target)) { color = Main.roleColors[CustomRoles.Cultist]; } if (seer.Is(CustomRoles.Admirer) && target.Is(CustomRoles.Admired)) { color = Main.roleColors[CustomRoles.Admirer]; } if (seer.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer)) { color = Main.roleColors[CustomRoles.Admirer]; } if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) { color = "bf1313"; } if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) { color = Main.roleColors[seer.GetCustomRole()]; } if (seer.Is(CustomRoles.Refugee) && target.Is(Custom_Team.Impostor)) { color = Main.roleColors[CustomRoles.ImpostorTOHE]; } if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Refugee)) { color = Main.roleColors[CustomRoles.Refugee]; } if (Infectious.InfectedKnowColorOthersInfected(seer, target)) { color = Main.roleColors[CustomRoles.Infectious]; } if (!seer.Is(CustomRoles.Visionary) && target.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) { color = Main.roleColors[CustomRoles.Cyber]; } if (seer.Is(CustomRoles.Necroview) && seer.IsAlive() && target.Data.IsDead && !target.IsAlive()) { color = Necroview.NameColorOptions(target); } if (Jackal.JackalKnowRole(seer, target)) { color = Main.roleColors[CustomRoles.Jackal]; } if (target.Is(CustomRoles.Mare) && Utils.IsActive((SystemTypes)7) && !isMeeting) { color = Main.roleColors[CustomRoles.Mare]; } if (Virus.KnowRoleColor(seer, target) != "") { color = Virus.KnowRoleColor(seer, target); } if (color != "" && color != string.Empty) { return true; } if (!((Object)(object)seer == (Object)(object)target) && (!Main.GodMode.Value || !((InnerNetObject)seer).AmOwner) && Options.CurrentGameMode != CustomGameMode.FFA && (!Main.VisibleTasksCount || !Main.PlayerStates[seer.Data.PlayerId].IsDead || !seer.Data.IsDead || seer.IsAlive() || !Options.GhostCanSeeOtherRoles.GetBool()) && !seer.Is(CustomRoles.GM) && !target.Is(CustomRoles.GM) && !target.GetRoleClass().OthersKnowTargetRoleColor(seer, target) && !Mimic.CanSeeDeadRoles(seer, target) && (!seer.Is(Custom_Team.Impostor) || !target.Is(Custom_Team.Impostor)) && (!seer.Is(CustomRoles.Madmate) || !target.Is(Custom_Team.Impostor) || !Madmate.MadmateKnowWhosImp.GetBool()) && (!seer.Is(Custom_Team.Impostor) || !target.Is(CustomRoles.Madmate) || !Madmate.ImpKnowWhosMadmate.GetBool()) && (!seer.Is(CustomRoles.Madmate) || !target.Is(CustomRoles.Madmate) || !Madmate.MadmateKnowWhosMadmate.GetBool()) && !Workaholic.OthersKnowWorka(target) && (!target.Is(CustomRoles.Gravestone) || !Main.PlayerStates[target.Data.PlayerId].IsDead)) { return Mare.KnowTargetRoleColor(target, isMeeting); } return true; } public static bool TryGetData(PlayerControl seer, PlayerControl target, out string colorCode) { colorCode = ""; if (!Main.PlayerStates[seer.PlayerId].TargetColorData.TryGetValue(target.PlayerId, out var value)) { return false; } colorCode = value; return true; } public static void Add(byte seerId, byte targetId, string colorCode = "") { if (colorCode == "") { PlayerControl playerById = Utils.GetPlayerById(targetId); if ((Object)(object)playerById == (Object)null) { return; } colorCode = playerById.GetRoleColorCode(); } PlayerState playerState = Main.PlayerStates[seerId]; if (!playerState.TargetColorData.TryGetValue(targetId, out var value) || !(colorCode == value)) { playerState.TargetColorData.Add(targetId, colorCode); SendRPC(seerId, targetId, colorCode); } } public static void Remove(byte seerId, byte targetId) { PlayerState playerState = Main.PlayerStates[seerId]; if (playerState.TargetColorData.ContainsKey(targetId)) { playerState.TargetColorData.Remove(targetId); SendRPC(seerId, targetId); } } public static void RemoveAll(byte seerId) { Main.PlayerStates[seerId].TargetColorData.Clear(); SendRPC(seerId); } private static void SendRPC(byte seerId, byte targetId = byte.MaxValue, string colorCode = "") { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)116, (SendOption)1, -1); val.Write(seerId); val.Write(targetId); val.Write(colorCode); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader) { byte seerId = reader.ReadByte(); byte b = reader.ReadByte(); string text = reader.ReadString(); if (b == byte.MaxValue) { RemoveAll(seerId); } else if (text == "") { Remove(seerId, b); } else { Add(seerId, b, text); } } } public static class NameNotifyManager { public static readonly Dictionary Notice = new Dictionary(); public static void Reset() { Notice.Clear(); } public static bool Notifying(this PlayerControl pc) { return Notice.ContainsKey(pc.PlayerId); } public static void Notify(this PlayerControl pc, string text, float time = 4f, bool sendInLog = true) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (((InnerNetClient)AmongUsClient.Instance).AmHost && !((Object)(object)pc == (Object)null) && GameStates.IsInTask) { if (!text.Contains(" AllValues; public OptionBackupData(IGameOptions option) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected I4, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) AllValues = new List(32); ByteOptionNames[] allValues = EnumHelper.GetAllValues(); byte value = default(byte); foreach (ByteOptionNames val in allValues) { if (option.TryGetByte(val, ref value)) { AllValues.Add(new ByteOptionBackupValue(val, value)); } } BoolOptionNames[] allValues2 = EnumHelper.GetAllValues(); bool value2 = default(bool); foreach (BoolOptionNames val2 in allValues2) { if ((int)val2 != 2 && option.TryGetBool(val2, ref value2)) { AllValues.Add(new BoolOptionBackupValue(val2, value2)); } } FloatOptionNames[] allValues3 = EnumHelper.GetAllValues(); float value3 = default(float); foreach (FloatOptionNames val3 in allValues3) { if (option.TryGetFloat(val3, ref value3)) { AllValues.Add(new FloatOptionBackupValue(val3, value3)); } } Int32OptionNames[] allValues4 = EnumHelper.GetAllValues(); int value4 = default(int); foreach (Int32OptionNames val4 in allValues4) { if (option.TryGetInt(val4, ref value4)) { AllValues.Add(new IntOptionBackupValue(val4, value4)); } } AllValues.Add(new IntOptionBackupValue((Int32OptionNames)9, option.MaxPlayers)); AllValues.Add(new UIntOptionBackupValue((UInt32OptionNames)1, (uint)(int)option.Keywords)); RoleTypes[] array = new RoleTypes[7]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); RoleTypes[] array2 = (RoleTypes[])(object)array; foreach (RoleTypes val5 in array2) { AllValues.Add(new RoleRateBackupValue(val5, option.RoleOptions.GetNumPerGame(val5), option.RoleOptions.GetChancePerGame(val5))); } } public IGameOptions Restore(IGameOptions option) { OptionBackupValue[] array = AllValues.ToArray(); for (int i = 0; i < array.Length; i++) { array[i].Restore(option); } return option; } public byte GetByte(ByteOptionNames name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return this.Get(name); } public bool GetBool(BoolOptionNames name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return this.Get(name); } public float GetFloat(FloatOptionNames name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return this.Get(name); } public int GetInt(Int32OptionNames name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return this.Get(name); } public uint GetUInt(UInt32OptionNames name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return this.Get(name); } public TValue Get(TKey name) where TKey : Enum { OptionBackupValueBase optionBackupValueBase = AllValues.OfType>().FirstOrDefault((OptionBackupValueBase val) => val.OptionName.Equals(name)); if (optionBackupValueBase != null) { return optionBackupValueBase.Value; } return default(TValue); } } public abstract class OptionBackupValue { public abstract void Restore(IGameOptions option); } public abstract class OptionBackupValueBase : OptionBackupValue where NameT : Enum { public readonly NameT OptionName; public readonly ValueT Value; protected OptionBackupValueBase(NameT name, ValueT value) { OptionName = name; Value = value; base..ctor(); } } public class ByteOptionBackupValue : OptionBackupValueBase { public ByteOptionBackupValue(ByteOptionNames name, byte value) : base(name, value) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) public override void Restore(IGameOptions option) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) option.SetByte(OptionName, Value); } } public class BoolOptionBackupValue : OptionBackupValueBase { public BoolOptionBackupValue(BoolOptionNames name, bool value) : base(name, value) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) public override void Restore(IGameOptions option) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)OptionName != 2) { option.SetBool(OptionName, Value); } } } public class FloatOptionBackupValue : OptionBackupValueBase { public FloatOptionBackupValue(FloatOptionNames name, float value) : base(name, value) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) public override void Restore(IGameOptions option) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) option.SetFloat(OptionName, Value); } } public class IntOptionBackupValue : OptionBackupValueBase { public IntOptionBackupValue(Int32OptionNames name, int value) : base(name, value) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) public override void Restore(IGameOptions option) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) option.SetInt(OptionName, Value); } } public class UIntOptionBackupValue : OptionBackupValueBase { public UIntOptionBackupValue(UInt32OptionNames name, uint value) : base(name, value) { }//IL_0001: Unknown result type (might be due to invalid IL or missing references) public override void Restore(IGameOptions option) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) option.SetUInt(OptionName, Value); } } public class RoleRateBackupValue : OptionBackupValue { public RoleTypes roleType; public int maxCount; public int chance; public RoleRateBackupValue(RoleTypes type, int maxCount, int chance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) roleType = type; this.maxCount = maxCount; this.chance = chance; base..ctor(); } public override void Restore(IGameOptions option) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) option.RoleOptions.SetRoleRate(roleType, maxCount, chance); } } [Flags] public enum CustomGameMode { Standard = 1, FFA = 2, HidenSeekTOHE = 8, All = int.MaxValue } [HarmonyPatch] public static class Options { public enum SpawnChance { Chance0, Chance5, Chance10, Chance15, Chance20, Chance25, Chance30, Chance35, Chance40, Chance45, Chance50, Chance55, Chance60, Chance65, Chance70, Chance75, Chance80, Chance85, Chance90, Chance95, Chance100 } private enum RatesZeroOne { RoleOff, RoleRate } public class OverrideTasksData { public static Dictionary AllData = new Dictionary(); public OptionItem doOverride; public OptionItem assignCommonTasks; public OptionItem numLongTasks; public OptionItem numShortTasks; public CustomRoles Role { get; private set; } public int IdStart { get; private set; } public OverrideTasksData(int idStart, TabGroup tab, CustomRoles role) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) IdStart = idStart; Role = role; Dictionary replacementDictionary = new Dictionary { { "%role%", Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(role)), Utils.GetRoleName(role)) } }; doOverride = BooleanOptionItem.Create(idStart++, "doOverride", defaultValue: false, tab, isSingleValue: false).SetParent(CustomRoleSpawnChances[role]).SetValueFormat(OptionFormat.None); doOverride.ReplacementDictionary = replacementDictionary; assignCommonTasks = BooleanOptionItem.Create(idStart++, "assignCommonTasks", defaultValue: true, tab, isSingleValue: false).SetParent(doOverride).SetValueFormat(OptionFormat.None); assignCommonTasks.ReplacementDictionary = replacementDictionary; numLongTasks = IntegerOptionItem.Create(idStart++, "roleLongTasksNum", new IntegerValueRule(0, 99, 1), 3, tab, isSingleValue: false).SetParent(doOverride).SetValueFormat(OptionFormat.Pieces); numLongTasks.ReplacementDictionary = replacementDictionary; numShortTasks = IntegerOptionItem.Create(idStart++, "roleShortTasksNum", new IntegerValueRule(0, 99, 1), 3, tab, isSingleValue: false).SetParent(doOverride).SetValueFormat(OptionFormat.Pieces); numShortTasks.ReplacementDictionary = replacementDictionary; if (!AllData.ContainsKey(role)) { AllData.Add(role, this); } else { Logger.Warn("重複したCustomRolesを対象とするOverrideTasksDataが作成されました", "OverrideTasksData", escapeCRLF: true, 2046, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionHolder.cs"); } } public static OverrideTasksData Create(int idStart, TabGroup tab, CustomRoles role) { return new OverrideTasksData(idStart, tab, role); } } private static readonly string[] presets; public static OptionItem GameMode; public static readonly string[] gameModes; public static Dictionary roleCounts; public static Dictionary roleSpawnChances; public static Dictionary CustomRoleCounts; public static Dictionary CustomGhostRoleCounts; public static Dictionary CustomRoleSpawnChances; public static Dictionary CustomAdtRoleSpawnRate; public static readonly string[] CheatResponsesName; public static readonly string[] ConfirmEjectionsMode; public static readonly string[] CamouflageMode; public static float DefaultKillCooldown; public static OptionItem GhostsDoTasks; public static OptionItem GradientTagsOpt; public static OptionItem EnableKillerLeftCommand; public static OptionItem ShowMadmatesInLeftCommand; public static OptionItem SeeEjectedRolesInMeeting; public static OptionItem KickLowLevelPlayer; public static OptionItem TempBanLowLevelPlayer; public static OptionItem ApplyAllowList; public static OptionItem AllowOnlyWhiteList; public static OptionItem KickOtherPlatformPlayer; public static OptionItem OptKickAndroidPlayer; public static OptionItem OptKickIphonePlayer; public static OptionItem OptKickXboxPlayer; public static OptionItem OptKickPlayStationPlayer; public static OptionItem OptKickNintendoPlayer; public static OptionItem KickPlayerFriendCodeInvalid; public static OptionItem TempBanPlayerFriendCodeInvalid; public static OptionItem AutoKickStart; public static OptionItem AutoKickStartTimes; public static OptionItem AutoKickStartAsBan; public static OptionItem TempBanPlayersWhoKeepQuitting; public static OptionItem QuitTimesTillTempBan; public static OptionItem ApplyVipList; public static OptionItem ApplyDenyNameList; public static OptionItem ApplyBanList; public static OptionItem ApplyModeratorList; public static OptionItem AllowSayCommand; public static OptionItem MinWaitAutoStart; public static OptionItem MaxWaitAutoStart; public static OptionItem PlayerAutoStart; public static OptionItem AutoStartTimer; public static OptionItem ImmediateAutoStart; public static OptionItem ImmediateStartTimer; public static OptionItem StartWhenPlayersReach; public static OptionItem StartWhenTimerLowerThan; public static OptionItem AutoPlayAgain; public static OptionItem AutoPlayAgainCountdown; public static OptionItem LowLoadMode; public static OptionItem EndWhenPlayerBug; public static OptionItem HideExileChat; public static OptionItem RemovePetsAtDeadPlayers; public static OptionItem CheatResponses; public static OptionItem NewHideMsg; public static OptionItem AutoDisplayKillLog; public static OptionItem AutoDisplayLastRoles; public static OptionItem AutoDisplayLastResult; public static OptionItem OldKillLog; public static OptionItem SuffixMode; public static OptionItem HideHostText; public static OptionItem HideAllTagsAndText; public static OptionItem HideGameSettings; public static OptionItem PlayerCanSetColor; public static OptionItem PlayerCanSetName; public static OptionItem PlayerCanUseQuitCommand; public static OptionItem PlayerCanUseTP; public static OptionItem CanPlayMiniGames; public static OptionItem FormatNameMode; public static OptionItem DisableEmojiName; public static OptionItem ChangeNameToRoleInfo; public static OptionItem SendRoleDescriptionFirstMeeting; public static OptionItem NoGameEnd; public static OptionItem AllowConsole; public static OptionItem DisableAntiBlackoutProtects; public static OptionItem RoleAssigningAlgorithm; public static OptionItem KPDCamouflageMode; public static OptionItem EnableUpMode; public static OptionItem NumImpostorsHnS; public static OptionItem CEMode; public static OptionItem ShowImpRemainOnEject; public static OptionItem ShowNKRemainOnEject; public static OptionItem ShowTeamNextToRoleNameOnEject; public static OptionItem ConfirmEgoistOnEject; public static OptionItem ConfirmLoversOnEject; public static OptionItem RandomMapsMode; public static OptionItem SkeldChance; public static OptionItem MiraChance; public static OptionItem PolusChance; public static OptionItem DleksChance; public static OptionItem AirshipChance; public static OptionItem FungleChance; public static OptionItem UseMoreRandomMapSelection; public static OptionItem MapModification; public static OptionItem AirshipVariableElectrical; public static OptionItem DisableAirshipMovingPlatform; public static OptionItem DisableSporeTriggerOnFungle; public static OptionItem DisableZiplineOnFungle; public static OptionItem DisableZiplineFromTop; public static OptionItem DisableZiplineFromUnder; public static OptionItem ResetDoorsEveryTurns; public static OptionItem DoorsResetMode; public static OptionItem ChangeDecontaminationTime; public static OptionItem DecontaminationTimeOnMiraHQ; public static OptionItem DecontaminationTimeOnPolus; public static OptionItem CommsCamouflage; public static OptionItem DisableOnSomeMaps; public static OptionItem DisableOnSkeld; public static OptionItem DisableOnMira; public static OptionItem DisableOnPolus; public static OptionItem DisableOnDleks; public static OptionItem DisableOnAirship; public static OptionItem DisableOnFungle; public static OptionItem DisableReportWhenCC; public static OptionItem SabotageCooldownControl; public static OptionItem SabotageCooldown; public static OptionItem SabotageTimeControl; public static OptionItem SkeldReactorTimeLimit; public static OptionItem SkeldO2TimeLimit; public static OptionItem MiraReactorTimeLimit; public static OptionItem MiraO2TimeLimit; public static OptionItem PolusReactorTimeLimit; public static OptionItem AirshipReactorTimeLimit; public static OptionItem FungleReactorTimeLimit; public static OptionItem FungleMushroomMixupDuration; public static OptionItem LightsOutSpecialSettings; public static OptionItem BlockDisturbancesToSwitches; public static OptionItem DisableAirshipViewingDeckLightsPanel; public static OptionItem DisableAirshipGapRoomLightsPanel; public static OptionItem DisableAirshipCargoLightsPanel; public static OptionItem DisableShieldAnimations; public static OptionItem DisableKillAnimationOnGuess; public static OptionItem DisableVanillaRoles; public static OptionItem DisableTaskWin; public static OptionItem DisableTaskWinIfAllCrewsAreDead; public static OptionItem DisableTaskWinIfAllCrewsAreConverted; public static OptionItem DisableMeeting; public static OptionItem DisableSabotage; public static OptionItem DisableCloseDoor; public static OptionItem DisableDevices; public static OptionItem DisableSkeldDevices; public static OptionItem DisableSkeldAdmin; public static OptionItem DisableSkeldCamera; public static OptionItem DisableMiraHQDevices; public static OptionItem DisableMiraHQAdmin; public static OptionItem DisableMiraHQDoorLog; public static OptionItem DisablePolusDevices; public static OptionItem DisablePolusAdmin; public static OptionItem DisablePolusCamera; public static OptionItem DisablePolusVital; public static OptionItem DisableAirshipDevices; public static OptionItem DisableAirshipCockpitAdmin; public static OptionItem DisableAirshipRecordsAdmin; public static OptionItem DisableAirshipCamera; public static OptionItem DisableAirshipVital; public static OptionItem DisableFungleDevices; public static OptionItem DisableFungleBinoculars; public static OptionItem DisableFungleVital; public static OptionItem DisableDevicesIgnoreConditions; public static OptionItem DisableDevicesIgnoreImpostors; public static OptionItem DisableDevicesIgnoreNeutrals; public static OptionItem DisableDevicesIgnoreCrewmates; public static OptionItem DisableDevicesIgnoreAfterAnyoneDied; public static OptionItem SyncButtonMode; public static OptionItem SyncedButtonCount; public static int UsedButtonCount; public static OptionItem AllAliveMeeting; public static OptionItem AllAliveMeetingTime; public static OptionItem AdditionalEmergencyCooldown; public static OptionItem AdditionalEmergencyCooldownThreshold; public static OptionItem AdditionalEmergencyCooldownTime; public static OptionItem VoteMode; public static OptionItem WhenSkipVote; public static OptionItem WhenSkipVoteIgnoreFirstMeeting; public static OptionItem WhenSkipVoteIgnoreNoDeadBody; public static OptionItem WhenSkipVoteIgnoreEmergency; public static OptionItem WhenNonVote; public static OptionItem WhenTie; public static OptionItem LadderDeath; public static OptionItem LadderDeathChance; public static OptionItem FixFirstKillCooldown; public static OptionItem FixKillCooldownValue; public static OptionItem ShieldPersonDiedFirst; public static OptionItem EveryoneCanSeeDeathReason; public static OptionItem KillFlashDuration; public static OptionItem GhostIgnoreTasks; public static OptionItem GhostCanSeeOtherRoles; public static OptionItem GhostCanSeeOtherVotes; public static OptionItem GhostCanSeeDeathReason; public static OptionItem ConvertedCanBecomeGhost; public static OptionItem MaxImpGhost; public static OptionItem MaxCrewGhost; public static OptionItem DefaultAngelCooldown; public static OptionItem DisableShortTasks; public static OptionItem DisableCleanVent; public static OptionItem DisableCalibrateDistributor; public static OptionItem DisableChartCourse; public static OptionItem DisableStabilizeSteering; public static OptionItem DisableCleanO2Filter; public static OptionItem DisableUnlockManifolds; public static OptionItem DisablePrimeShields; public static OptionItem DisableMeasureWeather; public static OptionItem DisableBuyBeverage; public static OptionItem DisableAssembleArtifact; public static OptionItem DisableSortSamples; public static OptionItem DisableProcessData; public static OptionItem DisableRunDiagnostics; public static OptionItem DisableRepairDrill; public static OptionItem DisableAlignTelescope; public static OptionItem DisableRecordTemperature; public static OptionItem DisableFillCanisters; public static OptionItem DisableMonitorTree; public static OptionItem DisableStoreArtifacts; public static OptionItem DisablePutAwayPistols; public static OptionItem DisablePutAwayRifles; public static OptionItem DisableMakeBurger; public static OptionItem DisableCleanToilet; public static OptionItem DisableDecontaminate; public static OptionItem DisableSortRecords; public static OptionItem DisableFixShower; public static OptionItem DisablePickUpTowels; public static OptionItem DisablePolishRuby; public static OptionItem DisableDressMannequin; public static OptionItem DisableCommonTasks; public static OptionItem DisableSwipeCard; public static OptionItem DisableFixWiring; public static OptionItem DisableEnterIdCode; public static OptionItem DisableInsertKeys; public static OptionItem DisableScanBoardingPass; public static OptionItem DisableLongTasks; public static OptionItem DisableSubmitScan; public static OptionItem DisableUnlockSafe; public static OptionItem DisableStartReactor; public static OptionItem DisableResetBreaker; public static OptionItem DisableAlignEngineOutput; public static OptionItem DisableInspectSample; public static OptionItem DisableEmptyChute; public static OptionItem DisableClearAsteroids; public static OptionItem DisableWaterPlants; public static OptionItem DisableOpenWaterways; public static OptionItem DisableReplaceWaterJug; public static OptionItem DisableRebootWifi; public static OptionItem DisableDevelopPhotos; public static OptionItem DisableRewindTapes; public static OptionItem DisableStartFans; public static OptionItem DisableOtherTasks; public static OptionItem DisableUploadData; public static OptionItem DisableEmptyGarbage; public static OptionItem DisableFuelEngines; public static OptionItem DisableDivertPower; public static OptionItem DisableActivateWeatherNodes; public static OptionItem DisableRoastMarshmallow; public static OptionItem DisableCollectSamples; public static OptionItem DisableReplaceParts; public static OptionItem DisableCollectVegetables; public static OptionItem DisableMineOres; public static OptionItem DisableExtractFuel; public static OptionItem DisableCatchFish; public static OptionItem DisablePolishGem; public static OptionItem DisableHelpCritter; public static OptionItem DisableHoistSupplies; public static OptionItem DisableFixAntenna; public static OptionItem DisableBuildSandcastle; public static OptionItem DisableCrankGenerator; public static OptionItem DisableMonitorMushroom; public static OptionItem DisablePlayVideoGame; public static OptionItem DisableFindSignal; public static OptionItem DisableThrowFisbee; public static OptionItem DisableLiftWeights; public static OptionItem DisableCollectShells; public static OptionItem GuesserMode; public static OptionItem CrewmatesCanGuess; public static OptionItem ImpostorsCanGuess; public static OptionItem NeutralKillersCanGuess; public static OptionItem PassiveNeutralsCanGuess; public static OptionItem CanGuessAddons; public static OptionItem ImpCanGuessImp; public static OptionItem CrewCanGuessCrew; public static OptionItem HideGuesserCommands; public static OptionItem ShowOnlyEnabledRolesInGuesserUI; public static OptionItem ImpsCanSeeEachOthersRoles; public static OptionItem ImpsCanSeeEachOthersAddOns; public static OptionItem DefaultShapeshiftCooldown; public static OptionItem DeadImpCantSabotage; public static OptionItem NonNeutralKillingRolesMinPlayer; public static OptionItem NonNeutralKillingRolesMaxPlayer; public static OptionItem NeutralKillingRolesMinPlayer; public static OptionItem NeutralKillingRolesMaxPlayer; public static OptionItem NeutralRoleWinTogether; public static OptionItem NeutralWinTogether; public static OptionItem NameDisplayAddons; public static OptionItem AddBracketsToAddons; public static OptionItem NoLimitAddonsNumMax; public static OptionItem LoverSpawnChances; public static OptionItem LoverKnowRoles; public static OptionItem LoverSuicide; public static OptionItem ImpCanBeInLove; public static OptionItem CrewCanBeInLove; public static OptionItem NeutralCanBeInLove; public static readonly string[] voteModes; public static readonly string[] tieModes; public static readonly string[] suffixModes; public static readonly string[] roleAssigningAlgorithms; public static readonly string[] formatNameModes; public static int SnitchExposeTaskLeft; public static bool IsLoaded; public static CustomGameMode CurrentGameMode => GameMode.GetInt() switch { 1 => CustomGameMode.FFA, 2 => CustomGameMode.HidenSeekTOHE, _ => CustomGameMode.Standard, }; [HarmonyPatch(typeof(TranslationController), "Initialize")] [HarmonyPostfix] public static void OptionsLoadStart_Postfix() { Logger.Msg("Mod option loading start", "Load Options", escapeCRLF: true, 27, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionHolder.cs"); try { Main.Instance.StartCoroutine(CoLoadOptions()); } catch (Exception value) { Logger.Error($"Fatal error after loading mod options: {value}", "Load Options", escapeCRLF: true, 34, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionHolder.cs"); } } public static VoteMode GetWhenSkipVote() { return (VoteMode)WhenSkipVote.GetValue(); } public static VoteMode GetWhenNonVote() { return (VoteMode)WhenNonVote.GetValue(); } public static SuffixModes GetSuffixMode() { return (SuffixModes)SuffixMode.GetValue(); } static Options() { presets = new string[5] { Main.Preset1.Value, Main.Preset2.Value, Main.Preset3.Value, Main.Preset4.Value, Main.Preset5.Value }; gameModes = new string[3] { "Standard", "FFA", "Hide&SeekTOHE" }; CheatResponsesName = new string[6] { "Ban", "Kick", "NoticeMe", "NoticeEveryone", "TempBan", "OnlyCancel" }; ConfirmEjectionsMode = new string[3] { "ConfirmEjections.None", "ConfirmEjections.Team", "ConfirmEjections.Role" }; CamouflageMode = new string[12] { "CamouflageMode.Default", "CamouflageMode.Host", "CamouflageMode.Random", "CamouflageMode.OnlyRandomColor", "CamouflageMode.Karpe", "CamouflageMode.Lauryn", "CamouflageMode.Moe", "CamouflageMode.Pyro", "CamouflageMode.ryuk", "CamouflageMode.Gurge44", "CamouflageMode.TommyXL", "CamouflageMode.Sarha" }; NormalGameOptionsV08 normalOptions = Main.NormalOptions; DefaultKillCooldown = ((normalOptions != null) ? normalOptions.KillCooldown : 20f); UsedButtonCount = 0; voteModes = new string[4] { "Default", "Suicide", "SelfVote", "Skip" }; tieModes = new string[3] { "TieMode.Default", "TieMode.All", "TieMode.Random" }; suffixModes = new string[9] { "SuffixMode.None", "SuffixMode.Version", "SuffixMode.Streaming", "SuffixMode.Recording", "SuffixMode.RoomHost", "SuffixMode.OriginalName", "SuffixMode.DoNotKillMe", "SuffixMode.NoAndroidPlz", "SuffixMode.AutoHost" }; roleAssigningAlgorithms = new string[5] { "RoleAssigningAlgorithm.Default", "RoleAssigningAlgorithm.NetRandom", "RoleAssigningAlgorithm.HashRandom", "RoleAssigningAlgorithm.Xorshift", "RoleAssigningAlgorithm.MersenneTwister" }; formatNameModes = new string[3] { "FormatNameModes.None", "FormatNameModes.Color", "FormatNameModes.Snacks" }; SnitchExposeTaskLeft = 1; IsLoaded = false; ResetRoleCounts(); } public static void ResetRoleCounts() { roleCounts = new Dictionary(); roleSpawnChances = new Dictionary(); CustomRoles[] allRoles = CustomRolesHelper.AllRoles; foreach (CustomRoles key in allRoles) { roleCounts.Add(key, 0); roleSpawnChances.Add(key, 0f); } } public static void SetRoleCount(CustomRoles role, int count) { roleCounts[role] = count; if (CustomRoleCounts.TryGetValue(role, out var value)) { value.SetValue(count - 1); } } public static int GetRoleSpawnMode(CustomRoles role) { if (!CustomRoleSpawnChances.TryGetValue(role, out var value)) { return 0; } return value.GetChance(); } public static int GetRoleCount(CustomRoles role) { if (GetRoleSpawnMode(role) != 0) { if (!CustomRoleCounts.TryGetValue(role, out var value)) { return roleCounts[role]; } return value.GetInt(); } return 0; } public static float GetRoleChance(CustomRoles role) { if (!CustomRoleSpawnChances.TryGetValue(role, out var value)) { return roleSpawnChances[role]; } return value.GetValue(); } private static IEnumerator CoLoadOptions() { if (IsLoaded) { yield break; } OptionSaver.Initialize(); yield return null; PresetOptionItem.Create(0, TabGroup.SystemSettings).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)235, (byte)4, byte.MaxValue))).SetHeader(value: true); GameMode = StringOptionItem.Create(60000, "GameMode", gameModes, 0, TabGroup.ModSettings, isSingleValue: false).SetHeader(value: true); CustomRoleCounts = new Dictionary(); CustomGhostRoleCounts = new Dictionary(); CustomRoleSpawnChances = new Dictionary(); CustomAdtRoleSpawnRate = new Dictionary(); ImpsCanSeeEachOthersRoles = BooleanOptionItem.Create(60001, "ImpsCanSeeEachOthersRoles", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true); ImpsCanSeeEachOthersAddOns = BooleanOptionItem.Create(60002, "ImpsCanSeeEachOthersAddOns", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(ImpsCanSeeEachOthersRoles); Madmate.SetupMenuOptions(); DefaultShapeshiftCooldown = FloatOptionItem.Create(60011, "DefaultShapeshiftCooldown", new FloatValueRule(5f, 180f, 5f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetValueFormat(OptionFormat.Seconds); DeadImpCantSabotage = BooleanOptionItem.Create(60012, "DeadImpCantSabotage", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard); NonNeutralKillingRolesMinPlayer = IntegerOptionItem.Create(60013, "NonNeutralKillingRolesMinPlayer", new IntegerValueRule(0, 15, 1), 0, TabGroup.NeutralRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetValueFormat(OptionFormat.Players); NonNeutralKillingRolesMaxPlayer = IntegerOptionItem.Create(60014, "NonNeutralKillingRolesMaxPlayer", new IntegerValueRule(0, 15, 1), 0, TabGroup.NeutralRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetValueFormat(OptionFormat.Players); NeutralKillingRolesMinPlayer = IntegerOptionItem.Create(60015, "NeutralKillingRolesMinPlayer", new IntegerValueRule(0, 15, 1), 0, TabGroup.NeutralRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetValueFormat(OptionFormat.Players); NeutralKillingRolesMaxPlayer = IntegerOptionItem.Create(60016, "NeutralKillingRolesMaxPlayer", new IntegerValueRule(0, 15, 1), 0, TabGroup.NeutralRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetValueFormat(OptionFormat.Players); NeutralRoleWinTogether = BooleanOptionItem.Create(60017, "NeutralRoleWinTogether", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true); NeutralWinTogether = BooleanOptionItem.Create(60018, "NeutralWinTogether", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(NeutralRoleWinTogether).SetGameMode(CustomGameMode.Standard); NameDisplayAddons = BooleanOptionItem.Create(60019, "NameDisplayAddons", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true); AddBracketsToAddons = BooleanOptionItem.Create(60021, "BracketAddons", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(NameDisplayAddons); NoLimitAddonsNumMax = IntegerOptionItem.Create(60020, "NoLimitAddonsNumMax", new IntegerValueRule(1, 15, 1), 1, TabGroup.Addons, isSingleValue: false).SetGameMode(CustomGameMode.Standard); yield return null; TextOptionItem.Create(10000000, "RoleType.VanillaRoles", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorVanilla).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); if (CustomRoleManager.RoleClass.Where((KeyValuePair x) => x.Key.IsImpostor()).Any((KeyValuePair r) => r.Value.IsExperimental)) { TextOptionItem.Create(10000020, "Experimental.Roles", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)141, (byte)70, (byte)49, byte.MaxValue))); CustomRoleManager.GetExperimentalOptions(Custom_Team.Impostor).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); } TextOptionItem.Create(10000001, "RoleType.ImpKilling", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorKilling).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000002, "RoleType.ImpSupport", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorSupport).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000003, "RoleType.ImpConcealing", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorConcealing).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000004, "RoleType.ImpHindering", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorHindering).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000005, "RoleType.Madmate", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.Madmate).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000111, "RoleType.ImpGhost", TabGroup.ImpostorRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorGhosts).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); yield return null; TextOptionItem.Create(10000006, "RoleType.VanillaRoles", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateVanilla).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateVanillaGhosts).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); if (CustomRoleManager.RoleClass.Where((KeyValuePair x) => x.Key.IsCrewmate()).Any((KeyValuePair r) => r.Value.IsExperimental)) { TextOptionItem.Create(10000021, "Experimental.Roles", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)141, (byte)70, (byte)49, byte.MaxValue))); CustomRoleManager.GetExperimentalOptions(Custom_Team.Crewmate).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); } TextOptionItem.Create(10000007, "RoleType.CrewBasic", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateBasic).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); CustomRoles.Mini.GetStaticRoleClass().SetupCustomOption(); TextOptionItem.Create(10000008, "RoleType.CrewSupport", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateSupport).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000009, "RoleType.CrewKilling", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateKilling).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000010, "RoleType.CrewPower", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmatePower).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000101, "RoleType.CrewGhost", TabGroup.CrewmateRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.CrewmateGhosts).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); yield return null; if (CustomRoleManager.RoleClass.Where((KeyValuePair x) => x.Key.IsNeutral()).Any((KeyValuePair r) => r.Value.IsExperimental)) { TextOptionItem.Create(10000022, "Experimental.Roles", TabGroup.NeutralRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)141, (byte)70, (byte)49, byte.MaxValue))); CustomRoleManager.GetExperimentalOptions(Custom_Team.Neutral).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); } TextOptionItem.Create(10000011, "RoleType.NeutralBenign", TabGroup.NeutralRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.NeutralBenign).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000012, "RoleType.NeutralEvil", TabGroup.NeutralRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.NeutralEvil).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000013, "RoleType.NeutralChaos", TabGroup.NeutralRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.NeutralChaos).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); TextOptionItem.Create(10000014, "RoleType.NeutralKilling", TabGroup.NeutralRoles).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); CustomRoleManager.GetNormalOptions(Custom_RoleType.NeutralKilling).ForEach(delegate(RoleBase r) { r.SetupCustomOption(); }); yield return null; TextOptionItem.Create(10000015, "RoleType.Helpful", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)154, (byte)206, byte.MaxValue))); Autopsy.SetupCustomOptions(); Bait.SetupCustomOptions(); Trapper.SetupCustomOptions(); Bewilder.SetupCustomOptions(); Burst.SetupCustomOptions(); Cyber.SetupCustomOptions(); Flash.SetupCustomOption(); Lazy.SetupCustomOptions(); Loyal.SetupCustomOptions(); Lucky.SetupCustomOptions(); Necroview.SetupCustomOptions(); Nimble.SetupCustomOptions(); Overclocked.SetupCustomOptions(); Radar.SetupCustomOptions(); Seer.SetupCustomOptions(); Silent.SetupCustomOptions(); Sleuth.SetupCustomOptions(); Tiebreaker.SetupCustomOptions(); Torch.SetupCustomOptions(); Watcher.SetupCustomOptions(); TextOptionItem.Create(10000016, "RoleType.Harmful", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)154, (byte)206, byte.MaxValue))); Unreportable.SetupCustomOptions(); Fool.SetupCustomOptions(); Fragile.SetupCustomOptions(); Statue.SetupCustomOptions(); Hurried.SetupCustomOption(); Influenced.SetupCustomOption(); Mundane.SetupCustomOption(); Oblivious.SetupCustomOptions(); Rascal.SetupCustomOptions(); Unlucky.SetupCustomOptions(); Tired.SetupCustomOptions(); VoidBallot.SetupCustomOptions(); TextOptionItem.Create(10000017, "RoleType.Mixed", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)154, (byte)206, byte.MaxValue))); Antidote.SetupCustomOptions(); Avanger.SetupCustomOptions(); Aware.SetupCustomOptions(); Bloodthirst.SetupCustomOptions(); Diseased.SetupCustomOptions(); Ghoul.SetupCustomOptions(); Gravestone.SetupCustomOptions(); Guesser.SetupCustomOptions(); Oiiai.SetupCustomOptions(); Paranoia.SetupCustomOptions(); Stubborn.SetupCustomOptions(); Susceptible.SetupCustomOptions(); TextOptionItem.Create(10000018, "RoleType.Impostor", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); Circumvent.SetupCustomOption(); Clumsy.SetupCustomOption(); LastImpostor.SetupCustomOption(); Madmate.SetupCustomMenuOptions(); Mare.SetupCustomOption(); Mimic.SetupCustomOption(); Stealer.SetupCustomOption(); Tricky.SetupCustomOption(); TextOptionItem.Create(10000019, "RoleType.Misc", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); Youtuber.SetupCustomOptions(); Egoist.SetupCustomOption(); SetupLoversRoleOptionsToggle(23600); Reach.SetupCustomOptions(); Rainbow.SetupCustomOptions(); Workhorse.SetupCustomOption(); TextOptionItem.Create(10000023, "Experimental.Roles", TabGroup.Addons).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)141, (byte)140, (byte)141, byte.MaxValue))); Glow.SetupCustomOptions(); Swift.SetupCustomOption(); yield return null; yield return null; GradientTagsOpt = BooleanOptionItem.Create(60031, "EnableGadientTags", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true); EnableKillerLeftCommand = BooleanOptionItem.Create(60040, "EnableKillerLeftCommand", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); ShowMadmatesInLeftCommand = BooleanOptionItem.Create(60042, "ShowMadmatesInLeftCommand", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetParent(EnableKillerLeftCommand); SeeEjectedRolesInMeeting = BooleanOptionItem.Create(60041, "SeeEjectedRolesInMeeting", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); KickLowLevelPlayer = IntegerOptionItem.Create(60050, "KickLowLevelPlayer", new IntegerValueRule(0, 100, 1), 0, TabGroup.SystemSettings, isSingleValue: false).SetValueFormat(OptionFormat.Level).SetHeader(value: true); TempBanLowLevelPlayer = BooleanOptionItem.Create(60051, "TempBanLowLevelPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickLowLevelPlayer).SetValueFormat(OptionFormat.Times); ApplyAllowList = BooleanOptionItem.Create(60060, "ApplyWhiteList", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); AllowOnlyWhiteList = BooleanOptionItem.Create(60061, "AllowOnlyWhiteList", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); KickOtherPlatformPlayer = BooleanOptionItem.Create(60070, "KickOtherPlatformPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); OptKickAndroidPlayer = BooleanOptionItem.Create(60071, "OptKickAndroidPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickOtherPlatformPlayer); OptKickIphonePlayer = BooleanOptionItem.Create(60072, "OptKickIphonePlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickOtherPlatformPlayer); OptKickXboxPlayer = BooleanOptionItem.Create(60073, "OptKickXboxPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickOtherPlatformPlayer); OptKickPlayStationPlayer = BooleanOptionItem.Create(60074, "OptKickPlayStationPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickOtherPlatformPlayer); OptKickNintendoPlayer = BooleanOptionItem.Create(60075, "OptKickNintendoPlayer", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickOtherPlatformPlayer); KickPlayerFriendCodeInvalid = BooleanOptionItem.Create(60080, "KickPlayerFriendCodeInvalid", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false); TempBanPlayerFriendCodeInvalid = BooleanOptionItem.Create(60081, "TempBanPlayerFriendCodeInvalid", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(KickPlayerFriendCodeInvalid); AutoKickStart = BooleanOptionItem.Create(60140, "AutoKickStart", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); AutoKickStartTimes = IntegerOptionItem.Create(60141, "AutoKickStartTimes", new IntegerValueRule(0, 99, 1), 1, TabGroup.SystemSettings, isSingleValue: false).SetParent(AutoKickStart).SetValueFormat(OptionFormat.Times); AutoKickStartAsBan = BooleanOptionItem.Create(60142, "AutoKickStartAsBan", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(AutoKickStart); TempBanPlayersWhoKeepQuitting = BooleanOptionItem.Create(60150, "TempBanPlayersWhoKeepQuitting", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); QuitTimesTillTempBan = IntegerOptionItem.Create(60151, "QuitTimesTillTempBan", new IntegerValueRule(1, 15, 1), 4, TabGroup.SystemSettings, isSingleValue: false).SetValueFormat(OptionFormat.Times).SetParent(TempBanPlayersWhoKeepQuitting); ApplyVipList = BooleanOptionItem.Create(60090, "ApplyVipList", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true); ApplyDenyNameList = BooleanOptionItem.Create(60100, "ApplyDenyNameList", defaultValue: true, TabGroup.SystemSettings, isSingleValue: true); ApplyBanList = BooleanOptionItem.Create(60110, "ApplyBanList", defaultValue: true, TabGroup.SystemSettings, isSingleValue: true); ApplyModeratorList = BooleanOptionItem.Create(60120, "ApplyModeratorList", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); AllowSayCommand = BooleanOptionItem.Create(60121, "AllowSayCommand", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetParent(ApplyModeratorList); MinWaitAutoStart = FloatOptionItem.Create(60170, "MinWaitAutoStart", new FloatValueRule(0f, 10f, 0.5f), 1.5f, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true); MaxWaitAutoStart = FloatOptionItem.Create(60180, "MaxWaitAutoStart", new FloatValueRule(0f, 10f, 0.5f), 1.5f, TabGroup.SystemSettings, isSingleValue: false); PlayerAutoStart = IntegerOptionItem.Create(60190, "PlayerAutoStart", new IntegerValueRule(1, 100, 1), 14, TabGroup.SystemSettings, isSingleValue: false).SetValueFormat(OptionFormat.Players); AutoStartTimer = IntegerOptionItem.Create(60200, "AutoStartTimer", new IntegerValueRule(10, 600, 1), 20, TabGroup.SystemSettings, isSingleValue: false).SetValueFormat(OptionFormat.Seconds); ImmediateAutoStart = BooleanOptionItem.Create(60201, "ImmediateAutoStart", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); ImmediateStartTimer = IntegerOptionItem.Create(60202, "ImmediateStartTimer", new IntegerValueRule(0, 60, 1), 20, TabGroup.SystemSettings, isSingleValue: false).SetParent(ImmediateAutoStart).SetValueFormat(OptionFormat.Seconds); StartWhenPlayersReach = IntegerOptionItem.Create(60203, "StartWhenPlayersReach", new IntegerValueRule(0, 100, 1), 14, TabGroup.SystemSettings, isSingleValue: false).SetParent(ImmediateAutoStart).SetValueFormat(OptionFormat.Players); StartWhenTimerLowerThan = IntegerOptionItem.Create(60204, "StartWhenTimerLowerThan", new IntegerValueRule(0, 600, 5), 60, TabGroup.SystemSettings, isSingleValue: false).SetParent(ImmediateAutoStart).SetValueFormat(OptionFormat.Seconds); AutoPlayAgain = BooleanOptionItem.Create(60210, "AutoPlayAgain", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); AutoPlayAgainCountdown = IntegerOptionItem.Create(60211, "AutoPlayAgainCountdown", new IntegerValueRule(1, 20, 1), 10, TabGroup.SystemSettings, isSingleValue: false).SetParent(AutoPlayAgain).SetValueFormat(OptionFormat.Seconds); LowLoadMode = BooleanOptionItem.Create(60230, "LowLoadMode", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true).SetColor(Color.green); EndWhenPlayerBug = BooleanOptionItem.Create(60240, "EndWhenPlayerBug", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetColor(Color.blue); HideExileChat = BooleanOptionItem.Create(60292, "HideExileChat", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetColor(Color.blue).HideInHnS(); RemovePetsAtDeadPlayers = BooleanOptionItem.Create(60294, "RemovePetsAtDeadPlayers", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetColor(Color.magenta); CheatResponses = StringOptionItem.Create(60250, "CheatResponses", CheatResponsesName, 0, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true); AutoDisplayKillLog = BooleanOptionItem.Create(60270, "AutoDisplayKillLog", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).SetHeader(value: true).HideInHnS(); OldKillLog = BooleanOptionItem.Create(60291, "RevertOldKillLog", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); AutoDisplayLastRoles = BooleanOptionItem.Create(60280, "AutoDisplayLastRoles", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); AutoDisplayLastResult = BooleanOptionItem.Create(60290, "AutoDisplayLastResult", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); SuffixMode = StringOptionItem.Create(60300, "SuffixMode", suffixModes, 0, TabGroup.SystemSettings, isSingleValue: true).SetHeader(value: true); HideHostText = BooleanOptionItem.Create(60311, "HideHostText", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); HideAllTagsAndText = BooleanOptionItem.Create(60312, "HideAllTagsAndText", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); HideGameSettings = BooleanOptionItem.Create(60310, "HideGameSettings", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); PlayerCanSetColor = BooleanOptionItem.Create(60330, "PlayerCanSetColor", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); PlayerCanUseQuitCommand = BooleanOptionItem.Create(60331, "PlayerCanUseQuitCommand", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); PlayerCanSetName = BooleanOptionItem.Create(60332, "PlayerCanSetName", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); PlayerCanUseTP = BooleanOptionItem.Create(60333, "PlayerCanUseTP", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); CanPlayMiniGames = BooleanOptionItem.Create(60334, "CanPlayMiniGames", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false); FormatNameMode = StringOptionItem.Create(60340, "FormatNameMode", formatNameModes, 0, TabGroup.SystemSettings, isSingleValue: false); DisableEmojiName = BooleanOptionItem.Create(60350, "DisableEmojiName", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false); ChangeNameToRoleInfo = BooleanOptionItem.Create(60360, "ChangeNameToRoleInfo", defaultValue: true, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); SendRoleDescriptionFirstMeeting = BooleanOptionItem.Create(60370, "SendRoleDescriptionFirstMeeting", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).HideInHnS(); NoGameEnd = BooleanOptionItem.Create(60380, "NoGameEnd", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetColor(Color.red).SetHeader(value: true); AllowConsole = BooleanOptionItem.Create(60382, "AllowConsole", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetColor(Color.red); DisableAntiBlackoutProtects = BooleanOptionItem.Create(60384, "DisableAntiBlackoutProtects", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color.red); RoleAssigningAlgorithm = StringOptionItem.Create(60400, "RoleAssigningAlgorithm", roleAssigningAlgorithms, 4, TabGroup.SystemSettings, isSingleValue: true).RegisterUpdateValueEvent(delegate(object obj, OptionItem.UpdateValueEventArgs args) { IRandom.SetInstanceById(args.CurrentValue); }).SetHeader(value: true); KPDCamouflageMode = StringOptionItem.Create(60410, "KPDCamouflageMode", CamouflageMode, 0, TabGroup.SystemSettings, isSingleValue: false).HideInHnS().SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)192, (byte)203, byte.MaxValue))); EnableUpMode = BooleanOptionItem.Create(60430, "EnableYTPlan", defaultValue: false, TabGroup.SystemSettings, isSingleValue: false).HideInHnS().SetColor(Color.cyan) .SetHeader(value: true); yield return null; FFAManager.SetupCustomOption(); TextOptionItem.Create(10000055, "MenuTitle.Hide&Seek", TabGroup.ModSettings).SetGameMode(CustomGameMode.HidenSeekTOHE).SetColor(Color.red); NumImpostorsHnS = IntegerOptionItem.Create(60891, "NumImpostorsHnS", new IntegerValueRule(1, 3, 1), 1, TabGroup.ModSettings, isSingleValue: false).SetHeader(value: true).SetColor(Color.red) .SetGameMode(CustomGameMode.HidenSeekTOHE) .SetValueFormat(OptionFormat.Players); TextOptionItem.Create(10000024, "MenuTitle.Ejections", TabGroup.ModSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); CEMode = StringOptionItem.Create(60440, "ConfirmEjectionsMode", ConfirmEjectionsMode, 2, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); ShowImpRemainOnEject = BooleanOptionItem.Create(60441, "ShowImpRemainOnEject", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); ShowNKRemainOnEject = BooleanOptionItem.Create(60442, "ShowNKRemainOnEject", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetParent(ShowImpRemainOnEject).SetGameMode(CustomGameMode.Standard) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); ShowTeamNextToRoleNameOnEject = BooleanOptionItem.Create(60443, "ShowTeamNextToRoleNameOnEject", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); ConfirmEgoistOnEject = BooleanOptionItem.Create(60444, "ConfirmEgoistOnEject", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))) .SetHeader(value: true); ConfirmLoversOnEject = BooleanOptionItem.Create(60445, "ConfirmLoversOnEject", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)238, (byte)232, byte.MaxValue))); TextOptionItem.Create(10000025, "MenuTitle.MapsSettings", TabGroup.ModSettings).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); RandomMapsMode = BooleanOptionItem.Create(60450, "RandomMapsMode", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetHeader(value: true).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); SkeldChance = IntegerOptionItem.Create(60451, "SkeldChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); MiraChance = IntegerOptionItem.Create(60452, "MiraChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); PolusChance = IntegerOptionItem.Create(60453, "PolusChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); DleksChance = IntegerOptionItem.Create(60457, "DleksChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); AirshipChance = IntegerOptionItem.Create(60454, "AirshipChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); FungleChance = IntegerOptionItem.Create(60455, "FungleChance", new IntegerValueRule(0, 100, 5), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); UseMoreRandomMapSelection = BooleanOptionItem.Create(60456, "UseMoreRandomMapSelection", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomMapsMode).SetValueFormat(OptionFormat.Percent); NewHideMsg = BooleanOptionItem.Create(60460, "NewHideMsg", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetHidden(value: true).SetGameMode(CustomGameMode.Standard) .SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))); RandomSpawn.SetupCustomOption(); MapModification = BooleanOptionItem.Create(60480, "MapModification", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); AirshipVariableElectrical = BooleanOptionItem.Create(60481, "AirshipVariableElectrical", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(MapModification).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DisableAirshipMovingPlatform = BooleanOptionItem.Create(60482, "DisableAirshipMovingPlatform", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(MapModification).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DisableSporeTriggerOnFungle = BooleanOptionItem.Create(60483, "DisableSporeTriggerOnFungle", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(MapModification).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DisableZiplineOnFungle = BooleanOptionItem.Create(60490, "DisableZiplineOnFungle", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(MapModification).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DisableZiplineFromTop = BooleanOptionItem.Create(60491, "DisableZiplineFromTop", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableZiplineOnFungle).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DisableZiplineFromUnder = BooleanOptionItem.Create(60492, "DisableZiplineFromUnder", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableZiplineOnFungle).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); ResetDoorsEveryTurns = BooleanOptionItem.Create(60500, "ResetDoorsEveryTurns", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DoorsResetMode = StringOptionItem.Create(60501, "DoorsResetMode", EnumHelper.GetAllNames(), 2, TabGroup.ModSettings, isSingleValue: false).SetParent(ResetDoorsEveryTurns).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); ChangeDecontaminationTime = BooleanOptionItem.Create(60503, "ChangeDecontaminationTime", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DecontaminationTimeOnMiraHQ = FloatOptionItem.Create(60504, "DecontaminationTimeOnMiraHQ", new FloatValueRule(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, isSingleValue: false).SetParent(ChangeDecontaminationTime).SetValueFormat(OptionFormat.Seconds) .SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); DecontaminationTimeOnPolus = FloatOptionItem.Create(60505, "DecontaminationTimeOnPolus", new FloatValueRule(0.5f, 10f, 0.25f), 3f, TabGroup.ModSettings, isSingleValue: false).SetParent(ChangeDecontaminationTime).SetValueFormat(OptionFormat.Seconds) .SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); TextOptionItem.Create(10000026, "MenuTitle.Sabotage", TabGroup.ModSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)243, (byte)96, (byte)96, byte.MaxValue))) .SetHeader(value: true); CommsCamouflage = BooleanOptionItem.Create(60510, "CommsCamouflage", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32((byte)243, (byte)96, (byte)96, byte.MaxValue))); DisableOnSomeMaps = BooleanOptionItem.Create(60511, "DisableOnSomeMaps", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(CommsCamouflage); DisableOnSkeld = BooleanOptionItem.Create(60512, "DisableOnSkeld", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableOnMira = BooleanOptionItem.Create(60513, "DisableOnMira", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableOnPolus = BooleanOptionItem.Create(60514, "DisableOnPolus", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableOnDleks = BooleanOptionItem.Create(60517, "DisableOnDleks", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableOnAirship = BooleanOptionItem.Create(60515, "DisableOnAirship", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableOnFungle = BooleanOptionItem.Create(60516, "DisableOnFungle", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(DisableOnSomeMaps); DisableReportWhenCC = BooleanOptionItem.Create(60520, "DisableReportWhenCC", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetParent(CommsCamouflage); SabotageCooldownControl = BooleanOptionItem.Create(60530, "SabotageCooldownControl", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)243, (byte)96, (byte)96, byte.MaxValue))); SabotageCooldown = FloatOptionItem.Create(60535, "SabotageCooldown", new FloatValueRule(1f, 60f, 1f), 30f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageCooldownControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); SabotageTimeControl = BooleanOptionItem.Create(60540, "SabotageTimeControl", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)243, (byte)96, (byte)96, byte.MaxValue))).SetGameMode(CustomGameMode.Standard); SkeldReactorTimeLimit = FloatOptionItem.Create(60541, "SkeldReactorTimeLimit", new FloatValueRule(5f, 90f, 1f), 30f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); SkeldO2TimeLimit = FloatOptionItem.Create(60542, "SkeldO2TimeLimit", new FloatValueRule(5f, 90f, 1f), 30f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); MiraReactorTimeLimit = FloatOptionItem.Create(60543, "MiraReactorTimeLimit", new FloatValueRule(5f, 90f, 1f), 45f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); MiraO2TimeLimit = FloatOptionItem.Create(60544, "MiraO2TimeLimit", new FloatValueRule(5f, 90f, 1f), 45f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); PolusReactorTimeLimit = FloatOptionItem.Create(60545, "PolusReactorTimeLimit", new FloatValueRule(5f, 90f, 1f), 60f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); AirshipReactorTimeLimit = FloatOptionItem.Create(60546, "AirshipReactorTimeLimit", new FloatValueRule(5f, 90f, 1f), 90f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); FungleReactorTimeLimit = FloatOptionItem.Create(60547, "FungleReactorTimeLimit", new FloatValueRule(5f, 90f, 1f), 60f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); FungleMushroomMixupDuration = FloatOptionItem.Create(60548, "FungleMushroomMixupDuration", new FloatValueRule(5f, 90f, 1f), 10f, TabGroup.ModSettings, isSingleValue: false).SetParent(SabotageTimeControl).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); LightsOutSpecialSettings = BooleanOptionItem.Create(60550, "LightsOutSpecialSettings", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)243, (byte)96, (byte)96, byte.MaxValue))); BlockDisturbancesToSwitches = BooleanOptionItem.Create(60551, "BlockDisturbancesToSwitches", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(LightsOutSpecialSettings).SetGameMode(CustomGameMode.Standard); DisableAirshipViewingDeckLightsPanel = BooleanOptionItem.Create(60552, "DisableAirshipViewingDeckLightsPanel", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(LightsOutSpecialSettings).SetGameMode(CustomGameMode.Standard); DisableAirshipGapRoomLightsPanel = BooleanOptionItem.Create(60553, "DisableAirshipGapRoomLightsPanel", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(LightsOutSpecialSettings).SetGameMode(CustomGameMode.Standard); DisableAirshipCargoLightsPanel = BooleanOptionItem.Create(60554, "DisableAirshipCargoLightsPanel", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(LightsOutSpecialSettings).SetGameMode(CustomGameMode.Standard); TextOptionItem.Create(10000027, "MenuTitle.Disable", TabGroup.ModSettings).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))).HideInHnS(); DisableShieldAnimations = BooleanOptionItem.Create(60560, "DisableShieldAnimations", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableKillAnimationOnGuess = BooleanOptionItem.Create(60561, "DisableKillAnimationOnGuess", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableVanillaRoles = BooleanOptionItem.Create(60562, "DisableVanillaRoles", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableTaskWin = BooleanOptionItem.Create(60563, "DisableTaskWin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableTaskWinIfAllCrewsAreDead = BooleanOptionItem.Create(60900, "DisableTaskWinIfAllCrewsAreDead", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableTaskWinIfAllCrewsAreConverted = BooleanOptionItem.Create(60901, "DisableTaskWinIfAllCrewsAreConverted", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableMeeting = BooleanOptionItem.Create(60564, "DisableMeeting", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableSabotage = BooleanOptionItem.Create(60565, "DisableSabotage", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableCloseDoor = BooleanOptionItem.Create(60566, "DisableCloseDoor", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))); DisableDevices = BooleanOptionItem.Create(60570, "DisableDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32(byte.MaxValue, (byte)153, (byte)153, byte.MaxValue))).HideInHnS(); DisableSkeldDevices = BooleanOptionItem.Create(60571, "DisableSkeldDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisableSkeldAdmin = BooleanOptionItem.Create(60572, "DisableSkeldAdmin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableSkeldDevices); DisableSkeldCamera = BooleanOptionItem.Create(60573, "DisableSkeldCamera", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableSkeldDevices); DisableMiraHQDevices = BooleanOptionItem.Create(60574, "DisableMiraHQDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisableMiraHQAdmin = BooleanOptionItem.Create(60575, "DisableMiraHQAdmin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableMiraHQDevices); DisableMiraHQDoorLog = BooleanOptionItem.Create(60576, "DisableMiraHQDoorLog", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableMiraHQDevices); DisablePolusDevices = BooleanOptionItem.Create(60577, "DisablePolusDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisablePolusAdmin = BooleanOptionItem.Create(60578, "DisablePolusAdmin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisablePolusDevices); DisablePolusCamera = BooleanOptionItem.Create(60579, "DisablePolusCamera", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisablePolusDevices); DisablePolusVital = BooleanOptionItem.Create(60580, "DisablePolusVital", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisablePolusDevices); DisableAirshipDevices = BooleanOptionItem.Create(60581, "DisableAirshipDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisableAirshipCockpitAdmin = BooleanOptionItem.Create(60582, "DisableAirshipCockpitAdmin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableAirshipDevices); DisableAirshipRecordsAdmin = BooleanOptionItem.Create(60583, "DisableAirshipRecordsAdmin", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableAirshipDevices); DisableAirshipCamera = BooleanOptionItem.Create(60584, "DisableAirshipCamera", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableAirshipDevices); DisableAirshipVital = BooleanOptionItem.Create(60585, "DisableAirshipVital", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableAirshipDevices); DisableFungleDevices = BooleanOptionItem.Create(60586, "DisableFungleDevices", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisableFungleBinoculars = BooleanOptionItem.Create(60587, "DisableFungleBinoculars", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableFungleDevices); DisableFungleVital = BooleanOptionItem.Create(60588, "DisableFungleVital", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableFungleDevices); DisableDevicesIgnoreConditions = BooleanOptionItem.Create(60589, "IgnoreConditions", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevices); DisableDevicesIgnoreImpostors = BooleanOptionItem.Create(60590, "IgnoreImpostors", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevicesIgnoreConditions); DisableDevicesIgnoreNeutrals = BooleanOptionItem.Create(60591, "IgnoreNeutrals", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevicesIgnoreConditions); DisableDevicesIgnoreCrewmates = BooleanOptionItem.Create(60592, "IgnoreCrewmates", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevicesIgnoreConditions); DisableDevicesIgnoreAfterAnyoneDied = BooleanOptionItem.Create(60593, "IgnoreAfterAnyoneDied", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(DisableDevicesIgnoreConditions); DisableShortTasks = BooleanOptionItem.Create(60594, "DisableShortTasks", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).HideInFFA().SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32((byte)239, (byte)89, (byte)175, byte.MaxValue))); DisableCleanVent = BooleanOptionItem.Create(60595, "DisableCleanVent", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCalibrateDistributor = BooleanOptionItem.Create(60596, "DisableCalibrateDistributor", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableChartCourse = BooleanOptionItem.Create(60597, "DisableChartCourse", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableStabilizeSteering = BooleanOptionItem.Create(60598, "DisableStabilizeSteering", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCleanO2Filter = BooleanOptionItem.Create(60599, "DisableCleanO2Filter", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableUnlockManifolds = BooleanOptionItem.Create(60600, "DisableUnlockManifolds", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePrimeShields = BooleanOptionItem.Create(60601, "DisablePrimeShields", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableMeasureWeather = BooleanOptionItem.Create(60602, "DisableMeasureWeather", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableBuyBeverage = BooleanOptionItem.Create(60603, "DisableBuyBeverage", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableAssembleArtifact = BooleanOptionItem.Create(60604, "DisableAssembleArtifact", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableSortSamples = BooleanOptionItem.Create(60605, "DisableSortSamples", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableProcessData = BooleanOptionItem.Create(60606, "DisableProcessData", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableRunDiagnostics = BooleanOptionItem.Create(60607, "DisableRunDiagnostics", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableRepairDrill = BooleanOptionItem.Create(60608, "DisableRepairDrill", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableAlignTelescope = BooleanOptionItem.Create(60609, "DisableAlignTelescope", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableRecordTemperature = BooleanOptionItem.Create(60610, "DisableRecordTemperature", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableFillCanisters = BooleanOptionItem.Create(60611, "DisableFillCanisters", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableMonitorTree = BooleanOptionItem.Create(60612, "DisableMonitorTree", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableStoreArtifacts = BooleanOptionItem.Create(60613, "DisableStoreArtifacts", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePutAwayPistols = BooleanOptionItem.Create(60614, "DisablePutAwayPistols", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePutAwayRifles = BooleanOptionItem.Create(60615, "DisablePutAwayRifles", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableMakeBurger = BooleanOptionItem.Create(60616, "DisableMakeBurger", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCleanToilet = BooleanOptionItem.Create(60617, "DisableCleanToilet", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableDecontaminate = BooleanOptionItem.Create(60618, "DisableDecontaminate", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableSortRecords = BooleanOptionItem.Create(60619, "DisableSortRecords", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableFixShower = BooleanOptionItem.Create(60620, "DisableFixShower", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePickUpTowels = BooleanOptionItem.Create(60621, "DisablePickUpTowels", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePolishRuby = BooleanOptionItem.Create(60622, "DisablePolishRuby", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableDressMannequin = BooleanOptionItem.Create(60623, "DisableDressMannequin", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableFixAntenna = BooleanOptionItem.Create(60656, "DisableFixAntenna", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableBuildSandcastle = BooleanOptionItem.Create(60657, "DisableBuildSandcastle", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCrankGenerator = BooleanOptionItem.Create(60658, "DisableCrankGenerator", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableMonitorMushroom = BooleanOptionItem.Create(60659, "DisableMonitorMushroom", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisablePlayVideoGame = BooleanOptionItem.Create(60660, "DisablePlayVideoGame", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableFindSignal = BooleanOptionItem.Create(60661, "DisableFindSignal", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableThrowFisbee = BooleanOptionItem.Create(60662, "DisableThrowFisbee", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableLiftWeights = BooleanOptionItem.Create(60663, "DisableLiftWeights", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCollectShells = BooleanOptionItem.Create(60664, "DisableCollectShells", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableShortTasks); DisableCommonTasks = BooleanOptionItem.Create(60627, "DisableCommonTasks", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).HideInFFA().SetColor(Color32.op_Implicit(new Color32((byte)239, (byte)89, (byte)175, byte.MaxValue))); DisableSwipeCard = BooleanOptionItem.Create(60628, "DisableSwipeCardTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableFixWiring = BooleanOptionItem.Create(60629, "DisableFixWiring", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableEnterIdCode = BooleanOptionItem.Create(60630, "DisableEnterIdCode", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableInsertKeys = BooleanOptionItem.Create(60631, "DisableInsertKeys", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableScanBoardingPass = BooleanOptionItem.Create(60632, "DisableScanBoardingPass", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableRoastMarshmallow = BooleanOptionItem.Create(60624, "DisableRoastMarshmallow", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableCollectSamples = BooleanOptionItem.Create(60625, "DisableCollectSamples", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableReplaceParts = BooleanOptionItem.Create(60626, "DisableReplaceParts", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableCommonTasks); DisableLongTasks = BooleanOptionItem.Create(60640, "DisableLongTasks", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).HideInFFA().SetColor(Color32.op_Implicit(new Color32((byte)239, (byte)89, (byte)175, byte.MaxValue))); DisableSubmitScan = BooleanOptionItem.Create(60641, "DisableSubmitScanTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableUnlockSafe = BooleanOptionItem.Create(60642, "DisableUnlockSafeTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableStartReactor = BooleanOptionItem.Create(60643, "DisableStartReactorTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableResetBreaker = BooleanOptionItem.Create(60644, "DisableResetBreakerTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableAlignEngineOutput = BooleanOptionItem.Create(60645, "DisableAlignEngineOutput", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableInspectSample = BooleanOptionItem.Create(60646, "DisableInspectSample", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableEmptyChute = BooleanOptionItem.Create(60647, "DisableEmptyChute", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableClearAsteroids = BooleanOptionItem.Create(60648, "DisableClearAsteroids", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableWaterPlants = BooleanOptionItem.Create(60649, "DisableWaterPlants", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableOpenWaterways = BooleanOptionItem.Create(60650, "DisableOpenWaterways", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableReplaceWaterJug = BooleanOptionItem.Create(60651, "DisableReplaceWaterJug", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableRebootWifi = BooleanOptionItem.Create(60652, "DisableRebootWifi", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableDevelopPhotos = BooleanOptionItem.Create(60653, "DisableDevelopPhotos", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableRewindTapes = BooleanOptionItem.Create(60654, "DisableRewindTapes", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableStartFans = BooleanOptionItem.Create(60655, "DisableStartFans", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableCollectVegetables = BooleanOptionItem.Create(60633, "DisableCollectVegetables", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableMineOres = BooleanOptionItem.Create(60634, "DisableMineOres", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableExtractFuel = BooleanOptionItem.Create(60635, "DisableExtractFuel", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableCatchFish = BooleanOptionItem.Create(60636, "DisableCatchFish", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisablePolishGem = BooleanOptionItem.Create(60637, "DisablePolishGem", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableHelpCritter = BooleanOptionItem.Create(60638, "DisableHelpCritter", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableHoistSupplies = BooleanOptionItem.Create(60639, "DisableHoistSupplies", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableLongTasks); DisableOtherTasks = BooleanOptionItem.Create(60665, "DisableOtherTasks", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).HideInFFA().SetColor(Color32.op_Implicit(new Color32((byte)239, (byte)89, (byte)175, byte.MaxValue))); DisableUploadData = BooleanOptionItem.Create(60666, "DisableUploadDataTask", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableOtherTasks); DisableEmptyGarbage = BooleanOptionItem.Create(60667, "DisableEmptyGarbage", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableOtherTasks); DisableFuelEngines = BooleanOptionItem.Create(60668, "DisableFuelEngines", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableOtherTasks); DisableDivertPower = BooleanOptionItem.Create(60669, "DisableDivertPower", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableOtherTasks); DisableActivateWeatherNodes = BooleanOptionItem.Create(60670, "DisableActivateWeatherNodes", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(DisableOtherTasks); TextOptionItem.Create(10000028, "MenuTitle.Guessers", TabGroup.ModifierSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color.yellow) .SetHeader(value: true); GuesserMode = BooleanOptionItem.Create(60680, "GuesserMode", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color.yellow) .SetHeader(value: true); CrewmatesCanGuess = BooleanOptionItem.Create(60681, "CrewmatesCanGuess", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode); ImpostorsCanGuess = BooleanOptionItem.Create(60682, "ImpostorsCanGuess", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode); NeutralKillersCanGuess = BooleanOptionItem.Create(60683, "NeutralKillersCanGuess", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode); PassiveNeutralsCanGuess = BooleanOptionItem.Create(60684, "PassiveNeutralsCanGuess", defaultValue: false, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode); CanGuessAddons = BooleanOptionItem.Create(60685, "CanGuessAddons", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode); CrewCanGuessCrew = BooleanOptionItem.Create(60686, "CrewCanGuessCrew", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetHidden(value: true).SetParent(GuesserMode); ImpCanGuessImp = BooleanOptionItem.Create(60687, "ImpCanGuessImp", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetHidden(value: true).SetParent(GuesserMode); HideGuesserCommands = BooleanOptionItem.Create(60688, "GuesserTryHideMsg", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(GuesserMode).SetColor(Color.green); ShowOnlyEnabledRolesInGuesserUI = BooleanOptionItem.Create(60689, "ShowOnlyEnabledRolesInGuesserUI", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetHeader(value: true).SetGameMode(CustomGameMode.Standard) .SetColor(Color.cyan); TextOptionItem.Create(10000029, "MenuTitle.GuesserModeRoles", TabGroup.ModifierSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color.yellow) .SetHeader(value: true); DoubleShot.SetupCustomOption(); Onbound.SetupCustomOptions(); Rebound.SetupCustomOptions(); TextOptionItem.Create(10000030, "MenuTitle.Meeting", TabGroup.ModSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)147, (byte)241, (byte)240, byte.MaxValue))); SyncButtonMode = BooleanOptionItem.Create(60700, "SyncButtonMode", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetHeader(value: true).SetColor(Color32.op_Implicit(new Color32((byte)147, (byte)241, (byte)240, byte.MaxValue))) .SetGameMode(CustomGameMode.Standard); SyncedButtonCount = IntegerOptionItem.Create(60701, "SyncedButtonCount", new IntegerValueRule(0, 100, 1), 10, TabGroup.ModSettings, isSingleValue: false).SetParent(SyncButtonMode).SetValueFormat(OptionFormat.Times) .SetGameMode(CustomGameMode.Standard); AllAliveMeeting = BooleanOptionItem.Create(60710, "AllAliveMeeting", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)147, (byte)241, (byte)240, byte.MaxValue))); AllAliveMeetingTime = FloatOptionItem.Create(60711, "AllAliveMeetingTime", new FloatValueRule(1f, 300f, 1f), 10f, TabGroup.ModSettings, isSingleValue: false).SetParent(AllAliveMeeting).SetValueFormat(OptionFormat.Seconds); AdditionalEmergencyCooldown = BooleanOptionItem.Create(60720, "AdditionalEmergencyCooldown", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)147, (byte)241, (byte)240, byte.MaxValue))); AdditionalEmergencyCooldownThreshold = IntegerOptionItem.Create(60721, "AdditionalEmergencyCooldownThreshold", new IntegerValueRule(1, 15, 1), 1, TabGroup.ModSettings, isSingleValue: false).SetParent(AdditionalEmergencyCooldown).SetGameMode(CustomGameMode.Standard) .SetValueFormat(OptionFormat.Players); AdditionalEmergencyCooldownTime = FloatOptionItem.Create(60722, "AdditionalEmergencyCooldownTime", new FloatValueRule(1f, 60f, 1f), 1f, TabGroup.ModSettings, isSingleValue: false).SetParent(AdditionalEmergencyCooldown).SetGameMode(CustomGameMode.Standard) .SetValueFormat(OptionFormat.Seconds); VoteMode = BooleanOptionItem.Create(60730, "VoteMode", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)147, (byte)241, (byte)240, byte.MaxValue))).SetGameMode(CustomGameMode.Standard); WhenSkipVote = StringOptionItem.Create(60731, "WhenSkipVote", voteModes[0..3], 0, TabGroup.ModSettings, isSingleValue: false).SetParent(VoteMode).SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreFirstMeeting = BooleanOptionItem.Create(60732, "WhenSkipVoteIgnoreFirstMeeting", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(WhenSkipVote).SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreNoDeadBody = BooleanOptionItem.Create(60733, "WhenSkipVoteIgnoreNoDeadBody", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(WhenSkipVote).SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreEmergency = BooleanOptionItem.Create(60734, "WhenSkipVoteIgnoreEmergency", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(WhenSkipVote).SetGameMode(CustomGameMode.Standard); WhenNonVote = StringOptionItem.Create(60735, "WhenNonVote", voteModes, 0, TabGroup.ModSettings, isSingleValue: false).SetParent(VoteMode).SetGameMode(CustomGameMode.Standard); WhenTie = StringOptionItem.Create(60745, "WhenTie", tieModes, 0, TabGroup.ModSettings, isSingleValue: false).SetParent(VoteMode).SetGameMode(CustomGameMode.Standard); TextOptionItem.Create(10000031, "MenuTitle.Other", TabGroup.ModSettings).HideInFFA().SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))); LadderDeath = BooleanOptionItem.Create(60760, "LadderDeath", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))).HideInFFA(); LadderDeathChance = StringOptionItem.Create(60761, "LadderDeathChance", EnumHelper.GetAllNames()[1..], 0, TabGroup.ModSettings, isSingleValue: false).SetParent(LadderDeath); FixFirstKillCooldown = BooleanOptionItem.Create(60770, "FixFirstKillCooldown", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))); FixKillCooldownValue = FloatOptionItem.Create(60771, "FixKillCooldownValue", new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.ModSettings, isSingleValue: false).SetValueFormat(OptionFormat.Seconds).SetParent(FixFirstKillCooldown); ShieldPersonDiedFirst = BooleanOptionItem.Create(60780, "ShieldPersonDiedFirst", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))); EveryoneCanSeeDeathReason = BooleanOptionItem.Create(60781, "EveryoneCanSeeDeathReason", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))); KillFlashDuration = FloatOptionItem.Create(60790, "KillFlashDuration", new FloatValueRule(0.1f, 0.45f, 0.05f), 0.3f, TabGroup.ModSettings, isSingleValue: false).SetColor(Color32.op_Implicit(new Color32((byte)193, byte.MaxValue, (byte)209, byte.MaxValue))).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); TextOptionItem.Create(10000032, "MenuTitle.Ghost", TabGroup.ModSettings).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); GhostIgnoreTasks = BooleanOptionItem.Create(60800, "GhostIgnoreTasks", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetHeader(value: true) .SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); GhostCanSeeOtherRoles = BooleanOptionItem.Create(60810, "GhostCanSeeOtherRoles", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); GhostCanSeeOtherVotes = BooleanOptionItem.Create(60820, "GhostCanSeeOtherVotes", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); GhostCanSeeDeathReason = BooleanOptionItem.Create(60830, "GhostCanSeeDeathReason", defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); ConvertedCanBecomeGhost = BooleanOptionItem.Create(60840, "ConvertedCanBeGhostRole", defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); MaxImpGhost = IntegerOptionItem.Create(60850, "MaxImpGhostRole", new IntegerValueRule(0, 15, 1), 15, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetValueFormat(OptionFormat.Times) .SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); MaxCrewGhost = IntegerOptionItem.Create(60860, "MaxCrewGhostRole", new IntegerValueRule(0, 15, 1), 15, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetValueFormat(OptionFormat.Times) .SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); DefaultAngelCooldown = FloatOptionItem.Create(60870, "DefaultAngelCooldown", new FloatValueRule(2.5f, 120f, 2.5f), 35f, TabGroup.ModSettings, isSingleValue: false).SetGameMode(CustomGameMode.Standard).SetValueFormat(OptionFormat.Seconds) .SetColor(Color32.op_Implicit(new Color32((byte)217, (byte)218, byte.MaxValue, byte.MaxValue))); yield return null; OptionSaver.Load(); IsLoaded = true; Logger.Msg("Mod option loading eng", "Load Options", escapeCRLF: true, 1907, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionHolder.cs"); } public static void SetupRoleOptions(int id, TabGroup tab, CustomRoles role, CustomGameMode customGameMode = CustomGameMode.Standard, bool zeroOne = false) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) StringOptionItem stringOptionItem = StringOptionItem.Create(id, role.ToString(), zeroOne ? EnumHelper.GetAllNames() : EnumHelper.GetAllNames(), 0, tab, isSingleValue: false).SetColor(Utils.GetRoleColor(role)).SetHeader(value: true) .SetGameMode(customGameMode) as StringOptionItem; OptionItem value = IntegerOptionItem.Create(id + 1, "Maximum", new IntegerValueRule(1, 15, 1), 1, tab, isSingleValue: false).SetParent(stringOptionItem).SetValueFormat(OptionFormat.Players) .SetGameMode(customGameMode); if (role.IsGhostRole()) { CustomGhostRoleCounts.Add(role, value); } CustomRoleSpawnChances.Add(role, stringOptionItem); CustomRoleCounts.Add(role, value); } private static void SetupLoversRoleOptionsToggle(int id, CustomGameMode customGameMode = CustomGameMode.Standard) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) CustomRoles customRoles = CustomRoles.Lovers; StringOptionItem stringOptionItem = StringOptionItem.Create(id, customRoles.ToString(), EnumHelper.GetAllNames(), 0, TabGroup.Addons, isSingleValue: false).SetColor(Utils.GetRoleColor(customRoles)).SetHeader(value: true) .SetGameMode(customGameMode) as StringOptionItem; LoverSpawnChances = IntegerOptionItem.Create(id + 2, "LoverSpawnChances", new IntegerValueRule(0, 100, 5), 50, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetValueFormat(OptionFormat.Percent) .SetGameMode(customGameMode); LoverKnowRoles = BooleanOptionItem.Create(id + 4, "LoverKnowRoles", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetGameMode(customGameMode); LoverSuicide = BooleanOptionItem.Create(id + 3, "LoverSuicide", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetGameMode(customGameMode); ImpCanBeInLove = BooleanOptionItem.Create(id + 5, "ImpCanBeInLove", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetGameMode(customGameMode); CrewCanBeInLove = BooleanOptionItem.Create(id + 6, "CrewCanBeInLove", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetGameMode(customGameMode); NeutralCanBeInLove = BooleanOptionItem.Create(id + 7, "NeutralCanBeInLove", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetGameMode(customGameMode); OptionItem value = IntegerOptionItem.Create(id + 1, "NumberOfLovers", new IntegerValueRule(2, 2, 1), 2, TabGroup.Addons, isSingleValue: false).SetParent(stringOptionItem).SetHidden(value: true) .SetGameMode(customGameMode); CustomRoleSpawnChances.Add(customRoles, stringOptionItem); CustomRoleCounts.Add(customRoles, value); } public static void SetupAdtRoleOptions(int id, CustomRoles role, CustomGameMode customGameMode = CustomGameMode.Standard, bool canSetNum = false, TabGroup tab = TabGroup.Addons, bool canSetChance = true) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) StringOptionItem stringOptionItem = StringOptionItem.Create(id, role.ToString(), EnumHelper.GetAllNames(), 0, tab, isSingleValue: false).SetColor(Utils.GetRoleColor(role)).SetHeader(value: true) .SetGameMode(customGameMode) as StringOptionItem; OptionItem value = IntegerOptionItem.Create(id + 1, "Maximum", new IntegerValueRule(1, (!canSetNum) ? 1 : 10, 1), 1, tab, isSingleValue: false).SetParent(stringOptionItem).SetValueFormat(OptionFormat.Players) .SetHidden(!canSetNum) .SetGameMode(customGameMode); IntegerOptionItem value2 = IntegerOptionItem.Create(id + 2, "AdditionRolesSpawnRate", new IntegerValueRule(0, 100, 5), canSetChance ? 65 : 100, tab, isSingleValue: false).SetParent(stringOptionItem).SetValueFormat(OptionFormat.Percent) .SetHidden(!canSetChance) .SetGameMode(customGameMode) as IntegerOptionItem; CustomAdtRoleSpawnRate.Add(role, value2); CustomRoleSpawnChances.Add(role, stringOptionItem); CustomRoleCounts.Add(role, value); } public static void SetupSingleRoleOptions(int id, TabGroup tab, CustomRoles role, int count = 1, CustomGameMode customGameMode = CustomGameMode.Standard, bool zeroOne = false) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) StringOptionItem stringOptionItem = StringOptionItem.Create(id, role.ToString(), zeroOne ? EnumHelper.GetAllNames() : EnumHelper.GetAllNames(), 0, tab, isSingleValue: false).SetColor(Utils.GetRoleColor(role)).SetHeader(value: true) .SetGameMode(customGameMode) as StringOptionItem; OptionItem value = IntegerOptionItem.Create(id + 1, "Maximum", new IntegerValueRule(count, count, count), count, tab, isSingleValue: false).SetParent(stringOptionItem).SetHidden(value: true) .SetGameMode(customGameMode); if (role.IsGhostRole()) { CustomGhostRoleCounts.Add(role, value); } CustomRoleSpawnChances.Add(role, stringOptionItem); CustomRoleCounts.Add(role, value); } } public class BooleanOptionItem : OptionItem { public const string TEXT_true = "ColoredOn"; public const string TEXT_false = "ColoredOff"; public BooleanOptionItem(int id, string name, bool defaultValue, TabGroup tab, bool isSingleValue, bool vanilla) : base(id, name, defaultValue ? 1 : 0, tab, isSingleValue, vanilla) { } public static BooleanOptionItem Create(int id, string name, bool defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new BooleanOptionItem(id, name, defaultValue, tab, isSingleValue, vanillaText); } public static BooleanOptionItem Create(int id, Enum name, bool defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new BooleanOptionItem(id, name.ToString(), defaultValue, tab, isSingleValue, vanillaText); } public override string GetString() { return Translator.GetString(GetBool() ? "ColoredOn" : "ColoredOff"); } public override void SetValue(int value, bool doSync = true) { base.SetValue((value % 2 != 0) ? 1 : 0, doSync); } } public class FloatOptionItem : OptionItem { public FloatValueRule Rule; public FloatOptionItem(int id, string name, float defaultValue, TabGroup tab, bool isSingleValue, FloatValueRule rule, bool vanilla) { Rule = rule; base..ctor(id, name, rule.GetNearestIndex(defaultValue), tab, isSingleValue, vanilla); } public static FloatOptionItem Create(int id, string name, FloatValueRule rule, float defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new FloatOptionItem(id, name, defaultValue, tab, isSingleValue, rule, vanillaText); } public static FloatOptionItem Create(int id, Enum name, FloatValueRule rule, float defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new FloatOptionItem(id, name.ToString(), defaultValue, tab, isSingleValue, rule, vanillaText); } public override int GetInt() { return (int)Rule.GetValueByIndex(base.CurrentValue); } public override float GetFloat() { return Rule.GetValueByIndex(base.CurrentValue); } public override string GetString() { return ApplyFormat(((float)((double)(int)(Rule.GetValueByIndex(base.CurrentValue) * 100f) * 1.0) / 100f).ToString()); } public override int GetValue() { return Rule.RepeatIndex(base.GetValue()); } public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } } public class IntegerOptionItem : OptionItem { public IntegerValueRule Rule; public IntegerOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, IntegerValueRule rule, bool vanilla) { Rule = rule; base..ctor(id, name, rule.GetNearestIndex(defaultValue), tab, isSingleValue, vanilla); } public static IntegerOptionItem Create(int id, string name, IntegerValueRule rule, int defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new IntegerOptionItem(id, name, defaultValue, tab, isSingleValue, rule, vanillaText); } public static IntegerOptionItem Create(int id, Enum name, IntegerValueRule rule, int defaultValue, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new IntegerOptionItem(id, name.ToString(), defaultValue, tab, isSingleValue, rule, vanillaText); } public override int GetInt() { return Rule.GetValueByIndex(base.CurrentValue); } public override float GetFloat() { return Rule.GetValueByIndex(base.CurrentValue); } public override string GetString() { return ApplyFormat(Rule.GetValueByIndex(base.CurrentValue).ToString()); } public override int GetValue() { return Rule.RepeatIndex(base.GetValue()); } public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } } public abstract class OptionItem { public class UpdateValueEventArgs : EventArgs { public int CurrentValue { get; set; } public int BeforeValue { get; set; } public UpdateValueEventArgs(int beforeValue, int currentValue) { CurrentValue = currentValue; BeforeValue = beforeValue; base..ctor(); } } private static readonly List _allOptions = new List(1024); private static readonly Dictionary _fastOptions = new Dictionary(1024); private static readonly Dictionary nameSettings = new Dictionary(); private Dictionary _replacementDictionary; public List Children; public OptionBehaviour OptionBehaviour; public const int NumPresets = 5; public const int PresetId = 0; public static IReadOnlyList AllOptions => _allOptions; public static IReadOnlyDictionary FastOptions => _fastOptions; public static int CurrentPreset { get; set; } public int Id { get; } public string Name { get; } public int DefaultValue { get; } public TabGroup Tab { get; } public bool IsSingleValue { get; } public Color NameColor { get; protected set; } public OptionFormat ValueFormat { get; protected set; } public CustomGameMode GameMode { get; protected set; } public CustomGameMode HideOptionInFFA { get; protected set; } public CustomGameMode HideOptionInHnS { get; protected set; } public bool IsHeader { get; protected set; } public bool IsHidden { get; protected set; } public bool IsText { get; protected set; } public bool IsVanillaText { get; protected set; } public Dictionary ReplacementDictionary { get { return _replacementDictionary; } set { if (value == null) { _replacementDictionary?.Clear(); } else { _replacementDictionary = value; } } } public int[] AllValues { get; private set; } = new int[5]; public int CurrentValue { get { return GetValue(); } set { SetValue(value); } } public int SingleValue { get; private set; } public OptionItem Parent { get; private set; } public event EventHandler UpdateValueEvent; public OptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, bool vanillaStr) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Id = id; Name = name; DefaultValue = defaultValue; Tab = tab; IsSingleValue = isSingleValue; IsVanillaText = vanillaStr; NameColor = Color.white; ValueFormat = OptionFormat.None; GameMode = CustomGameMode.All; HideOptionInFFA = CustomGameMode.All; HideOptionInHnS = CustomGameMode.All; IsHeader = false; IsHidden = false; IsText = false; Children = new List(); if (Id == 0) { SingleValue = DefaultValue; CurrentPreset = SingleValue; } else if (IsSingleValue) { SingleValue = DefaultValue; } else { for (int i = 0; i < 5; i++) { AllValues[i] = DefaultValue; } } if (_fastOptions.TryAdd(id, this)) { _allOptions.Add(this); nameSettings.Add(id, name); return; } Logger.Error($"Duplicate ID: {id} Name: {name}", "OptionItem", escapeCRLF: true, 112, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionItem\\OptionItem.cs"); nameSettings.TryGetValue(id, out var value); Logger.Error("Duplicate from: " + value, "OptionItem", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionItem\\OptionItem.cs"); } public OptionItem Do(Action action) { action(this); return this; } public OptionItem SetColor(Color value) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Do(delegate(OptionItem i) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) i.NameColor = value; }); } public OptionItem SetValueFormat(OptionFormat value) { return Do(delegate(OptionItem i) { i.ValueFormat = value; }); } public OptionItem SetGameMode(CustomGameMode value) { return Do(delegate(OptionItem i) { i.GameMode = value; }); } public OptionItem SetHeader(bool value) { return Do(delegate(OptionItem i) { i.IsHeader = value; }); } public OptionItem SetHidden(bool value) { return Do(delegate(OptionItem i) { i.IsHidden = value; }); } public OptionItem SetText(bool value) { return Do(delegate(OptionItem i) { i.IsText = value; }); } public OptionItem HideInFFA(CustomGameMode value = CustomGameMode.FFA) { return Do(delegate(OptionItem i) { i.HideOptionInFFA = value; }); } public OptionItem HideInHnS(CustomGameMode value = CustomGameMode.HidenSeekTOHE) { return Do(delegate(OptionItem i) { i.HideOptionInHnS = value; }); } public OptionItem SetParent(OptionItem parent) { return Do(delegate(OptionItem i) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) KeyValuePair[] array = Options.CustomRoleSpawnChances.Where((KeyValuePair x) => x.Value.Name == parent.Name).ToArray(); int num = 0; if (num < array.Length) { KeyValuePair keyValuePair = array[num]; string @string = Translator.GetString(Enum.GetName(typeof(CustomRoles), keyValuePair.Key)); if (ReplacementDictionary == null) { Dictionary dictionary2 = (ReplacementDictionary = new Dictionary()); } ReplacementDictionary.TryAdd(@string, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(keyValuePair.Key)), @string)); } i.Parent = parent; parent.SetChild(i); }); } public OptionItem SetChild(OptionItem child) { return Do(delegate(OptionItem i) { i.Children.Add(child); }); } public OptionItem RegisterUpdateValueEvent(EventHandler handler) { return Do(delegate { UpdateValueEvent += handler; }); } public OptionItem AddReplacement((string key, string value) kvp) { return Do(delegate { if (ReplacementDictionary == null) { Dictionary dictionary2 = (ReplacementDictionary = new Dictionary()); } ReplacementDictionary.Add(kvp.key, kvp.value); }); } public OptionItem RemoveReplacement(string key) { return Do(delegate { ReplacementDictionary?.Remove(key); }); } public virtual string GetName(bool disableColor = false, bool console = false) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!disableColor) { return Utils.ColorString(Color32.op_Implicit(NameColor), Translator.GetString(Name, ReplacementDictionary)); } return Translator.GetString(Name, ReplacementDictionary, console); } public virtual string GetNameVanilla() { return Translator.GetString(Name, ReplacementDictionary, console: false, showInvalid: true, vanilla: true); } public virtual bool GetBool() { if (CurrentValue != 0) { if (Parent != null) { return Parent.GetBool(); } return true; } return false; } public virtual int GetInt() { return CurrentValue; } public virtual float GetFloat() { return CurrentValue; } public virtual string GetString() { return ApplyFormat(CurrentValue.ToString()); } public virtual int GetValue() { if (!IsSingleValue) { return AllValues[CurrentPreset]; } return SingleValue; } public virtual bool IsHiddenOn(CustomGameMode mode) { if (!IsHidden && (HideOptionInFFA == CustomGameMode.All || HideOptionInFFA != mode) && (HideOptionInHnS == CustomGameMode.All || HideOptionInHnS != mode)) { if (GameMode != CustomGameMode.All) { return GameMode != mode; } return false; } return true; } public string ApplyFormat(string value) { if (ValueFormat == OptionFormat.None) { return value; } return string.Format(Translator.GetString("Format." + ValueFormat), value); } public virtual void Refresh() { OptionBehaviour optionBehaviour = OptionBehaviour; if (optionBehaviour == null) { return; } StringOption val = (StringOption)(object)((optionBehaviour is StringOption) ? optionBehaviour : null); if (val != null) { if (IsVanillaText) { ((TMP_Text)val.TitleText).text = GetNameVanilla(); } else { ((TMP_Text)val.TitleText).text = GetName(); } ((TMP_Text)val.ValueText).text = GetString(); int oldValue = (val.Value = CurrentValue); val.oldValue = oldValue; } } public virtual void SetValue(int afterValue, bool doSave, bool doSync = true) { int currentValue = CurrentValue; if (IsSingleValue) { SingleValue = afterValue; } else { AllValues[CurrentPreset] = afterValue; } CallUpdateValueEvent(currentValue, afterValue); Refresh(); if (doSync) { SyncAllOptions(); } if (doSave) { OptionSaver.Save(); } } public virtual void SetValue(int afterValue, bool doSync = true) { SetValue(afterValue, doSave: true, doSync); } public void SetAllValues(int[] values) { AllValues = values; } public virtual void SetValueNoRpc(int value) { int currentValue = CurrentValue; int num2 = (CurrentValue = value); int currentValue2 = num2; CallUpdateValueEvent(currentValue, currentValue2); Refresh(); } public static OptionItem operator ++(OptionItem item) { return item.Do(delegate(OptionItem item) { item.SetValue(item.CurrentValue + 1); }); } public static OptionItem operator --(OptionItem item) { return item.Do(delegate(OptionItem item) { item.SetValue(item.CurrentValue - 1); }); } public static void SwitchPreset(int newPreset) { CurrentPreset = Math.Clamp(newPreset, 0, 4); OptionItem[] array = AllOptions.ToArray(); for (int i = 0; i < array.Length; i++) { array[i].Refresh(); } SyncAllOptions(); } public static void SyncAllOptions(int targetId = -1) { if (Main.AllPlayerControls.Length > 1 && ((InnerNetClient)AmongUsClient.Instance).AmHost && !((Object)(object)PlayerControl.LocalPlayer == (Object)null)) { RPC.SyncCustomSettingsRPC(targetId); } } private void CallUpdateValueEvent(int beforeValue, int currentValue) { if (this.UpdateValueEvent == null) { return; } try { this.UpdateValueEvent(this, new UpdateValueEventArgs(beforeValue, currentValue)); } catch (Exception ex) { Logger.Error("[" + Name + "] - Exception occurred when calling UpdateValueEvent", "OptionItem.UpdateValueEvent", escapeCRLF: true, 287, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionItem\\OptionItem.cs"); Logger.Exception(ex, "OptionItem.UpdateValueEvent", 288, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionItem\\OptionItem.cs"); } } } public enum TabGroup { SystemSettings, ModSettings, ModifierSettings, ImpostorRoles, CrewmateRoles, NeutralRoles, Addons } public enum OptionFormat { None, Players, Seconds, Percent, Times, Multiplier, Votes, Pieces, Health, Level } public class PresetOptionItem : OptionItem { public IntegerValueRule Rule = (0, 4, 1); public int ValuePresets = 5; public PresetOptionItem(int defaultValue, TabGroup tab, bool vanilla) : base(0, "Preset", defaultValue, tab, isSingleValue: true, vanilla) { } public static PresetOptionItem Create(int defaultValue, TabGroup tab, bool vanillaText = false) { return new PresetOptionItem(defaultValue, tab, vanillaText); } public override int GetInt() { return Rule.GetValueByIndex(base.CurrentValue); } public override float GetFloat() { return Rule.GetValueByIndex(base.CurrentValue); } public override string GetString() { return base.CurrentValue switch { 0 => (Main.Preset1.Value == (string)((ConfigEntryBase)Main.Preset1).DefaultValue) ? Translator.GetString("Preset_1") : Main.Preset1.Value, 1 => (Main.Preset2.Value == (string)((ConfigEntryBase)Main.Preset2).DefaultValue) ? Translator.GetString("Preset_2") : Main.Preset2.Value, 2 => (Main.Preset3.Value == (string)((ConfigEntryBase)Main.Preset3).DefaultValue) ? Translator.GetString("Preset_3") : Main.Preset3.Value, 3 => (Main.Preset4.Value == (string)((ConfigEntryBase)Main.Preset4).DefaultValue) ? Translator.GetString("Preset_4") : Main.Preset4.Value, 4 => (Main.Preset5.Value == (string)((ConfigEntryBase)Main.Preset5).DefaultValue) ? Translator.GetString("Preset_5") : Main.Preset5.Value, _ => null, }; } public override int GetValue() { return Rule.RepeatIndex(base.GetValue()); } public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); OptionItem.SwitchPreset(Rule.RepeatIndex(value)); } public override void SetValue(int afterValue, bool doSave, bool doSync = true) { base.SetValue(Rule.RepeatIndex(afterValue), doSave, doSync); OptionItem.SwitchPreset(Rule.RepeatIndex(afterValue)); } } public class StringOptionItem : OptionItem { public IntegerValueRule Rule = (0, selections.Length - 1, 1); public string[] Selections; public StringOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, string[] selections, bool vanilla) { Selections = selections; base..ctor(id, name, defaultValue, tab, isSingleValue, vanilla); } public static StringOptionItem Create(int id, string name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new StringOptionItem(id, name, defaultIndex, tab, isSingleValue, selections, vanillaText); } public static StringOptionItem Create(int id, Enum name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new StringOptionItem(id, name.ToString(), defaultIndex, tab, isSingleValue, selections, vanillaText); } public override int GetInt() { return Rule.GetValueByIndex(base.CurrentValue); } public override float GetFloat() { return Rule.GetValueByIndex(base.CurrentValue); } public override string GetString() { return Translator.GetString(Selections[Rule.GetValueByIndex(base.CurrentValue)]); } public int GetChance() { if (Selections.Length == 2) { return base.CurrentValue * 100; } if (Selections.Length == 3) { return base.CurrentValue; } int num = EnumHelper.GetAllNames().Length - Selections.Length; return (base.CurrentValue + num) * 5; } public override int GetValue() { return Rule.RepeatIndex(base.GetValue()); } public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } } public class TextOptionItem : OptionItem { public IntegerValueRule Rule; public TextOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, bool vanilla) : base(id, name, defaultValue, tab, isSingleValue, vanilla) { base.IsText = true; base.IsHeader = true; } public static TextOptionItem Create(int id, string name, TabGroup tab, bool isSingleValue = false, bool vanillaText = false) { return new TextOptionItem(id, name, 0, tab, isSingleValue, vanillaText); } public override string GetString() { return Translator.GetString(base.Name); } } public abstract class ValueRule { public T MinValue { get; protected set; } public T MaxValue { get; protected set; } public T Step { get; protected set; } protected ValueRule(T minValue, T maxValue, T step) { MinValue = minValue; MaxValue = maxValue; Step = step; base..ctor(); } public ValueRule((T, T, T) tuple) : this(tuple.Item1, tuple.Item2, tuple.Item3) { } public abstract int RepeatIndex(int value); public abstract T GetValueByIndex(int index); public abstract int GetNearestIndex(T num); } public class IntegerValueRule : ValueRule { public IntegerValueRule(int minValue, int maxValue, int step) : base(minValue, maxValue, step) { } public IntegerValueRule((int, int, int) tuple) : base(tuple) { } public static implicit operator IntegerValueRule((int, int, int) tuple) { return new IntegerValueRule(tuple); } public override int RepeatIndex(int value) { int num = (base.MaxValue - base.MinValue) / base.Step; value %= num + 1; if (value < 0) { value = num; } return value; } public override int GetValueByIndex(int index) { return RepeatIndex(index) * base.Step + base.MinValue; } public override int GetNearestIndex(int num) { return (int)Math.Round((float)(num - base.MinValue) / (float)base.Step); } } public class FloatValueRule : ValueRule { public FloatValueRule(float minValue, float maxValue, float step) : base(minValue, maxValue, step) { } public FloatValueRule((float, float, float) tuple) : base(tuple) { } public static implicit operator FloatValueRule((float, float, float) tuple) { return new FloatValueRule(tuple); } public override int RepeatIndex(int value) { int num = (int)((base.MaxValue - base.MinValue) / base.Step); value %= num + 1; if (value < 0) { value = num; } return value; } public override float GetValueByIndex(int index) { return (float)RepeatIndex(index) * base.Step + base.MinValue; } public override int GetNearestIndex(float num) { return (int)Math.Round((num - base.MinValue) / base.Step); } } public static class OptionShower { public static int currentPage; public static List pages; private static byte DelayInUpdate; static OptionShower() { currentPage = 0; pages = new List(); DelayInUpdate = 0; } public static string GetTextNoFresh() { try { if (currentPage == 0 && DelayInUpdate >= 100) { DelayInUpdate = 0; GetText(); } DelayInUpdate++; return $"{pages[currentPage]}{Translator.GetString("PressTabToNextPage")}({currentPage + 1}/{pages.Count})"; } catch { return GetText(); } } public static string GetText() { //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) StringBuilder sb = new StringBuilder(); pages = new List(1) { IGameOptionsExtensions.ToHudString(GameOptionsManager.Instance.CurrentGameOptions, Object.op_Implicit((Object)(object)GameData.Instance) ? GameData.Instance.PlayerCount : 10) + "\n\n" }; StringBuilder stringBuilder = sb; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 2, stringBuilder); handler.AppendFormatted(Options.GameMode.GetName()); handler.AppendLiteral(": "); handler.AppendFormatted(Options.GameMode.GetString()); handler.AppendLiteral("\n\n"); stringBuilder2.Append(ref handler); if (Options.HideGameSettings.GetBool() && !((InnerNetClient)AmongUsClient.Instance).AmHost) { stringBuilder = sb; StringBuilder stringBuilder3 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(23, 1, stringBuilder); handler.AppendLiteral(""); handler.AppendFormatted(Translator.GetString("Message.HideGameSettings")); handler.AppendLiteral(""); stringBuilder3.Append(ref handler); } else { KeyValuePair[] array; if (Options.CurrentGameMode == CustomGameMode.Standard) { sb.Append(Translator.GetString("ActiveRolesList")).Append('\n'); array = Options.CustomRoleSpawnChances.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; CustomGameMode gameMode = keyValuePair.Value.GameMode; bool flag = ((gameMode == CustomGameMode.Standard || gameMode == CustomGameMode.All) ? true : false); if (flag && keyValuePair.Value.GetBool()) { string value = keyValuePair.Value.GetString(); if (keyValuePair.Key == CustomRoles.Lovers) { value = Utils.GetChance(Options.LoverSpawnChances.GetInt()); } else if (keyValuePair.Key.IsAdditionRole() && Options.CustomAdtRoleSpawnRate.ContainsKey(keyValuePair.Key)) { value = Utils.GetChance(Options.CustomAdtRoleSpawnRate[keyValuePair.Key].GetFloat()); } stringBuilder = sb; StringBuilder stringBuilder4 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(4, 3, stringBuilder); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(keyValuePair.Key)), Utils.GetRoleName(keyValuePair.Key))); handler.AppendLiteral(": "); handler.AppendFormatted(value); handler.AppendLiteral("×"); handler.AppendFormatted(keyValuePair.Key.GetCount()); handler.AppendLiteral("\n"); stringBuilder4.Append(ref handler); } } pages.Add(sb.ToString() + "\n\n"); sb.Clear(); } pages.Add(""); array = Options.CustomRoleSpawnChances.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair2 = array[i]; if (keyValuePair2.Key.IsEnable() && !keyValuePair2.Value.IsHiddenOn(Options.CurrentGameMode)) { sb.Append('\n'); stringBuilder = sb; StringBuilder stringBuilder5 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(4, 3, stringBuilder); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(keyValuePair2.Key)), Utils.GetRoleName(keyValuePair2.Key))); handler.AppendLiteral(": "); handler.AppendFormatted(keyValuePair2.Value.GetString()); handler.AppendLiteral("×"); handler.AppendFormatted(keyValuePair2.Key.GetCount()); handler.AppendLiteral("\n"); stringBuilder5.Append(ref handler); ShowChildren(keyValuePair2.Value, ref sb, Utils.GetRoleColor(keyValuePair2.Key).ShadeColor(-0.5f), 1); Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed.ShadeColor(-0.5f)), "┣ "); Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed.ShadeColor(-0.5f)), "┗ "); } } OptionItem[] array2 = OptionItem.AllOptions.Where((OptionItem x) => x.Id > 59999 && !x.IsHiddenOn(Options.CurrentGameMode) && x.Parent == null && !x.IsText).ToArray(); foreach (OptionItem optionItem in array2) { if (optionItem.IsHeader) { sb.Append('\n'); } stringBuilder = sb; StringBuilder stringBuilder6 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder); handler.AppendFormatted(optionItem.GetName()); handler.AppendLiteral(": "); handler.AppendFormatted(optionItem.GetString()); handler.AppendLiteral("\n"); stringBuilder6.Append(ref handler); if (optionItem.GetBool()) { ShowChildren(optionItem, ref sb, Color.white, 1); } } } string[] array3 = new List(sb.ToString().Split("\n\n")).ToArray(); foreach (string text in array3) { List list = pages; if (list[list.Count - 1].Count((char c) => c == '\n') + 1 + text.Count((char c) => c == '\n') + 1 > 35) { pages.Add(text + "\n\n"); continue; } List list2 = pages; int index = list2.Count - 1; list2[index] = list2[index] + text + "\n\n"; } if (currentPage >= pages.Count) { currentPage = pages.Count - 1; } return $"{pages[currentPage]}{Translator.GetString("PressTabToNextPage")}({currentPage + 1}/{pages.Count})"; } public static void Next() { currentPage++; if (currentPage >= pages.Count) { currentPage = 0; } } private static void ShowChildren(OptionItem option, ref StringBuilder sb, Color color, int deep = 0) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) foreach (var item in option.Children.Select((OptionItem v, int i) => new { Value = v, Index = i + 1 })) { if (!(item.Value.Name == "Maximum")) { sb.Append(string.Concat(Enumerable.Repeat(Utils.ColorString(Color32.op_Implicit(color), "┃"), deep - 1))); sb.Append(Utils.ColorString(Color32.op_Implicit(color), (item.Index == option.Children.Count) ? "┗ " : "┣ ")); StringBuilder obj = sb; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, sb); handler.AppendFormatted(item.Value.GetName()); handler.AppendLiteral(": "); handler.AppendFormatted(item.Value.GetString()); handler.AppendLiteral("\n"); obj.Append(ref handler); if (item.Value.GetBool()) { ShowChildren(item.Value, ref sb, color, deep + 1); } } } } } public class HashRandomWrapper : IRandom { public int Next(int minValue, int maxValue) { return HashRandom.Next(minValue, maxValue); } public int Next(int maxValue) { return HashRandom.Next(maxValue); } public uint Next() { return HashRandom.Next(); } public int FastNext(int maxValue) { return HashRandom.FastNext(maxValue); } } public interface IRandom { static Dictionary randomTypes = new Dictionary { { 0, typeof(NetRandomWrapper) }, { 1, typeof(NetRandomWrapper) }, { 2, typeof(HashRandomWrapper) }, { 3, typeof(Xorshift) }, { 4, typeof(MersenneTwister) } }; static IRandom Instance { get; private set; } int Next(int maxValue); int Next(int minValue, int maxValue); static void SetInstance(IRandom instance) { if (instance != null) { Instance = instance; } } static void SetInstanceById(int id) { if (randomTypes.TryGetValue(id, out var value)) { if (Instance == null || Instance.GetType() != value) { Instance = (Activator.CreateInstance(value) as IRandom) ?? Instance; } } else { Logger.Warn($"Invalid ID: {id}", "IRandom.SetInstanceById", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Random\\IRandom.cs"); } } } public class MersenneTwister : IRandom { public const string REFERENCE_HOMEPAGE = "http://www.math.sci.hiroshima-u.ac.jp/m-mat/MT/mt.html"; public const string REFERENCE_SOURCE_CODE = "https://github.com/vpmedia/template-unity/blob/master/Framework/Assets/Frameworks/URandom/MersenneTwister.cs"; private const int N = 624; private const int M = 397; private const uint MatrixA = 2567483615u; private const uint UpperMask = 2147483648u; private const uint LowerMask = 2147483647u; private const uint TemperingMaskB = 2636928640u; private const uint TemperingMaskC = 4022730752u; private readonly uint[] _mt = new uint[624]; private short _mtItems; private readonly uint[] _mag01 = new uint[2] { 0u, 2567483615u }; public MersenneTwister() : this((int)DateTime.UtcNow.Ticks) { } public MersenneTwister(int seed) { Init((uint)seed); } private static uint ShiftU(uint y) { return y >> 11; } private static uint ShiftS(uint y) { return y << 7; } private static uint ShiftT(uint y) { return y << 15; } private static uint ShiftL(uint y) { return y >> 18; } private void Init(uint seed) { _mt[0] = seed & 0xFFFFFFFFu; for (_mtItems = 1; _mtItems < 624; _mtItems++) { _mt[_mtItems] = (uint)(1812433253 * (_mt[_mtItems - 1] ^ (_mt[_mtItems - 1] >> 30)) + _mtItems); _mt[_mtItems] &= uint.MaxValue; } } public uint Next() { uint num2; if (_mtItems >= 624) { short num; for (num = 0; num < 227; num++) { num2 = (_mt[num] & 0x80000000u) | (_mt[num + 1] & 0x7FFFFFFFu); _mt[num] = _mt[num + 397] ^ (num2 >> 1) ^ _mag01[num2 & 1]; } while (num < 623) { num2 = (_mt[num] & 0x80000000u) | (_mt[num + 1] & 0x7FFFFFFFu); _mt[num] = _mt[num + -227] ^ (num2 >> 1) ^ _mag01[num2 & 1]; num++; } num2 = (_mt[623] & 0x80000000u) | (_mt[0] & 0x7FFFFFFFu); _mt[623] = _mt[396] ^ (num2 >> 1) ^ _mag01[num2 & 1]; _mtItems = 0; } num2 = _mt[_mtItems++]; num2 ^= ShiftU(num2); num2 ^= ShiftS(num2) & 0x9D2C5680u; num2 ^= ShiftT(num2) & 0xEFC60000u; return num2 ^ ShiftL(num2); } public int Next(int minValue, int maxValue) { if (minValue < 0) { throw new ArgumentOutOfRangeException("minValue", "minValue must be bigger than 0."); } if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue", "maxValue must be bigger than 0."); } if (minValue > maxValue) { throw new ArgumentException("maxValue must be bigger than minValue."); } if (minValue == maxValue) { return minValue; } return (int)(minValue + Next() % (maxValue - minValue)); } public int Next(int maxValue) { return Next(0, maxValue); } } public class NetRandomWrapper : IRandom { public Random wrapping; public NetRandomWrapper(Random instance) { wrapping = instance; base..ctor(); } public NetRandomWrapper() : this(new Random()) { } public NetRandomWrapper(int seed) : this(new Random(seed)) { } public int Next(int minValue, int maxValue) { return wrapping.Next(minValue, maxValue); } public int Next(int maxValue) { return wrapping.Next(maxValue); } public int Next() { return wrapping.Next(); } } public class Xorshift : IRandom { public const string REFERENCE = "https://ja.wikipedia.org/wiki/Xorshift"; private uint num; public Xorshift(uint seed) { num = seed; base..ctor(); } public Xorshift() : this((uint)DateTime.UtcNow.Ticks) { } public uint Next() { num ^= num << 13; num ^= num >> 17; num ^= num << 5; return num; } public int Next(int minValue, int maxValue) { if (minValue < 0) { throw new ArgumentOutOfRangeException("minValue", "minValue must be bigger than 0."); } if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue", "maxValue must be bigger than 0."); } if (minValue > maxValue) { throw new ArgumentException("maxValue must be bigger than minValue."); } if (minValue == maxValue) { return minValue; } return (int)(minValue + Next() % (maxValue - minValue)); } public int Next(int maxValue) { return Next(0, maxValue); } } internal enum CustomRPC : byte { VersionCheck = 80, RequestRetryVersionCheck = 81, SyncCustomSettings = 100, SetDeathReason = 102, EndGame = 103, PlaySound = 104, SetCustomRole = 105, AntiBlackout = 106, SetRealKiller = 107, PlayCustomSound = 108, SetKillTimer = 109, SyncAllPlayerNames = 110, SyncNameNotify = 111, ShowPopUp = 112, KillFlash = 113, DumpLog = 114, SyncRoleSkill = 115, SetNameColorData = 116, GuessKill = 117, Judge = 118, Guess = 119, CouncillorJudge = 120, NemesisRevenge = 121, RetributionistRevenge = 122, SetFriendCode = 123, SyncLobbyTimer = 124, SyncPlayerSetting = 125, ShowChat = 126, SetBountyTarget = 127, SyncPuppet = 128, SyncKami = 129, SetKillOrSpell = 130, SetKillOrHex = 131, SetKillOrCurse = 132, SetCaptainTargetSpeed = 133, RevertCaptainTargetSpeed = 134, RevertCaptainAllTargetSpeed = 135, SetCaptainVotedTarget = 136, RevertCaptainVoteRemove = 137, SetDousedPlayer = 138, DoSpell = 139, DoHex = 140, DoCurse = 141, SniperSync = 142, SetLoversPlayers = 143, SetExecutionerTarget = 144, RemoveExecutionerTarget = 145, SendFireworkerState = 146, SetCurrentDousingTarget = 147, SetEvilTrackerTarget = 148, SetDrawPlayer = 149, SetCrewpostorTasksDone = 150, SetCurrentDrawTarget = 151, RpcPassBomb = 152, SyncRomanticTarget = 153, SyncVengefulRomanticTarget = 154, SetJailerTarget = 155, SetJailerExeLimit = 156, SetInspectorLimit = 157, KeeperRPC = 158, SetAlchemistTimer = 159, UndertakerLocationSync = 160, RiftMakerSyncData = 161, LightningSetGhostPlayer = 162, SetDarkHiderKillCount = 163, SetConsigliere = 164, SetGreedy = 165, BenefactorRPC = 166, SetSwapperVotes = 167, SetMarkedPlayer = 168, SetConcealerTimer = 169, SetMedicalerProtectList = 170, SyncPsychicRedList = 171, SetMorticianArrow = 172, SetAmnesaicArrows = 173, SetTracefinderArrow = 174, PresidentEnd = 175, PresidentReveal = 176, SetBKTimer = 177, SetCursedSoulCurseLimit = 178, SetInvestgatorLimit = 179, SyncInvestigator = 180, SetOverseerRevealedPlayer = 181, SetOverseerTimer = 182, SetCoronerArrow = 183, SetCoronerkKillerArrow = 184, SetVultureArrow = 185, SetRadarArrow = 186, SyncVultureBodyAmount = 187, SpyRedNameSync = 188, SpyRedNameRemove = 189, SetChameleonTimer = 190, SyncAdmiredList = 191, SyncAdmiredAbility = 192, SetImitateLimit = 193, SetStalkerrKillCount = 194, SyncFFAPlayer = 195, SyncFFANameNotify = 196 } public enum Sounds { KillSound, TaskComplete, TaskUpdateSound, ImpTransform, Test } [HarmonyPatch(typeof(PlayerControl), "HandleRpc")] internal class RPCHandlerPatch { public static bool TrustedRpc(byte id) { switch ((CustomRPC)id) { case CustomRPC.VersionCheck: case CustomRPC.RequestRetryVersionCheck: case CustomRPC.AntiBlackout: case CustomRPC.DumpLog: case CustomRPC.Judge: case CustomRPC.Guess: case CustomRPC.CouncillorJudge: case CustomRPC.NemesisRevenge: case CustomRPC.RetributionistRevenge: case CustomRPC.SetFriendCode: case CustomRPC.SetSwapperVotes: case CustomRPC.PresidentEnd: return true; default: return false; } } public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Invalid comparison between Unknown and I4 //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Invalid comparison between Unknown and I4 //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Invalid comparison between Unknown and I4 //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Invalid comparison between Unknown and I4 //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Invalid comparison between Unknown and I4 //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Invalid comparison between Unknown and I4 //IL_016d: Unknown result type (might be due to invalid IL or missing references) RpcCalls val = (RpcCalls)callId; MessageReader val2 = MessageReader.Get(reader); if (EAC.PlayerControlReceiveRpc(__instance, callId, reader)) { return false; } DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(5, 4); byte? value; if (__instance == null) { value = null; } else { NetworkedPlayerInfo data = __instance.Data; value = ((data != null) ? new byte?(data.PlayerId) : null); } defaultInterpolatedStringHandler.AppendFormatted(value); defaultInterpolatedStringHandler.AppendLiteral("("); object value2; if (!((InnerNetObject)(object)__instance).OwnedByHost()) { if (__instance == null) { value2 = null; } else { NetworkedPlayerInfo data2 = __instance.Data; value2 = ((data2 != null) ? data2.PlayerName : null); } } else { value2 = "Host"; } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral("):"); defaultInterpolatedStringHandler.AppendFormatted(callId); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(RPC.GetRpcName(callId)); defaultInterpolatedStringHandler.AppendLiteral(")"); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "ReceiveRPC", escapeCRLF: true, 157, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); if ((int)val <= 13) { if ((int)val != 6) { if ((int)val == 13) { string text = val2.ReadString(); Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + ":" + text.RemoveHtmlTags(), "ReceiveChat", escapeCRLF: true, 173, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); ChatCommands.OnReceiveChat(__instance, text, out var canceled); if (canceled) { return false; } } } else { val2.ReadUInt32(); string text2 = val2.ReadString(); if (val2.BytesRemaining > 0 && val2.ReadBoolean()) { return false; } Logger.Info("RPC Set Name For Player: " + __instance.GetNameWithRole() + " => " + text2, "SetName", escapeCRLF: true, 164, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } } else if ((int)val != 14) { if ((int)val != 33) { if ((int)val == 44) { RoleTypes val3 = (RoleTypes)val2.ReadUInt16(); bool flag = val2.ReadBoolean(); Logger.Info("RPC Set Role For Player: " + __instance.GetRealName() + " => " + ((object)(RoleTypes)(ref val3)).ToString() + " CanOverrideRole: " + flag, "SetRole", escapeCRLF: true, 169, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } } else { Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + ":Some message from quick chat", "ReceiveChat", escapeCRLF: true, 178, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); ChatCommands.OnReceiveChat(__instance, "Some message from quick chat", out var canceled2); if (canceled2) { return false; } } } else { PlayerControl playerById = Utils.GetPlayerById(val2.ReadByte()); Logger.Info(__instance.GetNameWithRole() + " => " + (playerById?.GetNameWithRole() ?? "null"), "StartMeeting", escapeCRLF: true, 184, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } if (!((InnerNetObject)(object)__instance).OwnedByHost() && ((Enum.IsDefined(typeof(CustomRPC), callId) && !TrustedRpc(callId)) || (!Enum.IsDefined(typeof(CustomRPC), callId) && !Enum.IsDefined(typeof(RpcCalls), callId)))) { defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(72, 3); object value3; if (__instance == null) { value3 = null; } else { NetworkedPlayerInfo data3 = __instance.Data; value3 = ((data3 != null) ? data3.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value3); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(callId); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(RPC.GetRpcName(callId)); defaultInterpolatedStringHandler.AppendLiteral(") has been canceled because it was sent by someone other than the host"); Logger.Warn(defaultInterpolatedStringHandler.ToStringAndClear(), "CustomRPC", escapeCRLF: true, 191, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), false); object obj; if (__instance == null) { obj = null; } else { NetworkedPlayerInfo data4 = __instance.Data; obj = ((data4 != null) ? data4.PlayerName : null); } Logger.Warn("Received an uncredited RPC from " + (string?)obj + " and kicked it out", "Kick", escapeCRLF: true, 195, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); string @string = Translator.GetString("Warning.InvalidRpc"); object arg; if (__instance == null) { arg = null; } else { NetworkedPlayerInfo data5 = __instance.Data; arg = ((data5 != null) ? data5.PlayerName : null); } Logger.SendInGame(string.Format(@string, arg)); } return false; } return true; } public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { //IL_0b02: Unknown result type (might be due to invalid IL or missing references) switch (callId) { case 106: { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler; if (Options.EndWhenPlayerBug.GetBool()) { defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(51, 3); PlayerControl obj3 = __instance; object value3; if (obj3 == null) { value3 = null; } else { NetworkedPlayerInfo data2 = obj3.Data; value3 = ((data2 != null) ? data2.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value3); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(__instance.PlayerId); defaultInterpolatedStringHandler.AppendLiteral("): Error: "); defaultInterpolatedStringHandler.AppendFormatted(reader.ReadString()); defaultInterpolatedStringHandler.AppendLiteral(" - end the game according to the setting"); Logger.Fatal(defaultInterpolatedStringHandler.ToStringAndClear(), "Anti-black", escapeCRLF: true, 213, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); ChatUpdatePatch.DoBlockChat = true; string @string = Translator.GetString("RpcAntiBlackOutNotifyInLobby"); PlayerControl obj4 = __instance; object arg; if (obj4 == null) { arg = null; } else { NetworkedPlayerInfo data3 = obj4.Data; arg = ((data3 != null) ? data3.PlayerName : null); } Main.OverrideWelcomeMsg = string.Format(@string, arg, Translator.GetString("EndWhenPlayerBug")); new LateTask(delegate { string string3 = Translator.GetString("RpcAntiBlackOutEndGame"); PlayerControl obj7 = __instance; object arg3; if (obj7 == null) { arg3 = null; } else { NetworkedPlayerInfo data6 = obj7.Data; arg3 = ((data6 != null) ? data6.PlayerName : null); } Logger.SendInGame(string.Format(string3, arg3)); }, 3f, "RPC Anti-Black Msg SendInGame Error During Loading"); new LateTask(delegate { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); GameManager.Instance.LogicFlow.CheckEndCriteria(); RPC.ForceEndGame(CustomWinner.Error); }, 5.5f, "RPC Anti-Black End Game As Critical Error"); break; } defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(57, 3); PlayerControl obj5 = __instance; object value4; if (obj5 == null) { value4 = null; } else { NetworkedPlayerInfo data4 = obj5.Data; value4 = ((data4 != null) ? data4.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value4); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(__instance.PlayerId); defaultInterpolatedStringHandler.AppendLiteral("): Error: "); defaultInterpolatedStringHandler.AppendFormatted(reader.ReadString()); defaultInterpolatedStringHandler.AppendLiteral(" - continue the game according to the settings"); Logger.Fatal(defaultInterpolatedStringHandler.ToStringAndClear(), "Anti-black", escapeCRLF: true, 230, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); new LateTask(delegate { string string2 = Translator.GetString("RpcAntiBlackOutIgnored"); PlayerControl obj6 = __instance; object arg2; if (obj6 == null) { arg2 = null; } else { NetworkedPlayerInfo data5 = obj6.Data; arg2 = ((data5 != null) ? data5.PlayerName : null); } Logger.SendInGame(string.Format(string2, arg2)); }, 3f, "RPC Anti-Black Msg SendInGame Out Ignored"); break; } case 80: try { Version ver = Version.Parse(reader.ReadString()); string tag_str = reader.ReadString(); string forkId = reader.ReadString(); bool flag = reader.ReadBoolean(); if (__instance.GetClientId() < 0) { break; } if (!Main.playerVersion.TryGetValue(__instance.GetClientId(), out var _)) { RPC.RpcVersionCheck(); } Main.playerVersion[__instance.GetClientId()] = new PlayerVersion(ver, tag_str, forkId); if (Main.VersionCheat.Value && __instance.GetClientId() == ((InnerNetClient)AmongUsClient.Instance).HostId) { RPC.RpcVersionCheck(); } if (__instance.GetClientId() == Main.HostClientId && flag) { Main.IsHostVersionCheating = true; } if (Main.VersionCheat.Value && ((InnerNetClient)AmongUsClient.Instance).AmHost) { Main.playerVersion[__instance.GetClientId()] = Main.playerVersion[((InnerNetClient)AmongUsClient.Instance).HostId]; } if (!((InnerNetClient)AmongUsClient.Instance).AmHost || IsVersionMatch(__instance.GetClientId()) || Main.VersionCheat.Value) { break; } new LateTask(delegate { PlayerControl obj8 = __instance; bool? obj9; if (obj8 == null) { obj9 = null; } else { NetworkedPlayerInfo data7 = obj8.Data; obj9 = ((data7 != null) ? new bool?(data7.Disconnected) : null); } if ((!obj9) ?? false) { string string4 = Translator.GetString("KickBecauseDiffrentVersionOrMod"); PlayerControl obj10 = __instance; object arg4; if (obj10 == null) { arg4 = null; } else { NetworkedPlayerInfo data8 = obj10.Data; arg4 = ((data8 != null) ? data8.PlayerName : null); } string text3 = string.Format(string4, arg4); Logger.Warn(text3, "Version Kick", escapeCRLF: true, 273, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); Logger.SendInGame(text3); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), false); } }, 5f, "Kick Because Diffrent Version Or Mod"); break; } catch { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(16, 2); PlayerControl obj = __instance; object value2; if (obj == null) { value2 = null; } else { NetworkedPlayerInfo data = obj.Data; value2 = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(__instance.PlayerId); defaultInterpolatedStringHandler.AppendLiteral("): バージョン情報が無効です"); Logger.Warn(defaultInterpolatedStringHandler.ToStringAndClear(), "RpcVersionCheck", escapeCRLF: true, 284, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); new LateTask(delegate { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)81, (SendOption)1, __instance.GetClientId()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); }, 1f, "Retry Version Check Task"); break; } case 81: RPC.RpcVersionCheck(); break; case 123: RPC.SetFriendCode(__instance, reader.ReadString()); break; case 100: { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { break; } List list = new List(); IReadOnlyList allOptions = OptionItem.AllOptions; List list2 = new List(allOptions.Count); foreach (OptionItem item in allOptions) { list2.Add(item); } List list3 = list2; int num3 = reader.ReadPackedInt32(); int num4 = reader.ReadPackedInt32(); int count = OptionItem.AllOptions.Count; for (int k = num3; k < count && k <= num4; k++) { list.Add(list3[k]); } int count2 = list.Count; Logger.Msg($"StartAmount/LastAmount: {num3}/{num4} :--: ListOptionsCount/AllOptions: {count2}/{count}", "CustomRPC.SyncCustomSettings", escapeCRLF: true, 320, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); OptionItem[] array = list.ToArray(); foreach (OptionItem optionItem in array) { optionItem.SetValue(reader.ReadPackedInt32()); if (num3 == 0 && optionItem.Name == "Preset" && optionItem.CurrentValue != 4) { optionItem.SetValue(4); } } break; } case 102: RPC.GetDeathReason(reader); break; case 103: RPC.EndGame(reader); break; case 186: Radar.ReceiveRPC(reader); break; case 104: { byte playerID = reader.ReadByte(); Sounds sound = (Sounds)reader.ReadByte(); RPC.PlaySound(playerID, sound); break; } case 112: { string text = reader.ReadString(); string text2 = reader.ReadString(); if (text2 != "") { text = text2 + "\n" + text; } DestroyableSingleton.Instance.ShowPopUp(text); break; } case 105: { byte targetId2 = reader.ReadByte(); CustomRoles role = (CustomRoles)reader.ReadPackedInt32(); RPC.SetCustomRole(targetId2, role); break; } case 124: GameStartManagerPatch.timer = reader.ReadPackedInt32(); break; case 115: RPC.SyncRoleSkillReader(reader); break; case 127: BountyHunter.ReceiveRPC(reader); break; case 128: Puppeteer.ReceiveRPC(reader); break; case 130: Witch.ReceiveRPC(reader, doSpell: false); break; case 131: HexMaster.ReceiveRPC(reader, doHex: false); break; case 126: { uint num6 = reader.ReadPackedUInt32(); bool visible = reader.ReadBoolean(); if (((InnerNetClient)AmongUsClient.Instance).ClientId == num6) { DestroyableSingleton.Instance.Chat.SetVisible(visible); } break; } case 133: Captain.ReceiveRPCSetSpeed(reader); break; case 134: Captain.ReceiveRPCRevertSpeed(reader); break; case 135: Captain.ReceiveRPCRevertAllSpeed(); break; case 136: Captain.ReceiveRPCVoteAdd(reader); break; case 137: Captain.ReceiveRPCVoteRemove(reader); break; case 149: Revolutionist.ReceiveDrawPlayerRPC(reader); break; case 181: Overseer.ReceiveSetRevealedPlayerRPC(reader); break; case 182: Overseer.ReceiveTimerRPC(reader); break; case 116: NameColorManager.ReceiveRPC(reader); break; case 139: Witch.ReceiveRPC(reader, doSpell: true); break; case 140: HexMaster.ReceiveRPC(reader, doHex: true); break; case 142: Sniper.ReceiveRPC(reader); break; case 160: Undertaker.ReceiveRPC(reader); break; case 161: RiftMaker.ReceiveRPC(reader); break; case 143: { Main.LoversPlayers.Clear(); int num5 = reader.ReadInt32(); for (int m = 0; m < num5; m++) { Main.LoversPlayers.Add(Utils.GetPlayerById(reader.ReadByte())); } break; } case 144: Executioner.ReceiveRPC(reader, SetTarget: true); break; case 145: Executioner.ReceiveRPC(reader, SetTarget: false); break; case 146: Fireworker.ReceiveRPC(reader); break; case 147: Arsonist.ReceiveCurrentDousingTargetRPC(reader); break; case 138: Arsonist.ReceiveSetDousedPlayerRPC(reader); break; case 151: Revolutionist.ReceiveSetCurrentDrawTarget(reader); break; case 148: EvilTracker.ReceiveRPC(reader); break; case 107: { byte targetId = reader.ReadByte(); byte killerId = reader.ReadByte(); RPC.SetRealKiller(targetId, killerId); break; } case 156: Jailer.ReceiveRPC(reader, setTarget: false); break; case 155: Jailer.ReceiveRPC(reader); break; case 150: Crewpostor.ReceiveRPC(reader); break; case 191: Admirer.ReceiveRPC(reader, isList: true); break; case 192: Admirer.ReceiveRPC(reader, isList: false); break; case 108: CustomSoundsManager.ReceiveRPC(reader); break; case 162: Lightning.ReceiveRPC(reader); break; case 194: Stalker.ReceiveRPC(reader); break; case 165: Greedy.ReceiveRPC(reader); break; case 166: Benefactor.ReceiveRPC(reader); break; case 117: GuessManager.RpcClientGuess(Utils.GetPlayerById(reader.ReadByte())); break; case 168: Ninja.ReceiveRPC(reader); break; case 170: Medic.ReceiveRPCForProtectList(reader); break; case 171: Psychic.ReceiveRPC(reader); break; case 125: { byte key = reader.ReadByte(); CustomRoles mainRole = (CustomRoles)reader.ReadPackedInt32(); if (Main.PlayerStates.ContainsKey(key)) { Main.PlayerStates[key].MainRole = mainRole; } break; } case 109: { float killTimer = reader.ReadSingle(); PlayerControl.LocalPlayer.SetKillTimer(killTimer); break; } case 195: FFAManager.ReceiveRPCSyncFFAPlayer(reader); break; case 110: { Main.AllPlayerNames.Clear(); Main.AllClientRealNames.Clear(); int num = reader.ReadPackedInt32(); for (int i = 0; i < num; i++) { Main.AllPlayerNames.TryAdd(reader.ReadByte(), reader.ReadString()); } int num2 = reader.ReadPackedInt32(); for (int j = 0; j < num2; j++) { Main.AllClientRealNames.TryAdd(reader.ReadInt32(), reader.ReadString()); } break; } case 196: FFAManager.ReceiveRPCSyncNameNotify(reader); break; case 172: Mortician.ReceiveRPC(reader); break; case 173: Amnesiac.ReceiveRPC(reader); break; case 174: Tracefinder.ReceiveRPC(reader); break; case 111: NameNotifyManager.ReceiveRPC(reader); break; case 118: Judge.ReceiveRPC_Custom(reader, __instance); break; case 175: President.ReceiveRPC(reader, __instance); break; case 176: President.ReceiveRPC(reader, __instance, isEnd: false); break; case 120: Councillor.ReceiveRPC_Custom(reader, __instance); break; case 119: GuessManager.ReceiveRPC(reader, __instance); break; case 121: Nemesis.ReceiveRPC_Custom(reader, __instance); break; case 122: Retributionist.ReceiveRPC_Custom(reader, __instance); break; case 190: Chameleon.ReceiveRPC_Custom(reader); break; case 159: Alchemist.ReceiveRPC(reader); break; case 178: CursedSoul.ReceiveRPC(reader); break; case 164: Consigliere.ReceiveRPC(reader); break; case 179: Investigator.ReceiveRPC(reader); break; case 113: Utils.FlashColor(new Color(1f, 0f, 0f, 0.3f)); if (Constants.ShouldPlaySfx()) { RPC.PlaySound(PlayerControl.LocalPlayer.PlayerId, Sounds.KillSound); } break; case 114: { PlayerControl playerById = Utils.GetPlayerById(reader.ReadByte()); if ((Object)(object)playerById != (Object)null && !playerById.FriendCode.GetDevUser().DeBug) { Logger.Info("Player " + playerById.GetNameWithRole() + " used /dump", "RPC_DumpLogger", escapeCRLF: true, 595, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } break; } case 183: Coroner.ReceiveRPC(reader); break; case 184: Coroner.ReceiveRPCKiller(reader); break; case 185: Vulture.ReceiveRPC(reader); break; case 187: Vulture.ReceiveBodyRPC(reader); break; case 188: Spy.ReceiveRPC(reader); break; case 189: Spy.ReceiveRPC(reader, isRemove: true); break; case 157: Inspector.ReceiveRPC(reader); break; case 158: Keeper.ReceiveRPC(reader); break; case 167: Swapper.ReceiveSwapRPC(reader, __instance); break; } } private static bool IsVersionMatch(int ClientId) { if (Main.VersionCheat.Value) { return true; } Version version = Main.playerVersion[ClientId].version; string tag = Main.playerVersion[ClientId].tag; string forkId = Main.playerVersion[ClientId].forkId; if (version != Main.version || tag != "f6840257(main)" || forkId != Main.ForkId) { return false; } return true; } } [HarmonyPatch(typeof(PlayerPhysics), "HandleRpc")] internal class PlayerPhysicsRPCHandlerPatch { private static bool HasVent(int ventId) { return ((IEnumerable)ShipStatus.Instance.AllVents).Any((Vent v) => v.Id == ventId); } private static bool HasLadder(int ladderId) { return ((IEnumerable)ShipStatus.Instance.Ladders).Any((Ladder l) => l.Id == ladderId); } public static bool Prefix(PlayerPhysics __instance, byte callId, MessageReader reader) { if (EAC.PlayerPhysicsRpcCheck(__instance, callId, reader)) { return false; } PlayerControl myPlayer = __instance.myPlayer; if (!Object.op_Implicit((Object)(object)myPlayer)) { Logger.Warn("Received Physics RPC without a player", "PlayerPhysics_ReceiveRPC", escapeCRLF: true, 664, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); return false; } Logger.Info($"{myPlayer.PlayerId}({(((InnerNetObject)(object)__instance).OwnedByHost() ? "Host" : myPlayer.Data.PlayerName)}):{callId}({RPC.GetRpcName(callId)})", "PlayerPhysics_ReceiveRPC", escapeCRLF: true, 667, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); return true; } } internal static class RPC { public static void SyncCustomSettingsRPC(int targetId = -1) { if (targetId != -1) { ClientData clientById = Utils.GetClientById(targetId); if (clientById == null || (Object)(object)clientById.Character == (Object)null || !Main.playerVersion.ContainsKey(clientById.Id)) { return; } } if (((InnerNetClient)AmongUsClient.Instance).AmHost && PlayerControl.AllPlayerControls.Count > 1 && (((InnerNetClient)AmongUsClient.Instance).AmHost || !((Object)(object)PlayerControl.LocalPlayer == (Object)null))) { int count = OptionItem.AllOptions.Count; int num = count / 10; for (int i = 0; i <= 10; i++) { SyncOptionsBetween(i * num, (i + 1) * num, count, targetId); } } } private static void SyncOptionsBetween(int startAmount, int lastAmount, int amountAllOptions, int targetId = -1) { if (targetId != -1) { ClientData clientById = Utils.GetClientById(targetId); if (clientById == null || (Object)(object)clientById.Character == (Object)null || !Main.playerVersion.ContainsKey(clientById.Id)) { return; } } if (!((InnerNetClient)AmongUsClient.Instance).AmHost || PlayerControl.AllPlayerControls.Count <= 1 || (!((InnerNetClient)AmongUsClient.Instance).AmHost && (Object)(object)PlayerControl.LocalPlayer == (Object)null)) { return; } if (amountAllOptions != OptionItem.AllOptions.Count) { amountAllOptions = OptionItem.AllOptions.Count; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)100, (SendOption)1, targetId); val.WritePacked(startAmount); val.WritePacked(lastAmount); List list = new List(); IReadOnlyList allOptions = OptionItem.AllOptions; List list2 = new List(allOptions.Count); foreach (OptionItem item in allOptions) { list2.Add(item); } List list3 = list2; for (int i = startAmount; i < amountAllOptions && i <= lastAmount; i++) { list.Add(list3[i]); } _ = list.Count; OptionItem[] array = list.ToArray(); foreach (OptionItem optionItem in array) { val.WritePacked(optionItem.GetValue()); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void PlaySoundRPC(byte PlayerID, Sounds sound) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { PlaySound(PlayerID, sound); } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)104, (SendOption)1, -1); val.Write(PlayerID); val.Write((byte)sound); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void SyncAllPlayerNames() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)110, (SendOption)1, -1); val.WritePacked(Main.AllPlayerNames.Count); foreach (KeyValuePair allPlayerName in Main.AllPlayerNames) { val.Write(allPlayerName.Key); val.Write(allPlayerName.Value); } val.WritePacked(Main.AllClientRealNames.Count); foreach (KeyValuePair allClientRealName in Main.AllClientRealNames) { val.Write(allClientRealName.Key); val.Write(allClientRealName.Value); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ShowPopUp(this PlayerControl pc, string message, string title = "") { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)112, (SendOption)1, pc.GetClientId()); val.Write(message); val.Write(title); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ExileAsync(PlayerControl player) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)player).NetId, (byte)4, (SendOption)1, -1); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); player.Exiled(); } public static void RpcSetFriendCode(string fc) { MessageWriter obj = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)123, (SendOption)0); obj.Write(fc); obj.EndMessage(); SetFriendCode(PlayerControl.LocalPlayer, fc); } public static void SetFriendCode(PlayerControl target, string fc) { if (!GameStates.IsVanillaServer && (target.GetClient() == null || !(target.GetClient().ProductUserId != string.Empty))) { target.FriendCode = fc; target.Data.FriendCode = fc; target.GetClient().FriendCode = fc; target.Data.MarkDirty(); } } public static async void RpcVersionCheck() { try { while ((Object)(object)PlayerControl.LocalPlayer == (Object)null || ((InnerNetClient)AmongUsClient.Instance).HostId < 0 || PlayerControl.LocalPlayer.GetClientId() < 0) { await Task.Delay(500); } int hostId = ((InnerNetClient)AmongUsClient.Instance).HostId; if (Main.playerVersion.ContainsKey(hostId) || !Main.VersionCheat.Value) { bool value = Main.VersionCheat.Value; MessageWriter obj = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)80, (SendOption)1); obj.Write(value ? Main.playerVersion[hostId].version.ToString() : "2024.0813.203.9999"); obj.Write(value ? Main.playerVersion[hostId].tag : "f6840257(main)"); obj.Write(value ? Main.playerVersion[hostId].forkId : Main.ForkId); obj.Write(value); obj.EndMessage(); } Main.playerVersion[PlayerControl.LocalPlayer.GetClientId()] = new PlayerVersion("2024.0813.203.9999", "f6840257(main)", Main.ForkId); } catch { Logger.Error("Error while trying to send RPCVersionCheck, retry later", "RpcVersionCheck", escapeCRLF: true, 826, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); new LateTask(delegate { RpcVersionCheck(); }, 1f, "Retry RPCVersionCheck"); } } public static async void RpcRequestRetryVersionCheck() { while ((Object)(object)PlayerControl.LocalPlayer == (Object)null || ((InnerNetClient)AmongUsClient.Instance).GetHost() == null) { await Task.Delay(500); } int hostId = ((InnerNetClient)AmongUsClient.Instance).HostId; MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)81, (SendOption)1, hostId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void SendDeathReason(byte playerId, PlayerState.DeathReason deathReason) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)102, (SendOption)1, -1); val.Write(playerId); val.Write((int)deathReason); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void GetDeathReason(MessageReader reader) { byte key = reader.ReadByte(); int deathReason = reader.ReadInt32(); Main.PlayerStates[key].deathReason = (PlayerState.DeathReason)deathReason; Main.PlayerStates[key].IsDead = true; } public static void ForceEndGame(CustomWinner win) { if ((Object)(object)ShipStatus.Instance == (Object)null) { return; } try { CustomWinnerHolder.ResetAndSetWinner(win); } catch { } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } ((Behaviour)ShipStatus.Instance).enabled = false; try { GameManager.Instance.LogicFlow.CheckEndCriteria(); } catch { } try { GameManager.Instance.RpcEndGame((GameOverReason)5, false); } catch { } } public static void EndGame(MessageReader reader) { try { CustomWinnerHolder.ReadFrom(reader); } catch (Exception value) { Logger.Error($"正常にEndGameを行えませんでした。\n{value}", "EndGame", escapeCRLF: false, 873, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } } public static void PlaySound(byte playerID, Sounds sound) { if (PlayerControl.LocalPlayer.PlayerId == playerID) { switch (sound) { case Sounds.KillSound: SoundManager.Instance.PlaySound(PlayerControl.LocalPlayer.KillSfx, false, 1f, (AudioMixerGroup)null); break; case Sounds.TaskComplete: SoundManager.Instance.PlaySound(DestroyableSingleton.Instance.TaskCompleteSound, false, 1f, (AudioMixerGroup)null); break; case Sounds.TaskUpdateSound: SoundManager.Instance.PlaySound(DestroyableSingleton.Instance.TaskUpdateSound, false, 1f, (AudioMixerGroup)null); break; case Sounds.ImpTransform: SoundManager.Instance.PlaySound(DestroyableSingleton.Instance.HnSOtherImpostorTransformSfx, false, 0.8f, (AudioMixerGroup)null); break; } } } public static void SetCustomRole(byte targetId, CustomRoles role) { if (role < CustomRoles.NotAssigned) { Main.PlayerStates[targetId].SetMainRole(role); targetId.GetRoleClassById()?.OnAdd(targetId); } else if (role >= CustomRoles.NotAssigned) { Main.PlayerStates[targetId].SetSubRole(role); } switch (role) { case CustomRoles.LastImpostor: LastImpostor.Add(targetId); break; case CustomRoles.Aware: Aware.Add(targetId); break; case CustomRoles.Radar: Radar.Add(targetId); break; case CustomRoles.Glow: Glow.Add(targetId); break; case CustomRoles.Workhorse: Workhorse.Add(targetId); break; case CustomRoles.Diseased: Diseased.Add(); break; case CustomRoles.Antidote: Antidote.Add(); break; case CustomRoles.Burst: Burst.Add(); break; case CustomRoles.Fool: Fool.Add(); break; case CustomRoles.Ghoul: Ghoul.Add(); break; case CustomRoles.Rainbow: Rainbow.Add(); break; case CustomRoles.Statue: Statue.Add(targetId); break; } if (!((InnerNetClient)AmongUsClient.Instance).IsGameOver) { DestroyableSingleton.Instance.SetHudActive(true); } if (PlayerControl.LocalPlayer.PlayerId == targetId) { RemoveDisableDevicesPatch.UpdateDisableDevices(); } } public static void SyncRoleSkillReader(MessageReader reader) { try { PlayerControl val = MessageExtensions.ReadNetObject(reader); val.GetRoleClass(); val.GetRoleClass().ReceiveRPC(reader, val); } catch (Exception value) { Logger.Error($" Error RPC:{value}", "SyncRoleSkillReader", escapeCRLF: true, 971, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } } public static void SyncLoversPlayers() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)143, (SendOption)1, -1); val.Write(Main.LoversPlayers.Count); foreach (PlayerControl loversPlayer in Main.LoversPlayers) { val.Write(loversPlayer.PlayerId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void SendRpcLogger(uint targetNetId, byte callId, int targetClientId = -1) { if (!DebugModeManager.AmDebugger) { return; } string rpcName = GetRpcName(callId); string value = targetNetId.ToString(); string value2 = targetClientId.ToString(); try { value2 = ((targetClientId < 0) ? "All" : ((InnerNetClient)AmongUsClient.Instance).GetClient(targetClientId).PlayerName); PlayerControl? obj = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl c) => ((InnerNetObject)c).NetId == targetNetId)); object obj2; if (obj == null) { obj2 = null; } else { NetworkedPlayerInfo data = obj.Data; obj2 = ((data != null) ? data.PlayerName : null); } value = (string)obj2; } catch { } Logger.Info($"FromNetID:{targetNetId}({value}) TargetClientID:{targetClientId}({value2}) CallID:{callId}({rpcName})", "SendRPC", escapeCRLF: true, 997, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RPC.cs"); } public static string GetRpcName(byte callId) { string result; if ((result = Enum.GetName(typeof(RpcCalls), callId)) == null && (result = Enum.GetName(typeof(CustomRPC), callId)) == null) { result = callId.ToString(); } return result; } public static void SetRealKiller(byte targetId, byte killerId) { PlayerState playerState = Main.PlayerStates[targetId]; playerState.RealKiller.Item1 = DateTime.Now; playerState.RealKiller.Item2 = killerId; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)107, (SendOption)1, -1); val.Write(targetId); val.Write(killerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } } [HarmonyPatch(typeof(InnerNetClient), "StartRpc")] internal class StartRpcPatch { public static void Prefix([HarmonyArgument(0)] uint targetNetId, [HarmonyArgument(1)] byte callId) { RPC.SendRpcLogger(targetNetId, callId); } } [HarmonyPatch(typeof(InnerNetClient), "StartRpcImmediately")] internal class StartRpcImmediatelyPatch { public static void Prefix([HarmonyArgument(0)] uint targetNetId, [HarmonyArgument(1)] byte callId, [HarmonyArgument(3)] int targetClientId = -1) { RPC.SendRpcLogger(targetNetId, callId, targetClientId); } } public static class SpamManager { public static bool CheckSpam(PlayerControl player, string text) { if (player.PlayerId == PlayerControl.LocalPlayer.PlayerId) { return false; } string realName = player.GetRealName(); bool flag = false; string text2 = ""; if (Options.AutoKickStart.GetBool() && ContainsStart(text) && GameStates.IsLobby) { text2 = string.Format(Translator.GetString("Message.KickWhoSayStart"), realName); if (Options.AutoKickStart.GetBool()) { if (!Main.SayStartTimes.ContainsKey(player.GetClientId())) { Main.SayStartTimes.Add(player.GetClientId(), 0); } Main.SayStartTimes[player.GetClientId()]++; text2 = string.Format(Translator.GetString("Message.WarnWhoSayStart"), realName, Main.SayStartTimes[player.GetClientId()]); if (Main.SayStartTimes[player.GetClientId()] > Options.AutoKickStartTimes.GetInt()) { text2 = string.Format(Translator.GetString("Message.KickStartAfterWarn"), realName, Main.SayStartTimes[player.GetClientId()]); flag = true; } } if (text2 != "") { Utils.SendMessage(text2); } if (flag) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.GetClientId(), Options.AutoKickStartAsBan.GetBool()); } return true; } if (text2 != "") { if (flag || !GameStates.IsInGame) { Utils.SendMessage(text2); } else { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.IsAlive() == player.IsAlive()).ToArray(); foreach (PlayerControl val in array) { Utils.SendMessage(text2, val.PlayerId); } } } if (flag) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.GetClientId(), Options.AutoKickStartAsBan.GetBool()); } return true; } private static bool ContainsStart(string text) { text = text.Trim().ToLower(); int num = 0; for (int i = 0; i < text.Length; i++) { string text2 = text; int num2 = i; if (text2.Substring(num2, text2.Length - num2).Equals("k")) { num++; } text2 = text; num2 = i; if (text2.Substring(num2, text2.Length - num2).Equals("开")) { num++; } } if (num >= 3) { return true; } switch (text) { case "Start": return true; case "start": return true; case "/Start": return true; case "/Start/": return true; case "Start/": return true; case "/start": return true; case "/start/": return true; case "start/": return true; case "plsstart": return true; case "pls start": return true; case "please start": return true; case "pleasestart": return true; case "Plsstart": return true; case "Pls start": return true; case "Please start": return true; case "Pleasestart": return true; case "plsStart": return true; case "pls Start": return true; case "please Start": return true; case "pleaseStart": return true; case "PlsStart": return true; case "Pls Start": return true; case "Please Start": return true; case "PleaseStart": return true; case "sTart": return true; case "stArt": return true; case "staRt": return true; case "starT": return true; case "s t a r t": return true; case "S t a r t": return true; case "started": return true; case "Started": return true; case "s t a r t e d": return true; case "S t a r t e d": return true; case "Começa": return true; case "começa": return true; case "/Começar": return true; case "/Começar/": return true; case "Começar/": return true; case "/começar": return true; case "/começar/": return true; case "começar/": return true; case "começa por favor": return true; case "COMEÇA POR FAVOR": return true; case "cmc pfv": return true; case "CMC PFV": return true; case "cmc logo": return true; case "CMC LOGO": return true; case "começa logo": return true; case "COMEÇA LOGO": return true; case "CMC MANO": return true; case "CMC MN": return true; case "cmc mano": return true; case "cmc mn": return true; case "Iniciar": return true; case "Iniciar Por Favor": return true; case "iniciar por favor": return true; case "iNiciar": return true; case "inIciar": return true; case "iniCiar": return true; case "iniciAr": return true; case "C O M E Ç A": return true; case "I N I C I A R": return true; case "Го": return true; case "гО": return true; case "го": return true; case "Гоу": return true; case "гоу": return true; case "Старт": return true; case "старт": return true; case "/Старт": return true; case "/Старт/": return true; case "Старт/": return true; case "/старт": return true; case "/старт/": return true; case "старт/": return true; case "пжстарт": return true; case "пж старт": return true; case "пжСтарт": return true; case "пж Старт": return true; case "Пжстарт": return true; case "Пж старт": return true; case "ПжСтарт": return true; case "Пж Старт": return true; case "сТарт": return true; case "стАрт": return true; case "стаРт": return true; case "старТ": return true; case "с т а р т": return true; case "С т а р т": return true; case "начни": return true; case "Начни": return true; case "начинай": return true; case "начинай уже": return true; case "Начинай": return true; case "Начинай уже": return true; case "Начинай Уже": return true; case "н а ч и н а й": return true; case "Н а ч и н а й": return true; case "пж го": return true; case "пжго": return true; case "Пж Го": return true; case "Пж го": return true; case "пж Го": return true; case "ПжГо": return true; case "Пжго": return true; case "пжГо": return true; case "ГоПж": return true; case "гоПж": return true; case "Гопж": return true; case "开": return true; case "快开": return true; case "开始": return true; case "开啊": return true; case "开阿": return true; case "kai": return true; case "kaishi": return true; default: if (text.Contains('了')) { return false; } if (text.Contains('没')) { return false; } if (text.Contains('吗')) { return false; } if (text.Contains('哈')) { return false; } if (text.Contains('还')) { return false; } if (text.Contains('现')) { return false; } if (text.Contains('不')) { return false; } if (text.Contains('可')) { return false; } if (text.Contains('刚')) { return false; } if (text.Contains('的')) { return false; } if (text.Contains('打')) { return false; } if (text.Contains('门')) { return false; } if (text.Contains('关')) { return false; } if (text.Contains('怎')) { return false; } if (text.Contains('要')) { return false; } if (text.Contains('摆')) { return false; } if (text.Contains('啦')) { return false; } if (text.Contains('咯')) { return false; } if (text.Contains('嘞')) { return false; } if (text.Contains('勒')) { return false; } if (text.Contains('心')) { return false; } if (text.Contains('呢')) { return false; } if (text.Contains('门')) { return false; } if (text.Contains('总')) { return false; } if (text.Contains('哥')) { return false; } if (text.Contains('姐')) { return false; } if (text.Contains('《')) { return false; } if (text.Contains('?')) { return false; } if (text.Contains('?')) { return false; } if (!text.Contains('开')) { return text.Contains("kai"); } return true; } } } internal static class TargetArrow { private class ArrowInfo { public byte From; public byte To; public ArrowInfo(byte from, byte to) { From = from; To = to; base..ctor(); } public bool Equals(ArrowInfo obj) { if (From == obj.From) { return To == obj.To; } return false; } public override string ToString() { return $"(From:{From} To:{To})"; } } private static readonly Dictionary TargetArrows = new Dictionary(); private static readonly string[] Arrows = new string[9] { "↑", "↗", "→", "↘", "↓", "↙", "←", "↖", "・" }; public static void Init() { TargetArrows.Clear(); } public static void Add(byte seer, byte target) { ArrowInfo arrowInfo = new ArrowInfo(seer, target); if (!TargetArrows.Any((KeyValuePair a) => a.Key.Equals(arrowInfo))) { TargetArrows[arrowInfo] = "・"; } } public static void Remove(byte seer, byte target) { ArrowInfo arrowInfo = new ArrowInfo(seer, target); ArrowInfo[] array = new List(TargetArrows.Keys.Where((ArrowInfo k) => k.Equals(arrowInfo))).ToArray(); foreach (ArrowInfo key in array) { TargetArrows.Remove(key); } } public static void RemoveAllTarget(byte seer) { ArrowInfo[] array = new List(TargetArrows.Keys.Where((ArrowInfo k) => k.From == seer)).ToArray(); foreach (ArrowInfo key in array) { TargetArrows.Remove(key); } } public static string GetArrows(PlayerControl seer, params byte[] targets) { string text = ""; ArrowInfo[] array = TargetArrows.Keys.Where((ArrowInfo ai) => ai.From == seer.PlayerId && targets.Contains(ai.To)).ToArray(); foreach (ArrowInfo key in array) { text += TargetArrows[key]; } return text; } public static bool HasTargetArrows(PlayerControl seer) { return TargetArrows.Keys.Any((ArrowInfo a) => a.From == seer.PlayerId); } public static void OnFixedUpdate(PlayerControl seer) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsInTask) { return; } _ = seer.PlayerId; bool flag = !seer.IsAlive(); List list = new List(TargetArrows.Keys.Where((ArrowInfo a) => a.From == seer.PlayerId)); if (!list.Any()) { return; } bool flag2 = false; ArrowInfo[] array = list.ToArray(); foreach (ArrowInfo arrowInfo in array) { PlayerControl playerById = Utils.GetPlayerById(arrowInfo.To); if (flag || (!playerById.IsAlive() && !seer.Is(CustomRoles.Spiritualist))) { TargetArrows.Remove(arrowInfo); flag2 = true; continue; } Vector3 val = ((Component)playerById).transform.position - ((Component)seer).transform.position; int num = ((!(((Vector3)(ref val)).magnitude < 2f)) ? ((int)(((double)(Vector3.SignedAngle(Vector3.down, val, Vector3.back) + 180f) + 22.5) / 45.0) % 8) : 8); string text = Arrows[num]; if (TargetArrows[arrowInfo] != text) { TargetArrows[arrowInfo] = text; flag2 = true; } } if (flag2 && !((InnerNetObject)seer).AmOwner) { Utils.NotifyRoles(seer, null, isForMeeting: false, NoCache: false, ForceLoop: false); } } } public static class TemplateManager { private static readonly string TEMPLATE_FILE_PATH = "./TOHE-DATA/template.txt"; private static readonly Dictionary> _replaceDictionaryNormalOptions = new Dictionary> { ["RoomCode"] = () => GameCode.IntToGameName(((InnerNetClient)AmongUsClient.Instance).GameId), ["HostName"] = () => DataManager.Player.Customization.Name, ["AmongUsVersion"] = () => Application.version, ["InternalVersion"] = () => "2024.0813.203.9999", ["ModVersion"] = () => "2.0.3", ["Map"] = () => ((Il2CppArrayBase)(object)Constants.MapNames)[(int)Main.NormalOptions.MapId], ["NumEmergencyMeetings"] = () => Main.NormalOptions.NumEmergencyMeetings.ToString(), ["EmergencyCooldown"] = () => Main.NormalOptions.EmergencyCooldown.ToString(), ["DiscussionTime"] = () => Main.NormalOptions.DiscussionTime.ToString(), ["VotingTime"] = () => Main.NormalOptions.VotingTime.ToString(), ["PlayerSpeedMod"] = () => Main.NormalOptions.PlayerSpeedMod.ToString(), ["CrewLightMod"] = () => Main.NormalOptions.CrewLightMod.ToString(), ["ImpostorLightMod"] = () => Main.NormalOptions.ImpostorLightMod.ToString(), ["KillCooldown"] = () => Main.NormalOptions.KillCooldown.ToString(), ["NumCommonTasks"] = () => Main.NormalOptions.NumCommonTasks.ToString(), ["NumLongTasks"] = () => Main.NormalOptions.NumLongTasks.ToString(), ["NumShortTasks"] = () => Main.NormalOptions.NumShortTasks.ToString(), ["Date"] = () => DateTime.Now.ToShortDateString(), ["Time"] = () => DateTime.Now.ToShortTimeString(), ["PlayerName"] = () => "", ["LobbyTimer"] = delegate { if (GameStates.IsLobby) { int num2 = (int)GameStartManagerPatch.timer; int value3 = num2 / 60; int value4 = num2 % 60; return $"{value3:D2}:{value4:D2}"; } return string.Empty; } }; private static readonly Dictionary> _replaceDictionaryHideNSeekOptions = new Dictionary> { ["RoomCode"] = () => GameCode.IntToGameNameV2(((InnerNetClient)AmongUsClient.Instance).GameId), ["HostName"] = () => DataManager.Player.Customization.Name, ["AmongUsVersion"] = () => Application.version, ["InternalVersion"] = () => "2024.0813.203.9999", ["ModVersion"] = () => "2.0.3", ["Map"] = () => ((Il2CppArrayBase)(object)Constants.MapNames)[(int)Main.HideNSeekOptions.MapId], ["PlayerSpeedMod"] = () => Main.HideNSeekOptions.PlayerSpeedMod.ToString(), ["Date"] = () => DateTime.Now.ToShortDateString(), ["Time"] = () => DateTime.Now.ToShortTimeString(), ["PlayerName"] = () => "", ["LobbyTimer"] = delegate { if (GameStates.IsLobby) { int num = (int)GameStartManagerPatch.timer; int value = num / 60; int value2 = num % 60; return $"{value:D2}:{value2:D2}"; } return string.Empty; } }; public static void Init() { CreateIfNotExists(); } public static void CreateIfNotExists() { try { string name = CultureInfo.CurrentCulture.Name; string text3; if (name.Length >= 2) { string text = name; string text2; if (!text.StartsWith("ru")) { switch (text) { case "zh-Hans": case "zn-SG": case "zh-CN": case "zh": text2 = "SChinese"; break; case "zh-Hant": case "zh-MO": case "zh-TW": case "zh-HK": text2 = "TChinese"; break; case "pt-BR": text2 = "Brazilian"; break; case "es-419": text2 = "Latam"; break; default: text2 = ((!text.StartsWith("es")) ? (text.StartsWith("fr") ? "French" : ((!(text == "ja") && !(text == "ja-JP")) ? ((!text.StartsWith("nl")) ? ((!text.StartsWith("it")) ? "English" : "Italian") : "Dutch") : "Japanese")) : "Spanish"); break; } } else { text2 = "Russian"; } text3 = text2; } else { text3 = "English"; } if (!Directory.Exists("TOHE-DATA")) { Directory.CreateDirectory("TOHE-DATA"); } string resourcesTxt = GetResourcesTxt("TOHE.Resources.Config.template." + text3 + ".txt"); if (!File.Exists("./TOHE-DATA/Default_Teamplate.txt")) { Logger.Warn("Creating Default_Template.txt", "TemplateManager", escapeCRLF: true, 113, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\TemplateManager.cs"); using (File.Create("./TOHE-DATA/Default_Teamplate.txt")) { } } File.WriteAllText("./TOHE-DATA/Default_Teamplate.txt", resourcesTxt); if (!File.Exists(TEMPLATE_FILE_PATH)) { if (File.Exists("./template.txt")) { File.Move("./template.txt", TEMPLATE_FILE_PATH); return; } Logger.Warn("Creating a new Template file from: " + text3, "TemplateManager", escapeCRLF: true, 122, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\TemplateManager.cs"); File.WriteAllText(TEMPLATE_FILE_PATH, resourcesTxt); } else { string text4 = File.ReadAllText(TEMPLATE_FILE_PATH, Encoding.GetEncoding("UTF-8")); File.WriteAllText(TEMPLATE_FILE_PATH, text4.Replace("5PNwUaN5", "hkk2p9ggv4")); } } catch (Exception ex) { Logger.Exception(ex, "TemplateManager", 134, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\TemplateManager.cs"); } } private static string GetResourcesTxt(string path) { Stream? manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); manifestResourceStream.Position = 0L; using StreamReader streamReader = new StreamReader(manifestResourceStream, Encoding.UTF8); return streamReader.ReadToEnd(); } public static void SendTemplate(string str = "", byte playerId = byte.MaxValue, bool noErr = false) { CreateIfNotExists(); using StreamReader streamReader = new StreamReader(TEMPLATE_FILE_PATH, Encoding.GetEncoding("UTF-8")); string[] array = Array.Empty(); List list = new List(); HashSet hashSet = new HashSet(); Func value = () => ""; if (playerId != byte.MaxValue) { value = () => Main.AllPlayerNames[playerId]; } _replaceDictionaryNormalOptions["PlayerName"] = value; _replaceDictionaryHideNSeekOptions["PlayerName"] = value; string text; while ((text = streamReader.ReadLine()) != null) { array = text.Split(":"); if (array.Length > 1 && array[1] != "") { hashSet.Add(array[0]); if (array[0].ToLower() == str.ToLower()) { list.Add(GeneralExtensions.Join(array.Skip(1), (Func)null, ":").Replace("\\n", "\n")); } } } if (list.Count == 0 && !noErr) { if (playerId == byte.MaxValue) { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, string.Format(Translator.GetString("Message.TemplateNotFoundHost"), str, GeneralExtensions.Join((IEnumerable)hashSet, (Func)null, ", ")), true); } else { Utils.SendMessage(string.Format(Translator.GetString("Message.TemplateNotFoundClient"), str), playerId, "", logforChatManager: false, noReplay: true); } return; } string[] array2 = list.ToArray(); foreach (string text2 in array2) { bool Contains; string text3 = TryGetTitle(text2, out Contains); string text4 = text2; if (Contains) { text4 = ((text3 != "") ? text2.Remove(text2.IndexOf(""), text2.IndexOf("")) : ""); text4 = text4.Replace("", ""); text4 = text4.Replace("", ""); } Utils.SendMessage(ApplyReplaceDictionary(text4), playerId, text3, logforChatManager: false, noReplay: true); } } private static string ApplyReplaceDictionary(string text) { try { if (GameStates.IsNormalGame) { KeyValuePair>[] array = _replaceDictionaryNormalOptions.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair> keyValuePair = array[i]; text = Regex.Replace(text, "{{" + keyValuePair.Key + "}}", keyValuePair.Value() ?? "", RegexOptions.IgnoreCase); } } else if (GameStates.IsHideNSeek) { KeyValuePair>[] array = _replaceDictionaryHideNSeekOptions.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair> keyValuePair2 = array[i]; text = Regex.Replace(text, "{{" + keyValuePair2.Key + "}}", keyValuePair2.Value() ?? "", RegexOptions.IgnoreCase); } } return text; } catch { return text; } } private static string TryGetTitle(string Text, out bool Contains) { int num = Text.IndexOf(""); int num2 = Text.IndexOf(""); bool flag = (Contains = num != -1 && num2 != -1 && num < num2); string result = ""; if (flag) { result = Text.Substring(num, num2); result = result.Replace("", ""); result = result.Replace("", ""); } return result; } } public static class Translator { [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public string strItem; public SupportedLangs langId; public Func, bool> <>9__3; internal bool b__0(KeyValuePair> x) { return x.Key.ToLower().Contains(strItem.ToLower()); } internal string[] b__2(KeyValuePair> x) { return (from inner in x.Value where inner.Key == (int)langId select inner into x select x.Value).ToArray(); } internal bool b__3(KeyValuePair inner) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between I4 and Unknown return inner.Key == (int)langId; } } public static Dictionary> translateMaps; public const string LANGUAGE_FOLDER_NAME = "Language"; private static readonly Dictionary> ActualRoleNames = new Dictionary>(); public static void Init() { Logger.Info("Loading language files...", "Translator", escapeCRLF: true, 18, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); LoadLangs(); Logger.Info("Language file loaded successfully", "Translator", escapeCRLF: true, 20, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } public static void LoadLangs() { //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) try { string directoryName = "TOHE.Resources.Lang"; Assembly executingAssembly = Assembly.GetExecutingAssembly(); string[] jsonFileNames = GetJsonFileNames(executingAssembly, directoryName); translateMaps = new Dictionary>(); if (jsonFileNames.Length == 0) { Logger.Warn("Json Translation files does not exist.", "Translator", escapeCRLF: true, 37, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); return; } string[] array = jsonFileNames; foreach (string text in array) { using Stream stream = executingAssembly.GetManifestResourceStream(text); if (stream == null) { continue; } using StreamReader streamReader = new StreamReader(stream); Dictionary dictionary = JsonSerializer.Deserialize>(streamReader.ReadToEnd()); if (dictionary.TryGetValue("LanguageID", out var value) && int.TryParse(value, out var result)) { dictionary.Remove("LanguageID"); MergeJsonIntoTranslationMap(translateMaps, result, dictionary); } else { Logger.Warn("Invalid JSON format in " + text + ": Missing or invalid 'LanguageID' field.", "Translator", escapeCRLF: true, 63, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } } JsonSerializer.Serialize(translateMaps, new JsonSerializerOptions { WriteIndented = true }); } catch (Exception value2) { Logger.Error($"Error: {value2}", "Translator", escapeCRLF: true, 76, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } if (!Directory.Exists("Language")) { Directory.CreateDirectory("Language"); } CreateTemplateFile(); SupportedLangs[] allValues = EnumHelper.GetAllValues(); foreach (SupportedLangs val in allValues) { if (!File.Exists($"./{"Language"}/{val}.dat")) { continue; } if (!ActualRoleNames.ContainsKey(val)) { ActualRoleNames.Add(val, new Dictionary()); } CustomRoles[] allRoles = CustomRolesHelper.AllRoles; foreach (CustomRoles customRoles in allRoles) { if (ActualRoleNames[val].ContainsKey(customRoles)) { ActualRoleNames[val][customRoles] = GetString($"{customRoles}", val); } else { ActualRoleNames[val].Add(customRoles, GetString($"{customRoles}", val)); } } UpdateCustomTranslation($"{val}.dat"); LoadCustomTranslation($"{val}.dat", val); } } private static void MergeJsonIntoTranslationMap(Dictionary> translationMaps, int languageId, Dictionary jsonDictionary) { foreach (KeyValuePair item in jsonDictionary) { string key = item.Key; string value = item.Value; if (value != null) { if (!translationMaps.ContainsKey(key)) { translationMaps[key] = new Dictionary(); } translationMaps[key][languageId] = value.Replace("\\n", "\n").Replace("\\r", "\r"); } } } private static string[] GetJsonFileNames(Assembly assembly, string directoryName) { return (from resourceName in assembly.GetManifestResourceNames() where resourceName.StartsWith(directoryName) && resourceName.EndsWith(".json") select resourceName).ToArray(); } public static void GetActualRoleName(this CustomRoles role, out string RealName) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; if (ActualRoleNames.TryGetValue(languageID, out var value)) { if (value.TryGetValue(role, out var value2)) { RealName = value2; return; } RealName = GetString($"{role}"); Logger.Info($"Error while obtaining Rolename for LANG: {languageID}/{role}", "Translator.GetActualRoleName", escapeCRLF: true, 183, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } else { RealName = GetString($"{role}"); } } public static string GetString(string s, Dictionary replacementDic = null, bool console = false, bool showInvalid = true, bool vanilla = false) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (vanilla) { if (Enum.TryParse(s, out StringNames result)) { return DestroyableSingleton.Instance.GetString(result, (Il2CppReferenceArray)null); } if (!showInvalid) { return s; } return " (vanillaStr)"; } SupportedLangs langId = (SupportedLangs)(DestroyableSingleton.InstanceExists ? ((int)DestroyableSingleton.Instance.currentLanguage.languageID) : 0); if (console) { langId = (SupportedLangs)0; } if (Main.ForceOwnLanguage.Value) { langId = GetUserTrueLang(); } string text = GetString(s, langId, showInvalid); if (replacementDic != null) { foreach (KeyValuePair item in replacementDic) { text = text.Replace(item.Key, item.Value); } } return text; } public static bool TryGetStrings(string strItem, out string[] s) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0027->IL0027: Incompatible stack types: O vs I4 //IL_0018->IL0027: Incompatible stack types: I4 vs O //IL_0018->IL0027: Incompatible stack types: O vs I4 <>c__DisplayClass9_0 CS$<>8__locals0 = new <>c__DisplayClass9_0(); CS$<>8__locals0.strItem = strItem; object obj = CS$<>8__locals0; int num; if (DestroyableSingleton.InstanceExists) { obj = DestroyableSingleton.Instance.currentLanguage.languageID; num = (int)obj; } else { num = 0; obj = num; num = (int)obj; } ((<>c__DisplayClass9_0)num).langId = (SupportedLangs)obj; if (Main.ForceOwnLanguage.Value) { CS$<>8__locals0.langId = GetUserTrueLang(); } s = new string[1] { "" }; try { Dictionary dictionary = translateMaps.Where((KeyValuePair> x) => x.Key.ToLower().Contains(CS$<>8__locals0.strItem.ToLower())).ToDictionary((KeyValuePair> x) => x.Key, (KeyValuePair> x) => (from inner in x.Value where inner.Key == (int)CS$<>8__locals0.langId select inner into x select x.Value).ToArray()); if (dictionary.Keys.Any()) { List list = new List(); foreach (KeyValuePair item in dictionary) { string @string = GetString(item.Key, CS$<>8__locals0.langId); Logger.Info(" Adding < " + @string + " > to the list of strings", "Translator.TryGetStrings", escapeCRLF: true, 245, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); list.Add(@string); } int num2 = 0; string[] array = new string[list.Count]; foreach (string item2 in list) { array[num2] = item2; num2++; } s = array; return true; } } catch (Exception ex) { Logger.Exception(ex, "Translator.TryGetStrings", 254, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } return false; } public static string GetString(string str, SupportedLangs langId, bool showInvalid = true) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 string value = (showInvalid ? ("") : str); try { if (translateMaps.TryGetValue(str, out var value2) && (!value2.TryGetValue((int)langId, out value) || value == "" || ((int)langId != 13 && (int)langId != 14 && Regex.IsMatch(value, "[\\u4e00-\\u9fa5]") && value == GetString(str, (SupportedLangs)13)))) { value = (((int)langId != 0) ? GetString(str, (SupportedLangs)0) : ("*" + str)); } if (!translateMaps.ContainsKey(str)) { StringNames[] array = (from x in EnumHelper.GetAllValues() where ((object)(StringNames)(ref x)).ToString() == str select x).ToArray(); if (array != null && array.Any()) { value = GetString(array.FirstOrDefault()); } } } catch (Exception ex) { Logger.Fatal("Error oucured at [" + str + "] in String.csv", "Translator", escapeCRLF: true, 279, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); Logger.Error("Here was the error:\n" + ex.ToString(), "Translator", escapeCRLF: true, 280, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } return value; } public static string GetString(StringNames stringName) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return DestroyableSingleton.Instance.GetString(stringName, new Il2CppReferenceArray(0L)); } public static string GetRoleString(string str, bool forUser = true) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; SupportedLangs langId = (SupportedLangs)(forUser ? ((int)languageID) : 0); if (Main.ForceOwnLanguageRoleName.Value) { langId = GetUserTrueLang(); } return GetString(str, langId); } public static SupportedLangs GetUserTrueLang() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) try { string name = CultureInfo.CurrentUICulture.Name; if (name.StartsWith("en")) { return (SupportedLangs)0; } if (name.StartsWith("zh_CHT")) { return (SupportedLangs)14; } if (name.StartsWith("zh")) { return (SupportedLangs)13; } if (name.StartsWith("ru")) { return (SupportedLangs)5; } return DestroyableSingleton.Instance.currentLanguage.languageID; } catch { return (SupportedLangs)0; } } private static void UpdateCustomTranslation(string filename) { string path = "./Language/" + filename; if (!File.Exists(path)) { return; } Logger.Info("Updating Custom Translations", "UpdateCustomTranslation", escapeCRLF: true, 316, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); try { List list = new List(); using (StreamReader streamReader = new StreamReader(path, Encoding.GetEncoding("UTF-8"))) { string text; while ((text = streamReader.ReadLine()) != null) { string[] array = text.Split(':'); if (array.Length >= 1) { string item = array[0].Trim(); list.Add(item); } } } StringBuilder stringBuilder = new StringBuilder(); foreach (string key in translateMaps.Keys) { if (!list.Contains(key)) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(key); handler.AppendLiteral(":\n"); stringBuilder2.Append(ref handler); } } using FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write); using StreamWriter streamWriter = new StreamWriter(stream); streamWriter.WriteLine(stringBuilder.ToString()); } catch (Exception ex) { Logger.Error("An error occurred: " + ex.Message, "Translator", escapeCRLF: true, 351, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } } public static void LoadCustomTranslation(string filename, SupportedLangs lang) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected I4, but got Unknown string path = "./Language/" + filename; if (File.Exists(path)) { Logger.Info("加载自定义翻译文件:" + filename, "LoadCustomTranslation", escapeCRLF: true, 360, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); using StreamReader streamReader = new StreamReader(path, Encoding.GetEncoding("UTF-8")); string[] array = Array.Empty(); string text; while ((text = streamReader.ReadLine()) != null) { array = text.Split(":"); if (array.Length > 1 && array[1] != "") { try { translateMaps[array[0]][(int)lang] = GeneralExtensions.Join(array.Skip(1), (Func)null, ":").Replace("\\n", "\n").Replace("\\r", "\r"); } catch (KeyNotFoundException) { Logger.Warn("无效密钥:" + array[0], "LoadCustomTranslation", escapeCRLF: true, 375, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } } } return; } Logger.Error("找不到自定义翻译文件:" + filename, "LoadCustomTranslation", escapeCRLF: true, 382, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Translator.cs"); } private static void CreateTemplateFile() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair> translateMap in translateMaps) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(translateMap.Key); handler.AppendLiteral(":\n"); stringBuilder2.Append(ref handler); } File.WriteAllText("./Language/template.dat", stringBuilder.ToString()); } public static void ExportCustomTranslation() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected I4, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) LoadLangs(); StringBuilder stringBuilder = new StringBuilder(); SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; foreach (KeyValuePair> translateMap in translateMaps) { if (!translateMap.Value.TryGetValue((int)languageID, out var value)) { value = ""; } StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder2); handler.AppendFormatted(translateMap.Key); handler.AppendLiteral(":"); handler.AppendFormatted(value.Replace("\n", "\\n").Replace("\r", "\\r")); handler.AppendLiteral("\n"); stringBuilder2.Append(ref handler); } File.WriteAllText($"./{"Language"}/export_{languageID}.dat", stringBuilder.ToString()); } } public static class Utils { private static readonly DateTime timeStampStartTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); private static readonly StringBuilder SelfSuffix = new StringBuilder(); private static readonly StringBuilder SelfMark = new StringBuilder(20); private static readonly StringBuilder TargetSuffix = new StringBuilder(); private static readonly StringBuilder TargetMark = new StringBuilder(20); public static HashSet> LateExileTask = new HashSet>(); public static Dictionary CachedSprites = new Dictionary(); public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - timeStampStartTime).TotalSeconds; public static int AllPlayersCount => Main.PlayerStates.Values.Count((PlayerState state) => state.countTypes != CountTypes.OutOfGame); public static int AllAlivePlayersCount => Main.AllAlivePlayerControls.Count((PlayerControl pc) => !pc.Is(CountTypes.OutOfGame)); public static bool IsAllAlive => Main.PlayerStates.Values.All((PlayerState state) => state.countTypes == CountTypes.OutOfGame || !state.IsDead); public static long GetTimeStamp(DateTime? dateTime = null) { return (long)((dateTime ?? DateTime.Now).ToUniversalTime() - timeStampStartTime).TotalSeconds; } public static void ErrorEnd(string text) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Logger.Fatal("Error: " + text + " - triggering critical error", "Anti-black", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); ChatUpdatePatch.DoBlockChat = true; Main.OverrideWelcomeMsg = Translator.GetString("AntiBlackOutNotifyInLobby"); new LateTask(delegate { Logger.SendInGame(Translator.GetString("AntiBlackOutLoggerSendInGame")); }, 3f, "Anti-Black Msg SendInGame Error During Loading"); new LateTask(delegate { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); GameManager.Instance.LogicFlow.CheckEndCriteria(); RPC.ForceEndGame(CustomWinner.Error); }, 5.5f, "Anti-Black End Game As Critical Error"); return; } MessageWriter obj = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)106, (SendOption)1); obj.Write(text); obj.EndMessage(); if (Options.EndWhenPlayerBug.GetBool()) { new LateTask(delegate { Logger.SendInGame(Translator.GetString("AntiBlackOutRequestHostToForceEnd")); }, 3f, "Anti-Black Msg SendInGame Non-Host Modded Has Error During Loading"); return; } new LateTask(delegate { Logger.SendInGame(Translator.GetString("AntiBlackOutHostRejectForceEnd")); }, 3f, "Anti-Black Msg SendInGame Host Reject Force End"); new LateTask(delegate { AmongUsClient.Instance.ExitGame((DisconnectReasons)8); Logger.Fatal("Error: " + text + " - Disconnected from the game due critical error", "Anti-black", escapeCRLF: true, 78, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); }, 8f, "Anti-Black Exit Game Due Critical Error"); } public static ClientData GetClientById(int id) { try { return ((IEnumerable)((InnerNetClient)AmongUsClient.Instance).allClients.ToArray()).FirstOrDefault((Func)((ClientData cd) => cd.Id == id)); } catch { return null; } } public static bool AnySabotageIsActive() { if (!IsActive((SystemTypes)7) && !IsActive((SystemTypes)14) && !IsActive((SystemTypes)57) && !IsActive((SystemTypes)21) && !IsActive((SystemTypes)8) && !IsActive((SystemTypes)3)) { return IsActive((SystemTypes)58); } return true; } public static bool IsActive(SystemTypes type) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return false; } if (!ShipStatus.Instance.Systems.ContainsKey(type)) { return false; } int activeMapId = GetActiveMapId(); if ((int)type <= 8) { if ((int)type == 3) { if (activeMapId == 2) { return false; } ReactorSystemType val = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val != null) { return val.IsActive; } return false; } if ((int)type == 7) { if (activeMapId == 5) { return false; } SwitchSystem val2 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val2 != null) { return val2.IsActive; } return false; } if ((int)type == 8) { if ((activeMapId == 2 || (uint)(activeMapId - 4) <= 1u) ? true : false) { return false; } LifeSuppSystemType val3 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val3 != null) { return val3.IsActive; } return false; } } else if ((int)type <= 21) { if ((int)type == 14) { if ((activeMapId == 1 || activeMapId == 5) ? true : false) { HqHudSystemType val4 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val4 != null) { return val4.IsActive; } return false; } HudOverrideSystemType val5 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val5 != null) { return val5.IsActive; } return false; } if ((int)type == 21) { if (activeMapId != 2) { return false; } ReactorSystemType val6 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if (val6 != null) { return val6.IsActive; } return false; } } else { if ((int)type == 57) { if (activeMapId != 5) { return false; } MushroomMixupSabotageSystem val7 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).TryCast(); if ((Object)(object)val7 != (Object)null) { return val7.IsActive; } return false; } if ((int)type == 58) { if (activeMapId != 4) { return false; } HeliSabotageSystem val8 = ((Il2CppObjectBase)ShipStatus.Instance.Systems[type]).Cast(); if ((Object)(object)val8 != (Object)null) { return val8.IsActive; } return false; } } return false; } public static SystemTypes GetCriticalSabotageSystemType() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) MapNames activeMapName = GetActiveMapName(); if ((int)activeMapName != 2) { if ((int)activeMapName == 4) { return (SystemTypes)58; } return (SystemTypes)3; } return (SystemTypes)21; } public static MapNames GetActiveMapName() { return (MapNames)GameOptionsManager.Instance.CurrentGameOptions.MapId; } public static byte GetActiveMapId() { return GameOptionsManager.Instance.CurrentGameOptions.MapId; } public static void SetVision(this IGameOptions opt, bool HasImpVision) { if (HasImpVision) { opt.SetFloat((FloatOptionNames)4, opt.GetFloat((FloatOptionNames)3)); if (IsActive((SystemTypes)7)) { opt.SetFloat((FloatOptionNames)4, opt.GetFloat((FloatOptionNames)4) * 5f); } } else { opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)4)); if (IsActive((SystemTypes)7)) { opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)3) / 5f); } } } public static void SetVisionV2(this IGameOptions opt) { opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)4)); if (IsActive((SystemTypes)7)) { opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)3) / 5f); } } public static void TargetDies(PlayerControl killer, PlayerControl target) { if (!target.Data.IsDead || GameStates.IsMeeting) { return; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (KillFlashCheck(killer, target, val)) { val.KillFlash(); } } if (target.Is(CustomRoles.Cyber)) { Cyber.AfterCyberDeadTask(target, inMeeting: false); } } public static bool KillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { if (seer.Is(CustomRoles.GM) || seer.Is(CustomRoles.Seer)) { return true; } if (target.GetRoleClass().GlobalKillFlashCheck(killer, target, seer)) { return true; } if (seer.IsAlive() && seer.GetRoleClass().KillFlashCheck(killer, target, seer)) { return true; } return false; } public static void KillFlash(this PlayerControl player) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) bool flag = IsActive(GetCriticalSabotageSystemType()); float @float = Options.KillFlashDuration.GetFloat(); if (flag) { @float += 0.2f; } Main.PlayerStates[player.PlayerId].IsBlackOut = true; if (((InnerNetObject)player).AmOwner) { FlashColor(new Color(1f, 0f, 0f, 0.3f)); if (Constants.ShouldPlaySfx()) { RPC.PlaySound(player.PlayerId, Sounds.KillSound); } } else if (player.IsModClient()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)113, (SendOption)1, player.GetClientId()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else if (!flag) { player.ReactorFlash(); } player.MarkDirtySettings(); new LateTask(delegate { Main.PlayerStates[player.PlayerId].IsBlackOut = false; player.MarkDirtySettings(); }, Options.KillFlashDuration.GetFloat(), "Remove Kill Flash"); } public static void BlackOut(this IGameOptions opt, bool IsBlackOut) { opt.SetFloat((FloatOptionNames)3, Main.DefaultImpostorVision); opt.SetFloat((FloatOptionNames)4, Main.DefaultCrewmateVision); if (IsBlackOut) { opt.SetFloat((FloatOptionNames)3, 0f); opt.SetFloat((FloatOptionNames)4, 0f); } } public static string GetRoleTitle(this CustomRoles role) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) string text = ColorString(Color32.op_Implicit(GetRoleColor(role)), Translator.GetString($"{role}")); string text2 = GetRoleMode(role); if (role.IsAdditionRole() && !role.IsEnable()) { text2 = ColorString(Color32.op_Implicit(Color.red), "(OFF)"); } return text + " " + text2; } public static string GetInfoLong(this CustomRoles role) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) string @string = Translator.GetString($"{role}" + "InfoLong"); string text = ColorString(str: Translator.GetString($"{role}"), color: Color32.op_Implicit(GetRoleColor(role).ShadeColor(0.25f))); role.GetActualRoleName(out var RealName); return @string.Replace(RealName, text ?? ""); } public static string GetDisplayRoleAndSubName(byte seerId, byte targetId, bool notShowAddOns = false) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) (string, Color) roleAndSubText = GetRoleAndSubText(seerId, targetId, notShowAddOns); return ColorString(Color32.op_Implicit(roleAndSubText.Item2), roleAndSubText.Item1); } public static string GetRoleName(CustomRoles role, bool forUser = true) { return Translator.GetRoleString(Enum.GetName(typeof(CustomRoles), role), forUser); } public static string GetRoleMode(CustomRoles role, bool parentheses = true) { if (Options.HideGameSettings.GetBool() && Main.AllPlayerControls.Length > 1) { return string.Empty; } string chance = GetChance(role.GetMode()); if (role == CustomRoles.Lovers) { chance = GetChance(Options.LoverSpawnChances.GetInt()); } else if (role.IsAdditionRole() && Options.CustomAdtRoleSpawnRate.ContainsKey(role)) { chance = GetChance(Options.CustomAdtRoleSpawnRate[role].GetFloat()); } if (!parentheses) { return chance; } return "(" + chance + ")"; } public static string GetChance(float percent) { if (percent != 0f) { if (percent != 5f) { if (percent != 10f) { if (percent != 15f) { if (percent != 20f) { if (percent != 25f) { if (percent != 30f) { if (percent != 35f) { if (percent != 40f) { if (percent != 45f) { if (percent != 50f) { if (percent != 55f) { if (percent != 60f) { if (percent != 65f) { if (percent != 70f) { if (percent != 75f) { if (percent != 80f) { if (percent != 85f) { if (percent != 90f) { if (percent != 95f) { if (percent != 100f) { return $"{percent}%"; } return "100%"; } return "95%"; } return "90%"; } return "85%"; } return "80%"; } return "75%"; } return "70%"; } return "65%"; } return "60%"; } return "55%"; } return "50%"; } return "45%"; } return "40%"; } return "35%"; } return "30%"; } return "25%"; } return "20%"; } return "15%"; } return "10%"; } return "5%"; } return "0%"; } public static string GetDeathReason(PlayerState.DeathReason status) { return Translator.GetString("DeathReason." + Enum.GetName(typeof(PlayerState.DeathReason), status)); } public static Color GetRoleColor(CustomRoles role) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!Main.roleColors.TryGetValue(role, out var value)) { value = "#ffffff"; } Color result = default(Color); ColorUtility.TryParseHtmlString(value, ref result); return result; } public static Color GetTeamColor(PlayerControl player) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) string text = string.Empty; switch (player.GetCustomRole().GetCustomRoleTeam()) { case Custom_Team.Crewmate: text = "#8cffff"; break; case Custom_Team.Impostor: text = "#ff1919"; break; case Custom_Team.Neutral: text = "#7f8c8d"; break; } Color result = default(Color); ColorUtility.TryParseHtmlString(text, ref result); return result; } public static string GetRoleColorCode(CustomRoles role) { if (!Main.roleColors.TryGetValue(role, out var value)) { return "#ffffff"; } return value; } public static (string, Color) GetRoleAndSubText(byte seerId, byte targetId, bool notShowAddOns = false) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Invalid comparison between Unknown and I4 //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) string text = "Invalid Role"; Color val = Color32.op_Implicit(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)); CustomRoles mainRole = Main.PlayerStates[targetId].MainRole; List subRoles = Main.PlayerStates[targetId].SubRoles; if (DollMaster.IsControllingPlayer && !((Object)(object)DollMaster.DollMasterTarget == (Object)null) && !((Object)(object)DollMaster.controllingTarget == (Object)null)) { if (seerId != DollMaster.DollMasterTarget.PlayerId && targetId == DollMaster.DollMasterTarget.PlayerId) { subRoles = Main.PlayerStates[DollMaster.controllingTarget.PlayerId].SubRoles; } else if (seerId != DollMaster.controllingTarget.PlayerId && targetId == DollMaster.controllingTarget.PlayerId) { subRoles = Main.PlayerStates[DollMaster.DollMasterTarget.PlayerId].SubRoles; } } text = GetRoleName(mainRole); val = GetRoleColor(mainRole); try { PlayerControl seer; PlayerControl target; bool @bool; bool flag; if (subRoles.Any()) { seer = GetPlayerById(seerId); target = GetPlayerById(targetId); if ((Object)(object)seer == (Object)null || (Object)(object)target == (Object)null) { return (text, val); } if (LastImpostor.currentId == targetId) { text = Translator.GetRoleString("Last-") + text; } if (Options.NameDisplayAddons.GetBool() && !notShowAddOns) { ClientData client = seer.GetClient(); Platforms? val2 = ((client != null) ? new Platforms?(client.PlatformData.Platform) : null); @bool = Options.AddBracketsToAddons.GetBool(); if (val2.HasValue) { Platforms valueOrDefault = val2.GetValueOrDefault(); if (valueOrDefault - 8 <= 2) { flag = true; goto IL_01c5; } } flag = false; goto IL_01c5; } goto IL_036b; } goto IL_043c; IL_01c5: CustomRoles[] array; if (flag) { text = ColorStringWithoutEnding(Color32.op_Implicit(GetRoleColor(mainRole)), text); array = subRoles.Where((CustomRoles subRole) => subRole.ShouldBeDisplayed() && seer.ShowSubRoleTarget(target, subRole)).ToArray(); foreach (CustomRoles customRoles in array) { text = ColorStringWithoutEnding(Color32.op_Implicit(GetRoleColor(customRoles)), @bool ? ("(" + Getname($"{customRoles}") + ") ") : (Getname($"{customRoles}") + " ")) + text; } } else { array = subRoles.Where((CustomRoles subRole) => subRole.ShouldBeDisplayed() && seer.ShowSubRoleTarget(target, subRole)).ToArray(); foreach (CustomRoles customRoles2 in array) { text = ColorString(Color32.op_Implicit(GetRoleColor(customRoles2)), @bool ? ("(" + Getname($"{customRoles2}") + ") ") : (Getname($"{customRoles2}") + " ")) + text; } } goto IL_036b; IL_036b: array = subRoles.ToArray(); foreach (CustomRoles customRoles3 in array) { if (seer.ShowSubRoleTarget(target, customRoles3)) { switch (customRoles3) { case CustomRoles.Admired: case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Recruit: case CustomRoles.Soulless: val = GetRoleColor(customRoles3); text = Translator.GetRoleString($"{customRoles3}-") + text; break; } } } goto IL_043c; IL_043c: return (text, val); } catch { return (text, val); } static bool Checkif(string str) { return new string[2] { "*Prefix", "INVALID" }.Any(str.Contains); } static string Getname(string str) { if (Checkif(Translator.GetString("Prefix." + str))) { return Translator.GetString(str ?? ""); } return Translator.GetString("Prefix." + str); } } public static string GetKillCountText(byte playerId, bool ffa = false) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) int num = Main.PlayerStates.Count((KeyValuePair x) => x.Value.GetRealKiller() == playerId); if (num < 1 && !ffa) { return ""; } return ColorString(new Color32(byte.MaxValue, (byte)69, (byte)0, byte.MaxValue), string.Format(Translator.GetString("KillCount"), num)); } public static string GetVitalText(byte playerId, bool RealKillerColor = false) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) PlayerState playerState = Main.PlayerStates[playerId]; string text = ((!playerState.IsDead) ? Translator.GetString("Alive") : ((playerState.deathReason == PlayerState.DeathReason.etc && playerState.Disconnected) ? Translator.GetString("Disconnected") : Translator.GetString("DeathReason." + playerState.deathReason))); if (RealKillerColor) { byte realKiller = playerState.GetRealKiller(); Color val = ((realKiller != byte.MaxValue) ? GetRoleColor(Main.PlayerStates[realKiller].MainRole) : GetRoleColor(CustomRoles.Doctor)); if (playerState.deathReason == PlayerState.DeathReason.etc && playerState.Disconnected) { ((Color)(ref val))..ctor(255f, 255f, 255f, 50f); } text = ColorString(Color32.op_Implicit(val), text); } return text; } public static bool HasTasks(NetworkedPlayerInfo playerData, bool ForRecompute = true) { if (GameStates.IsLobby) { return false; } if ((Object)(object)playerData == (Object)null) { return false; } if (playerData.Tasks == null) { return false; } if ((Object)(object)playerData.Role == (Object)null) { return false; } bool flag = true; if (!Main.PlayerStates.TryGetValue(playerData.PlayerId, out var value)) { return false; } if (playerData.Disconnected) { return false; } if (playerData.Role.IsImpostor) { flag = false; } if (Options.CurrentGameMode == CustomGameMode.FFA) { return false; } if (playerData.IsDead && Options.GhostIgnoreTasks.GetBool()) { flag = false; } if (GameStates.IsHideNSeek) { return flag; } CustomRoles mainRole = value.MainRole; if (value.RoleClass != null && !value.RoleClass.HasTasks(playerData, mainRole, ForRecompute)) { flag = false; } if (mainRole == CustomRoles.GM) { flag = false; } else { CustomRoles thisRoleBase = value.RoleClass.ThisRoleBase; if ((thisRoleBase == CustomRoles.Impostor || thisRoleBase == CustomRoles.Shapeshifter) ? true : false) { flag = false; } } CustomRoles[] array = value.SubRoles.ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Egoist: case CustomRoles.EvilSpirit: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Rascal: case CustomRoles.Recruit: case CustomRoles.Soulless: flag = flag && !ForRecompute; break; case CustomRoles.Mundane: if (!flag) { flag = !ForRecompute; } break; } } if (CopyCat.NoHaveTask(playerData.PlayerId)) { flag = false; } if (Main.TasklessCrewmate.Contains(playerData.PlayerId)) { flag = false; } return flag; } public static string GetProgressText(PlayerControl pc) { try { if (!Main.playerVersion.ContainsKey(((InnerNetClient)AmongUsClient.Instance).HostId)) { return string.Empty; } TaskState playerTaskState = pc.GetPlayerTaskState(); bool comms = false; if (playerTaskState.hasTasks) { if (IsActive((SystemTypes)14)) { comms = true; } if (Camouflager.AbilityActivated) { comms = true; } } return GetProgressText(pc.PlayerId, comms); } catch (Exception ex) { ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs", 616, "GetProgressText"); Logger.Error($"PlayerId: {pc.PlayerId}, Role: {Main.PlayerStates[pc.PlayerId].MainRole}", "GetProgressText(PlayerControl pc)", escapeCRLF: true, 617, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); return "Error1"; } } public static string GetProgressText(byte playerId, bool comms = false) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) try { if (!Main.playerVersion.ContainsKey(((InnerNetClient)AmongUsClient.Instance).HostId)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); CustomRoles mainRole = Main.PlayerStates[playerId].MainRole; if (Options.CurrentGameMode == CustomGameMode.FFA && mainRole == CustomRoles.Killer) { stringBuilder.Append(FFAManager.GetDisplayScore(playerId)); } else { stringBuilder.Append(playerId.GetRoleClassById()?.GetProgressText(playerId, comms)); if (stringBuilder.Length == 0) { TaskState taskState = Main.PlayerStates?[playerId].TaskState; if (taskState.hasTasks) { NetworkedPlayerInfo playerInfoById = GetPlayerInfoById(playerId); Color val = (HasTasks(playerInfoById) ? Color.green : GetRoleColor(mainRole).ShadeColor(0.5f)); Color val2 = (HasTasks(playerInfoById) ? Color.yellow : Color.white); if (Workhorse.IsThisRole(playerId)) { val2 = Workhorse.RoleColor; } Color val3 = (taskState.IsTaskFinished ? val : val2); if (Main.PlayerStates.TryGetValue(playerId, out var value) && value.MainRole == CustomRoles.Crewpostor) { val3 = Color.red; } Color val4 = (comms ? Color.gray : val3); string value2 = (comms ? "?" : $"{taskState.CompletedTasksCount}"); stringBuilder.Append(ColorString(Color32.op_Implicit(val4), $" ({value2}/{taskState.AllTasksCount})")); } } else { stringBuilder.Insert(0, " "); } } return stringBuilder.ToString(); } catch (Exception ex) { ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs", 668, "GetProgressText"); Logger.Error($"PlayerId: {playerId}, Role: {Main.PlayerStates[playerId].MainRole}", "GetProgressText(byte playerId, bool comms = false)", escapeCRLF: true, 669, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); return "Error2"; } } public static void ShowActiveSettingsHelp(byte PlayerId = byte.MaxValue) { SendMessage(Translator.GetString("CurrentActiveSettingsHelp") + ":", PlayerId); if (Options.DisableDevices.GetBool()) { SendMessage(Translator.GetString("DisableDevicesInfo"), PlayerId); } if (Options.SyncButtonMode.GetBool()) { SendMessage(Translator.GetString("SyncButtonModeInfo"), PlayerId); } if (Options.SabotageTimeControl.GetBool()) { SendMessage(Translator.GetString("SabotageTimeControlInfo"), PlayerId); } if (Options.RandomMapsMode.GetBool()) { SendMessage(Translator.GetString("RandomMapsModeInfo"), PlayerId); } if (Main.EnableGM.Value) { SendMessage(GetRoleName(CustomRoles.GM) + Translator.GetString("GMInfoLong"), PlayerId); } CustomRoles[] allRoles = CustomRolesHelper.AllRoles; foreach (CustomRoles customRoles in allRoles) { if (customRoles.IsEnable() && !customRoles.IsVanilla()) { SendMessage(GetRoleName(customRoles) + GetRoleMode(customRoles) + Translator.GetString(Enum.GetName(typeof(CustomRoles), customRoles) + "InfoLong"), PlayerId); } } if (Options.NoGameEnd.GetBool()) { SendMessage(Translator.GetString("NoGameEndInfo"), PlayerId); } } public static void ShowActiveSettings(byte PlayerId = byte.MaxValue) { if (Options.HideGameSettings.GetBool() && PlayerId != byte.MaxValue) { SendMessage(Translator.GetString("Message.HideGameSettings"), PlayerId); return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(" ★ " + Translator.GetString("TabGroup.SystemSettings")); OptionItem[] array = OptionItem.AllOptions.Where((OptionItem x) => x.GetBool() && x.Parent == null && x.Tab == TabGroup.SystemSettings && !x.IsHiddenOn(Options.CurrentGameMode)).ToArray(); foreach (OptionItem optionItem in array) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2); handler.AppendLiteral("\n"); handler.AppendFormatted(optionItem.GetName(disableColor: true)); handler.AppendLiteral(": "); handler.AppendFormatted(optionItem.GetString()); stringBuilder3.Append(ref handler); string str = stringBuilder.ToString(); stringBuilder.Clear().Append(str.RemoveHtmlTags()); } stringBuilder.Append("\n\n ★ " + Translator.GetString("TabGroup.ModSettings")); array = OptionItem.AllOptions.Where((OptionItem x) => x.GetBool() && x.Parent == null && x.Tab == TabGroup.ModSettings && !x.IsHiddenOn(Options.CurrentGameMode)).ToArray(); foreach (OptionItem optionItem2 in array) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, stringBuilder2); handler.AppendLiteral("\n"); handler.AppendFormatted(optionItem2.GetName(disableColor: true)); handler.AppendLiteral(": "); handler.AppendFormatted(optionItem2.GetString()); stringBuilder4.Append(ref handler); string str2 = stringBuilder.ToString(); stringBuilder.Clear().Append(str2.RemoveHtmlTags()); } SendMessage(stringBuilder.ToString(), PlayerId); } public static void ShowAllActiveSettings(byte PlayerId = byte.MaxValue) { if (Options.HideGameSettings.GetBool() && PlayerId != byte.MaxValue) { SendMessage(Translator.GetString("Message.HideGameSettings"), PlayerId); return; } StringBuilder sb = new StringBuilder(); sb.Append(Translator.GetString("Settings")).Append(':'); CustomRoles[] array = Options.CustomRoleCounts.Keys.ToArray(); foreach (CustomRoles customRoles in array) { if (customRoles.IsEnable()) { string chance = GetChance(customRoles.GetMode()); StringBuilder stringBuilder = sb; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 3, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(GetRoleName(customRoles)); handler.AppendLiteral(":"); handler.AppendFormatted(chance); handler.AppendLiteral(" ×"); handler.AppendFormatted(customRoles.GetCount()); handler.AppendLiteral("】\n"); stringBuilder2.Append(ref handler); ShowChildrenSettings(Options.CustomRoleSpawnChances[customRoles], ref sb); string str = sb.ToString(); sb.Clear().Append(str.RemoveHtmlTags()); } } OptionItem[] array2 = OptionItem.AllOptions.Where((OptionItem x) => x.GetBool() && x.Parent == null && x.Id > 59999 && !x.IsHiddenOn(Options.CurrentGameMode)).ToArray(); foreach (OptionItem optionItem in array2) { string name = optionItem.Name; if ((name == "KillFlashDuration" || name == "RoleAssigningAlgorithm") ? true : false) { StringBuilder stringBuilder = sb; StringBuilder stringBuilder3 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(6, 2, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(optionItem.GetName(disableColor: true)); handler.AppendLiteral(": "); handler.AppendFormatted(optionItem.GetString()); handler.AppendLiteral("】\n"); stringBuilder3.Append(ref handler); } else { StringBuilder stringBuilder = sb; StringBuilder stringBuilder4 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 1, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(optionItem.GetName(disableColor: true)); handler.AppendLiteral("】\n"); stringBuilder4.Append(ref handler); } ShowChildrenSettings(optionItem, ref sb); string str2 = sb.ToString(); sb.Clear().Append(str2.RemoveHtmlTags()); } SendMessage(sb.ToString(), PlayerId); } public static void CopyCurrentSettings() { StringBuilder sb = new StringBuilder(); if (Options.HideGameSettings.GetBool() && !((InnerNetClient)AmongUsClient.Instance).AmHost) { ClipboardHelper.PutClipboardString(Translator.GetString("Message.HideGameSettings")); return; } StringBuilder stringBuilder = sb; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(26, 1, stringBuilder); handler.AppendLiteral("━━━━━━━━━━━━【"); handler.AppendFormatted(Translator.GetString("Roles")); handler.AppendLiteral("】━━━━━━━━━━━━"); stringBuilder2.Append(ref handler); CustomRoles[] array = Options.CustomRoleCounts.Keys.ToArray(); foreach (CustomRoles customRoles in array) { if (customRoles.IsEnable()) { string chance = GetChance(customRoles.GetMode()); stringBuilder = sb; StringBuilder stringBuilder3 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(7, 3, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(GetRoleName(customRoles)); handler.AppendLiteral(":"); handler.AppendFormatted(chance); handler.AppendLiteral(" ×"); handler.AppendFormatted(customRoles.GetCount()); handler.AppendLiteral("】\n"); stringBuilder3.Append(ref handler); ShowChildrenSettings(Options.CustomRoleSpawnChances[customRoles], ref sb); string str = sb.ToString(); sb.Clear().Append(str.RemoveHtmlTags()); } } stringBuilder = sb; StringBuilder stringBuilder4 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(26, 1, stringBuilder); handler.AppendLiteral("━━━━━━━━━━━━【"); handler.AppendFormatted(Translator.GetString("Settings")); handler.AppendLiteral("】━━━━━━━━━━━━"); stringBuilder4.Append(ref handler); OptionItem[] array2 = OptionItem.AllOptions.Where((OptionItem x) => x.GetBool() && x.Parent == null && x.Id > 59999 && !x.IsHiddenOn(Options.CurrentGameMode)).ToArray(); foreach (OptionItem optionItem in array2) { if (optionItem.Name == "KillFlashDuration") { stringBuilder = sb; StringBuilder stringBuilder5 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(6, 2, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(optionItem.GetName(disableColor: true)); handler.AppendLiteral(": "); handler.AppendFormatted(optionItem.GetString()); handler.AppendLiteral("】\n"); stringBuilder5.Append(ref handler); } else { stringBuilder = sb; StringBuilder stringBuilder6 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(4, 1, stringBuilder); handler.AppendLiteral("\n【"); handler.AppendFormatted(optionItem.GetName(disableColor: true)); handler.AppendLiteral("】\n"); stringBuilder6.Append(ref handler); } ShowChildrenSettings(optionItem, ref sb); string str2 = sb.ToString(); sb.Clear().Append(str2.RemoveHtmlTags()); } sb.Append("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); ClipboardHelper.PutClipboardString(sb.ToString()); } public static void ShowActiveRoles(byte PlayerId = byte.MaxValue) { //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) if (Options.HideGameSettings.GetBool() && PlayerId != byte.MaxValue) { SendMessage(Translator.GetString("Message.HideGameSettings"), PlayerId); return; } List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); CustomRoles[] allRoles = CustomRolesHelper.AllRoles; foreach (CustomRoles customRoles in allRoles) { string chance = GetChance(customRoles.GetMode()); if (customRoles.IsEnable()) { if (customRoles == CustomRoles.Lovers) { chance = GetChance(Options.LoverSpawnChances.GetInt()); } else if (customRoles.IsAdditionRole() && Options.CustomAdtRoleSpawnRate.ContainsKey(customRoles)) { chance = GetChance(Options.CustomAdtRoleSpawnRate[customRoles].GetFloat()); } string item = $"{GetRoleName(customRoles)}: {chance} x{customRoles.GetCount()}"; if (customRoles.IsAdditionRole()) { list4.Add(item); } else if (customRoles.IsCrewmate()) { list3.Add(item); } else if (customRoles.IsImpostor() || customRoles.IsMadmate()) { list.Add(item); } else if (customRoles.IsNeutral()) { list2.Add(item); } } } list.Sort(); list3.Sort(); list2.Sort(); list4.Sort(); SendMessage(string.Join("\n", list), PlayerId, ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Impostor)), Translator.GetString("ImpostorRoles")), logforChatManager: false, noReplay: false, ShouldSplit: true); SendMessage(string.Join("\n", list3), PlayerId, ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Crewmate)), Translator.GetString("CrewmateRoles")), logforChatManager: false, noReplay: false, ShouldSplit: true); SendMessage(string.Join("\n", list2), PlayerId, Translator.GetString("NeutralRoles"), logforChatManager: false, noReplay: false, ShouldSplit: true); SendMessage(string.Join("\n", list4), PlayerId, Translator.GetString("AddonRoles"), logforChatManager: false, noReplay: false, ShouldSplit: true); } public static void ShowChildrenSettings(OptionItem option, ref StringBuilder sb, int deep = 0, bool command = false) { if (Options.HideGameSettings.GetBool()) { return; } var array = option.Children.Select((OptionItem v, int i) => new { Value = v, Index = i + 1 }).ToArray(); foreach (var anon in array) { if (command) { sb.Append("\n\n"); command = false; } if (!(anon.Value.Name == "Maximum") && (!(anon.Value.Name == "DisableSkeldDevices") || GameStates.SkeldIsActive || GameStates.DleksIsActive) && (!(anon.Value.Name == "DisableMiraHQDevices") || GameStates.MiraHQIsActive) && (!(anon.Value.Name == "DisablePolusDevices") || GameStates.PolusIsActive) && (!(anon.Value.Name == "DisableAirshipDevices") || GameStates.AirshipIsActive) && (!(anon.Value.Name == "PolusReactorTimeLimit") || GameStates.PolusIsActive) && (!(anon.Value.Name == "AirshipReactorTimeLimit") || GameStates.AirshipIsActive)) { if (deep > 0) { sb.Append(string.Concat(Enumerable.Repeat("┃", Mathf.Max(deep - 1, 0)))); sb.Append((anon.Index == option.Children.Count) ? "┗ " : "┣ "); } StringBuilder obj = sb; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 2, sb); handler.AppendFormatted(anon.Value.GetName(disableColor: true)); handler.AppendLiteral(": "); handler.AppendFormatted(anon.Value.GetString()); handler.AppendLiteral("\n"); obj.Append(ref handler); if (anon.Value.GetBool()) { ShowChildrenSettings(anon.Value, ref sb, deep + 1); } } } } public static void ShowLastRoles(byte PlayerId = byte.MaxValue) { if (((InnerNetClient)AmongUsClient.Instance).IsGameStarted) { SendMessage(Translator.GetString("CantUse.lastroles"), PlayerId); return; } StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, stringBuilder2); handler.AppendLiteral("<#ffffff>"); handler.AppendFormatted(Translator.GetString("RoleSummaryText")); handler.AppendLiteral(""); stringBuilder2.Append(ref handler); List list = new List(Main.PlayerStates.Keys); byte[] array = Main.winnerList.ToArray(); foreach (byte b in array) { if (!EndGamePatch.SummaryText[b].Contains("")) { stringBuilder.Append("\n<#c4aa02>★ ").Append(EndGamePatch.SummaryText[b]); list.Remove(b); } } if (Options.CurrentGameMode == CustomGameMode.FFA) { List<(int, byte)> list2 = new List<(int, byte)>(); array = list.ToArray(); foreach (byte b2 in array) { list2.Add((FFAManager.GetRankOfScore(b2), b2)); } list2.Sort(); (int, byte)[] array2 = list2.ToArray(); for (int i = 0; i < array2.Length; i++) { (int, byte) tuple = array2[i]; stringBuilder.Append("\n\u3000 ").Append(EndGamePatch.SummaryText[tuple.Item2]); } } else { array = list.ToArray(); foreach (byte key in array) { if (!EndGamePatch.SummaryText[key].Contains("")) { stringBuilder.Append("\n\u3000 ").Append(EndGamePatch.SummaryText[key]); } } } string text = stringBuilder.ToString(); try { if (text.Length > 2024 && !GetPlayerById(PlayerId).IsModClient()) { text = text.Replace("((IEnumerable)text.SplitMessage(), (Action)delegate(string x) { SendMessage("\n", PlayerId, "" + x + ""); }); } else { SendMessage("\n", PlayerId, "" + text + ""); } } catch (Exception value) { Logger.Warn($"Error after try split the msg {text} at: {value}", "Utils.ShowLastRoles..LastRoles", escapeCRLF: true, 910, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } } public static void ShowKillLog(byte PlayerId = byte.MaxValue) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsInGame) { SendMessage(Translator.GetString("CantUse.killlog"), PlayerId); } else if (EndGamePatch.KillLog != "") { string killLog = EndGamePatch.KillLog; killLog = (Options.OldKillLog.GetBool() ? killLog.RemoveHtmlTags() : killLog.Replace(" 0 && Options.CurrentGameMode != CustomGameMode.FFA) { SendMessage(stringBuilder.ToString(), PlayerId); } } public static string GetSubRolesText(byte id, bool disableColor = false, bool intro = false, bool summary = false) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) List subRoles = Main.PlayerStates[id].SubRoles; if (subRoles.Count == 0 && !intro) { return ""; } StringBuilder stringBuilder = new StringBuilder(); if (summary) { stringBuilder.Append(' '); } CustomRoles[] array = subRoles.ToArray(); foreach (CustomRoles customRoles in array) { if ((customRoles == CustomRoles.NotAssigned || customRoles == CustomRoles.LastImpostor) ? true : false) { continue; } bool flag = summary; if (flag) { bool flag2; switch (customRoles) { case CustomRoles.Admired: case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Infected: case CustomRoles.Madmate: case CustomRoles.Recruit: case CustomRoles.Soulless: flag2 = true; break; default: flag2 = false; break; } flag = flag2; } if (!flag) { Color roleColor = GetRoleColor(customRoles); string value = (disableColor ? GetRoleName(customRoles) : ColorString(Color32.op_Implicit(roleColor), GetRoleName(customRoles))); if (summary) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(0, 3, stringBuilder2); handler.AppendFormatted(ColorString(Color32.op_Implicit(roleColor), "(")); handler.AppendFormatted(value); handler.AppendFormatted(ColorString(Color32.op_Implicit(roleColor), ")")); stringBuilder3.Append(ref handler); } else { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(0, 2, stringBuilder2); handler.AppendFormatted(ColorString(Color32.op_Implicit(Color.white), " + ")); handler.AppendFormatted(value); stringBuilder4.Append(ref handler); } } } return stringBuilder.ToString(); } public static string GetRegionName(IRegionInfo region = null) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if (region == null) { region = DestroyableSingleton.Instance.CurrentRegion; } string text = region.Name; if ((int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 1) { return "Local Games"; } if (region.PingServer.EndsWith("among.us", StringComparison.Ordinal)) { switch (text) { case "North America": text = "NA"; break; case "Europe": text = "EU"; break; case "Asia": text = "AS"; break; } return text; } ServerInfo? obj = ((IEnumerable)region.Servers).FirstOrDefault(); string text2 = ((obj != null) ? obj.Ip : null) ?? string.Empty; if (text2.Contains("aumods.us", StringComparison.Ordinal) || text2.Contains("duikbo.at", StringComparison.Ordinal)) { if (text2.Contains("au-eu")) { text = "MEU"; } else if (text2.Contains("au-as")) { text = "MAS"; } else if (text2.Contains("www.")) { text = "MNA"; } return text; } if (text.Contains("nikocat233", StringComparison.OrdinalIgnoreCase)) { text = text.Replace("nikocat233", "Niko233", StringComparison.OrdinalIgnoreCase); } return text; } public static void ThrowException(Exception ex, [CallerFilePath] string fileName = "", [CallerLineNumber] int lineNumber = 0, [CallerMemberName] string callerMemberName = "") { try { StackFrame[] frames = new StackTrace(1, fNeedFileInfo: true).GetFrames(); StackFrame stackFrame = frames.FirstOrDefault(); StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(88, 6, stringBuilder2); handler.AppendLiteral(" Exception: "); handler.AppendFormatted(ex.Message); handler.AppendLiteral("\n thrown by "); handler.AppendFormatted(ex.Source); handler.AppendLiteral("\n at "); handler.AppendFormatted(ex.TargetSite); handler.AppendLiteral("\n in "); handler.AppendFormatted(fileName); handler.AppendLiteral(" at line "); handler.AppendFormatted(lineNumber); handler.AppendLiteral(" in "); handler.AppendFormatted(callerMemberName); handler.AppendLiteral("\n------ Stack Trace ------"); stringBuilder3.Append(ref handler); bool flag = true; StackFrame[] array = frames; foreach (StackFrame stackFrame2 in array) { if (flag) { flag = false; continue; } MethodBase? method = stackFrame2.GetMethod(); string value = method?.Name; string value2 = method?.DeclaringType?.FullName; stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(11, 2, stringBuilder2); handler.AppendLiteral("\n at "); handler.AppendFormatted(value2); handler.AppendLiteral("."); handler.AppendFormatted(value); stringBuilder4.Append(ref handler); } stringBuilder.Append("\n------ End of Stack Trace ------"); Logger.Error(stringBuilder.ToString(), stackFrame?.GetMethod()?.ToString(), escapeCRLF: true, 1041, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs", multiLine: true); } catch { } } public static byte MsgToColor(string text, bool isHost = false) { text = text.ToLowerInvariant(); text = text.Replace("色", string.Empty); int num; try { num = int.Parse(text); } catch { num = -1; } if (text != null) { switch (text.Length) { case 1: switch (text[0]) { case '0': case '紅': case '红': break; case '1': case '蓝': case '藍': goto IL_17b1; case '2': case '綠': case '绿': goto IL_17b5; case '3': goto IL_17b9; case '4': case '橘': goto IL_17bd; case '5': case '黃': case '黄': goto IL_17c1; case '6': case '黑': goto IL_17c5; case '7': case '白': goto IL_17c9; case '8': case '紫': goto IL_17cd; case '9': case '棕': goto IL_17d1; case '青': goto IL_17d6; case '灰': goto IL_17ef; case '茶': goto IL_17f4; case '?': goto IL_17fe; default: goto end_IL_0038; } goto IL_17ad; case 3: { char c = text[0]; if ((uint)c <= 1047u) { if ((uint)c <= 84u) { if (c == 'R') { if (!(text == "Red")) { break; } goto IL_17ad; } if (c != 'T' || !(text == "Tan")) { break; } } else { if (c == 'r') { if (!(text == "red")) { break; } goto IL_17ad; } if (c != 't') { if (c != 'З' || !(text == "Зел")) { break; } goto IL_17b5; } if (!(text == "tan")) { break; } } goto IL_17f4; } if ((uint)c <= 1057u) { if (c == 'Р') { if (!(text == "Роз")) { break; } goto IL_17b9; } if (c != 'С') { break; } if (text == "Син") { goto IL_17b1; } if (!(text == "Сер")) { break; } } else { if (c == 'з') { if (!(text == "зел")) { break; } goto IL_17b5; } if (c == 'р') { if (!(text == "роз")) { break; } goto IL_17b9; } if (c != 'с') { break; } if (text == "син") { goto IL_17b1; } if (!(text == "сер")) { break; } } goto IL_17ef; } case 8: { char c = text[0]; if ((uint)c <= 1041u) { if (c != 'V') { if (c != 'v') { if (c != 'Б' || !(text == "Бордовый")) { break; } goto IL_17e0; } if (!(text == "vermelho")) { break; } } else if (!(text == "Vermelho")) { break; } goto IL_17ad; } if (c != 'Л') { if (c == 'б') { if (!(text == "бордовый")) { break; } goto IL_17e0; } if (c != 'л' || !(text == "лаймовый")) { break; } } else if (!(text == "Лаймовый")) { break; } goto IL_17db; } case 4: switch (text[0]) { case 'к': break; case 'К': goto IL_0aeb; case 'b': goto IL_0b00; case 'B': goto IL_0b25; case 'a': goto IL_0b4a; case 'A': goto IL_0b5f; case 'p': goto IL_0b74; case 'P': goto IL_0b89; case 'r': goto IL_0b9e; case 'R': goto IL_0bd3; case 'Ж': goto IL_0c08; case 'ж': goto IL_0c2d; case 'Ч': goto IL_0c52; case 'Ф': goto IL_0c77; case 'ф': goto IL_0c8c; case 'c': goto IL_0ca1; case 'C': goto IL_0cb6; case 'l': goto IL_0ccb; case 'L': goto IL_0ce0; case 'Л': goto IL_0cf5; case 'л': goto IL_0d0a; case 'Б': goto IL_0d1f; case 'б': goto IL_0d34; case 'g': goto IL_0d49; case 'G': goto IL_0d6e; default: goto end_IL_0038; } if (!(text == "крас")) { break; } goto IL_17ad; case 5: { char c = text[0]; if ((uint)c <= 119u) { if ((uint)c <= 87u) { if ((uint)c <= 71u) { if (c != 'B') { if (c != 'C') { if (c != 'G' || !(text == "Green")) { break; } goto IL_17b5; } switch (text) { case "Ciano": break; case "Cinza": goto IL_17ef; case "Coral": goto IL_17f9; default: goto end_IL_0038; } goto IL_17d6; } switch (text) { case "Black": break; case "Brown": goto IL_17d1; case "Bordô": goto IL_17e0; default: goto end_IL_0038; } } else { if (c != 'P') { if (c != 'V') { if (c != 'W' || !(text == "White")) { break; } goto IL_17c9; } if (!(text == "Vinho")) { break; } goto IL_17e0; } if (!(text == "Preto")) { break; } } } else if ((uint)c <= 103u) { if (c != 'b') { if (c != 'c') { if (c != 'g' || !(text == "green")) { break; } goto IL_17b5; } switch (text) { case "ciano": break; case "cinza": goto IL_17ef; case "coral": goto IL_17f9; default: goto end_IL_0038; } goto IL_17d6; } switch (text) { case "black": break; case "brown": goto IL_17d1; case "bordô": goto IL_17e0; default: goto end_IL_0038; } } else { if (c != 'p') { if (c != 'v') { if (c != 'w' || !(text == "white")) { break; } goto IL_17c9; } if (!(text == "vinho")) { break; } goto IL_17e0; } if (!(text == "preto")) { break; } } goto IL_17c5; } if ((uint)c <= 1057u) { if ((uint)c > 1047u) { if (c != 'К') { if (c != 'О') { if (c != 'С') { break; } if (text == "Синий") { goto IL_17b1; } if (!(text == "Серый")) { break; } goto IL_17ef; } if (!(text == "Оранж")) { break; } goto IL_17bd; } switch (text) { case "Красн": break; case "Корич": goto IL_17d1; case "Корал": goto IL_17f9; default: goto end_IL_0038; } goto IL_17ad; } if (c == 'Б') { if (text == "Белый") { goto IL_17c9; } if (!(text == "Банан")) { break; } goto IL_17ea; } if (c == 'Г') { if (!(text == "Голуб")) { break; } goto IL_17d6; } if (c != 'З' || !(text == "Загар")) { break; } } else { if ((uint)c > 1079u) { if (c != 'к') { if (c != 'о') { if (c != 'с') { break; } if (text == "синий") { goto IL_17b1; } if (!(text == "серый")) { break; } goto IL_17ef; } if (!(text == "оранж")) { break; } goto IL_17bd; } switch (text) { case "красн": break; case "корич": goto IL_17d1; case "корал": goto IL_17f9; default: goto end_IL_0038; } goto IL_17ad; } if (c == 'б') { if (text == "белый") { goto IL_17c9; } if (!(text == "банан")) { break; } goto IL_17ea; } if (c == 'г') { if (!(text == "голуб")) { break; } goto IL_17d6; } if (c != 'з' || !(text == "загар")) { break; } } goto IL_17f4; } case 7: { char c = text[0]; if ((uint)c <= 1047u) { if ((uint)c <= 97u) { if (c != 'A') { if (c == 'L') { if (!(text == "Laranja")) { break; } goto IL_17bd; } if (c != 'a' || !(text == "amarelo")) { break; } } else if (!(text == "Amarelo")) { break; } goto IL_17c1; } if (c != 'l') { if (c != 'Г') { if (c != 'З' || (!(text == "Зелёный") && !(text == "Зеленый"))) { break; } goto IL_17b5; } if (!(text == "Голубой")) { break; } goto IL_17d6; } if (!(text == "laranja")) { break; } goto IL_17bd; } if ((uint)c <= 1075u) { if (c == 'К') { if (!(text == "Красный")) { break; } goto IL_17ad; } if (c != 'Р') { if (c != 'г' || !(text == "голубой")) { break; } goto IL_17d6; } if (!(text == "Розовый")) { break; } } else { if (c == 'з') { if (!(text == "зелёный") && !(text == "зеленый")) { break; } goto IL_17b5; } if (c == 'к') { if (!(text == "красный")) { break; } goto IL_17ad; } if (c != 'р' || !(text == "розовый")) { break; } } goto IL_17b9; } case 2: switch (text[1]) { case '蓝': break; case '绿': goto IL_11bc; case '红': goto IL_11f1; case '0': goto IL_1226; case '1': goto IL_123b; case '綠': goto IL_1250; case '2': goto IL_1265; case '褐': goto IL_127a; case '3': goto IL_129f; case '紅': goto IL_12b4; case '粉': goto IL_12c9; case '4': goto IL_12de; case '黄': goto IL_12f3; case '黃': goto IL_1318; case '5': goto IL_132d; case '6': goto IL_1342; case '7': goto IL_1357; case '瑚': goto IL_136c; case '8': goto IL_1381; case '藏': goto IL_1396; default: goto end_IL_0038; } if (!(text == "深蓝")) { break; } goto IL_17b1; case 12: { char c = text[0]; if (c != 'V') { if (c != 'v' || !(text == "verde-escuro")) { break; } } else if (!(text == "Verde-Escuro")) { break; } goto IL_17b5; } case 6: switch (text[0]) { case 'o': break; case 'O': goto IL_13ea; case 'y': goto IL_13ff; case 'Y': goto IL_1414; case 'Ж': goto IL_1429; case 'ж': goto IL_144e; case 'Ч': goto IL_1473; case 'ч': goto IL_1498; case 'b': goto IL_14bd; case 'B': goto IL_14e2; case 'p': goto IL_1507; case 'P': goto IL_151c; case 'm': goto IL_1531; case 'M': goto IL_1556; case 'С': goto IL_157b; case 'с': goto IL_1590; case 's': goto IL_15a5; case 'S': goto IL_15ba; case 'К': goto IL_15cf; case 'к': goto IL_15e4; default: goto end_IL_0038; } if (!(text == "orange")) { break; } goto IL_17bd; case 9: { char c = text[0]; if ((uint)c <= 1057u) { if ((uint)c > 1047u) { if (c != 'О') { if (c != 'С' || !(text == "Сиреневый")) { break; } goto IL_17e5; } if (!(text == "Оранжевый")) { break; } goto IL_17bd; } if (c == 'Б') { if (!(text == "Банановый")) { break; } goto IL_17ea; } if (c != 'З' || !(text == "Загаровый")) { break; } } else { if ((uint)c > 1079u) { if (c != 'к') { if (c != 'о') { if (c != 'с' || !(text == "сиреневый")) { break; } goto IL_17e5; } if (!(text == "оранжевый")) { break; } goto IL_17bd; } if (!(text == "коричевый")) { break; } goto IL_17d1; } if (c == 'б') { if (!(text == "банановый")) { break; } goto IL_17ea; } if (c != 'з' || !(text == "загаровый")) { break; } } goto IL_17f4; } case 10: { char c = text[0]; if ((uint)c <= 1057u) { if ((uint)c <= 114u) { if (c != 'R') { if (c != 'r' || !(text == "rosa-claro")) { break; } } else if (!(text == "Rosa-Claro")) { break; } } else { if (c == 'К') { if (text == "Коричневый") { goto IL_17d1; } if (!(text == "Коралловый")) { break; } goto IL_17f9; } if (c != 'С' || !(text == "Светло роз")) { break; } } goto IL_17e5; } if ((uint)c <= 1082u) { if (c != 'Ф') { if (c != 'к' || !(text == "коралловый")) { break; } goto IL_17f9; } if (!(text == "Фиолетовый")) { break; } } else { if (c == 'с') { if (!(text == "светло роз")) { break; } goto IL_17e5; } if (c != 'ф' || !(text == "фиолетовый")) { break; } } goto IL_17cd; } case 11: { char c = text[0]; if (c != 'V') { if (c != 'v' || !(text == "verde-claro")) { break; } } else if (!(text == "Verde-Claro")) { break; } goto IL_17db; } case 14: { char c = text[0]; if (c != 'С') { if (c != 'с' || !(text == "светло розовый")) { break; } } else if (!(text == "Светло розовый")) { break; } goto IL_17e5; } IL_12b4: if (!(text == "玫紅")) { break; } goto IL_17e5; IL_127a: if (!(text == "红褐") && !(text == "紅褐")) { break; } goto IL_17e0; IL_129f: if (!(text == "13")) { break; } goto IL_17e5; IL_0ce0: if (!(text == "Lime")) { break; } goto IL_17db; IL_1250: if (!(text == "黃綠")) { break; } goto IL_17db; IL_1265: if (!(text == "12")) { break; } goto IL_17e0; IL_123b: if (!(text == "11")) { break; } goto IL_17db; IL_11f1: switch (text) { case "粉红": break; case "深红": goto IL_17e0; case "玫红": goto IL_17e5; default: goto end_IL_0038; } goto IL_17b9; IL_0d34: if (!(text == "борд")) { break; } goto IL_17e0; IL_0cf5: if (!(text == "Лайм")) { break; } goto IL_17db; IL_11bc: switch (text) { case "深绿": break; case "黄绿": case "浅绿": goto IL_17db; default: goto end_IL_0038; } goto IL_17b5; IL_17cd: num = 8; break; IL_0c8c: if (!(text == "фиол")) { break; } goto IL_17cd; IL_0ca1: if (!(text == "cyan")) { break; } goto IL_17d6; IL_17c1: num = 5; break; IL_1226: if (!(text == "10")) { break; } goto IL_17d6; IL_0cb6: if (!(text == "Cyan")) { break; } goto IL_17d6; IL_0ccb: if (!(text == "lime")) { break; } goto IL_17db; IL_0c08: if (!(text == "Жёлт") && !(text == "Желт")) { break; } goto IL_17c1; IL_0c52: if (!(text == "Чёрн") && !(text == "Черн")) { break; } goto IL_17c5; IL_0c77: if (!(text == "Фиол")) { break; } goto IL_17cd; IL_17e5: num = 13; break; IL_0bd3: switch (text) { case "Rosa": break; case "Roxo": goto IL_17cd; case "Rose": goto IL_17e5; default: goto end_IL_0038; } goto IL_17b9; IL_0b9e: switch (text) { case "rosa": break; case "roxo": goto IL_17cd; case "rose": goto IL_17e5; default: goto end_IL_0038; } goto IL_17b9; IL_0c2d: if (!(text == "жёлт") && !(text == "желт")) { break; } goto IL_17c1; IL_17c5: num = 6; break; IL_0b4a: if (!(text == "azul")) { break; } goto IL_17b1; IL_17d6: num = 10; break; IL_0b00: if (text == "blue") { goto IL_17b1; } if (!(text == "bege")) { break; } goto IL_17f4; IL_0b74: if (!(text == "pink")) { break; } goto IL_17b9; IL_0b25: if (text == "Blue") { goto IL_17b1; } if (!(text == "Bege")) { break; } goto IL_17f4; IL_0b89: if (!(text == "Pink")) { break; } goto IL_17b9; IL_0d1f: if (!(text == "Борд")) { break; } goto IL_17e0; IL_17db: num = 11; break; IL_17b9: num = 3; break; IL_17ad: num = 0; break; IL_0b5f: if (!(text == "Azul")) { break; } goto IL_17b1; IL_17d1: num = 9; break; IL_17f4: num = 16; break; IL_17ea: num = 14; break; IL_15e4: if (!(text == "коралл")) { break; } goto IL_17f9; IL_15cf: if (!(text == "Коралл")) { break; } goto IL_17f9; IL_15ba: if (!(text == "Salmão")) { break; } goto IL_17f9; IL_15a5: if (!(text == "salmão")) { break; } goto IL_17f9; IL_1590: if (!(text == "сирень")) { break; } goto IL_17e5; IL_157b: if (!(text == "Сирень")) { break; } goto IL_17e5; IL_1556: if (text == "Marrom") { goto IL_17d1; } if (!(text == "Maroon")) { break; } goto IL_17e0; IL_17bd: num = 4; break; IL_1531: if (text == "marrom") { goto IL_17d1; } if (!(text == "maroon")) { break; } goto IL_17e0; IL_17c9: num = 7; break; IL_151c: if (!(text == "Purple")) { break; } goto IL_17cd; IL_1507: if (!(text == "purple")) { break; } goto IL_17cd; IL_14e2: if (text == "Branco") { goto IL_17c9; } if (!(text == "Banana")) { break; } goto IL_17ea; IL_17b1: num = 1; break; IL_14bd: if (text == "branco") { goto IL_17c9; } if (!(text == "banana")) { break; } goto IL_17ea; IL_0aeb: if (!(text == "Крас")) { break; } goto IL_17ad; IL_1498: if (!(text == "чёрный") && !(text == "черный")) { break; } goto IL_17c5; IL_17b5: num = 2; break; IL_1473: if (!(text == "Чёрный") && !(text == "Черный")) { break; } goto IL_17c5; IL_144e: if (!(text == "жёлтый") && !(text == "желтый")) { break; } goto IL_17c1; IL_17e0: num = 12; break; IL_1429: if (!(text == "Жёлтый") && !(text == "Желтый")) { break; } goto IL_17c1; IL_0d6e: if (!(text == "Gray") && !(text == "Grey")) { break; } goto IL_17ef; IL_1414: if (!(text == "Yellow")) { break; } goto IL_17c1; IL_13ff: if (!(text == "yellow")) { break; } goto IL_17c1; IL_13ea: if (!(text == "Orange")) { break; } goto IL_17bd; IL_17ef: num = 15; break; IL_17f9: num = 17; break; IL_0d49: if (!(text == "gray") && !(text == "grey")) { break; } goto IL_17ef; IL_17fe: num = 18; break; IL_1396: if (!(text == "隐藏")) { break; } goto IL_17fe; IL_1381: if (!(text == "18")) { break; } goto IL_17fe; IL_136c: if (!(text == "珊瑚")) { break; } goto IL_17f9; IL_1357: if (!(text == "17")) { break; } goto IL_17f9; IL_1342: if (!(text == "16")) { break; } goto IL_17f4; IL_132d: if (!(text == "15")) { break; } goto IL_17ef; IL_1318: if (!(text == "焦黃")) { break; } goto IL_17ea; IL_12f3: if (!(text == "焦黄") && !(text == "淡黄")) { break; } goto IL_17ea; IL_0d0a: if (!(text == "лайм")) { break; } goto IL_17db; IL_12de: if (!(text == "14")) { break; } goto IL_17ea; IL_12c9: if (!(text == "浅粉")) { break; } goto IL_17e5; end_IL_0038: break; } } if (!isHost && num == 18) { return byte.MaxValue; } bool flag = ((num < 0 || num > 18) ? true : false); return flag ? byte.MaxValue : Convert.ToByte(num); } public static void ShowHelpToClient(byte ID) { SendMessage(Translator.GetString("CommandList") + "\n ○ /n " + Translator.GetString("Command.now") + "\n ○ /r " + Translator.GetString("Command.roles") + "\n ○ /m " + Translator.GetString("Command.myrole") + "\n ○ /xf " + Translator.GetString("Command.solvecover") + "\n ○ /l " + Translator.GetString("Command.lastresult") + "\n ○ /win " + Translator.GetString("Command.winner") + "\n\n" + Translator.GetString("CommandOtherList") + "\n ○ /color " + Translator.GetString("Command.color") + "\n ○ /qt " + Translator.GetString("Command.quit") + "\n ○ /death " + Translator.GetString("Command.death") + "\n ○ /icons " + Translator.GetString("Command.iconinfo"), ID); } public static void ShowHelp(byte ID) { SendMessage(Translator.GetString("CommandList") + "\n ○ /n " + Translator.GetString("Command.now") + "\n ○ /r " + Translator.GetString("Command.roles") + "\n ○ /m " + Translator.GetString("Command.myrole") + "\n ○ /l " + Translator.GetString("Command.lastresult") + "\n ○ /win " + Translator.GetString("Command.winner") + "\n\n" + Translator.GetString("CommandOtherList") + "\n ○ /color " + Translator.GetString("Command.color") + "\n ○ /rn " + Translator.GetString("Command.rename") + "\n ○ /qt " + Translator.GetString("Command.quit") + "\n ○ /icons " + Translator.GetString("Command.iconinfo") + "\n ○ /death " + Translator.GetString("Command.death") + "\n\n" + Translator.GetString("CommandHostList") + "\n ○ /s " + Translator.GetString("Command.say") + "\n ○ /rn " + Translator.GetString("Command.rename") + "\n ○ /poll " + Translator.GetString("Command.Poll") + "\n ○ /xf " + Translator.GetString("Command.solvecover") + "\n ○ /mw " + Translator.GetString("Command.mw") + "\n ○ /kill " + Translator.GetString("Command.kill") + "\n ○ /exe " + Translator.GetString("Command.exe") + "\n ○ /level " + Translator.GetString("Command.level") + "\n ○ /id " + Translator.GetString("Command.idlist") + "\n ○ /qq " + Translator.GetString("Command.qq") + "\n ○ /dump " + Translator.GetString("Command.dump"), ID); } public static string[] SplitMessage(this string LongMsg) { List list = new List(); string[] array = LongMsg.Split('\n'); string text = string.Empty; string[] array2 = array; foreach (string text2 in array2) { if (text.Length + text2.Length < 1200) { text = text + text2 + "\n"; continue; } if (text.Length >= 1200) { list.AddRange(from x in text.Chunk(1200) select new string(x)); } else { list.Add(text); } text = text2 + "\n"; } if (text.Length > 0) { list.Add(text); } int i = 0; array2 = new string[list.Count]; foreach (string item in list) { array2[i] = item; i++; } return array2; } private static string TryRemove(this string text) { if (text.Length < 1200) { return string.Empty; } return text.Remove(0, 1200); } public static void SendSpesificMessage(string text, byte sendTo = byte.MaxValue, string title = "") { bool flag = true; if (text.Length > 1200 && !GetPlayerById(sendTo).IsModClient()) { string[] array = text.SplitMessage(); foreach (string input in array) { string title2 = (flag ? title : "."); string text2 = Regex.Replace(input, "^", ""); text2 += "."; if (text2.IndexOf("\n") <= 4) { string text3 = text2; int num = text2.IndexOf("\n") + 1; text2 = text3.Substring(num, text2.Length - num); } SendMessage(text2, sendTo, title2); flag = false; } } else { text += "."; if (text.IndexOf("\n") <= 4) { string text4 = text; int i = text.IndexOf("\n") + 1; text = text4.Substring(i, text.Length - i); } SendMessage(text, sendTo, title); } } public static void SendMessage(string text, byte sendTo = byte.MaxValue, string title = "", bool logforChatManager = false, bool noReplay = false, bool ShouldSplit = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } try { if (ShouldSplit && text.Length > 1200 && !GetPlayerById(sendTo).IsModClient()) { CollectionExtensions.Do((IEnumerable)text.SplitMessage(), (Action)delegate(string x) { SendMessage(x, sendTo, title); }); return; } } catch (Exception value) { Logger.Warn($"Error after try split the msg {text} at: {value}", "Utils.SendMessage.SplitMessage", escapeCRLF: true, 1406, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } if (!noReplay && GameStates.IsInGame) { ChatManager.AddSystemChatHistory(sendTo, text); } if (title == "") { title = "" + Translator.GetString("DefaultSystemMessageTitle") + ""; } if (!logforChatManager) { ChatManager.AddToHostMessage(text.RemoveHtmlTagsTemplate()); } Main.MessagesToSend.Add((text.RemoveHtmlTagsTemplate(), sendTo, title)); } public static bool IsPlayerModerator(string friendCode) { if (friendCode == "") { return false; } return File.ReadAllLines("./TOHE-DATA/Moderators.txt").Any((string code) => code.Contains(friendCode)); } public static bool IsPlayerVIP(string friendCode) { if (friendCode == "") { return false; } return File.ReadAllLines("./TOHE-DATA/VIP-List.txt").Any((string code) => code.Contains(friendCode)); } public static bool CheckColorHex(string ColorCode) { if (!new Regex("^[0-9A-Fa-f]{6}$").IsMatch(ColorCode)) { return false; } return true; } public static bool CheckGradientCode(string ColorCode) { if (!new Regex("^[0-9A-Fa-f]{6}\\s[0-9A-Fa-f]{6}$").IsMatch(ColorCode)) { return false; } return true; } public static string GradientColorText(string startColorHex, string endColorHex, string text) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if (startColorHex.Length != 6 || endColorHex.Length != 6) { Logger.Error("Invalid color hex code. Hex code should be 6 characters long (without #) (e.g., FFFFFF).", "GradientColorText", escapeCRLF: true, 1449, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); return text; } Color val = HexToColor(startColorHex); Color val2 = HexToColor(endColorHex); int length = text.Length; float num = (val2.r - val.r) / (float)length; float num2 = (val2.g - val.g) / (float)length; float num3 = (val2.b - val.b) / (float)length; float num4 = (val2.a - val.a) / (float)length; string text2 = ""; for (int i = 0; i < length; i++) { float num5 = val.r + num * (float)i; float num6 = val.g + num2 * (float)i; float num7 = val.b + num3 * (float)i; float num8 = val.a + num4 * (float)i; string value = ColorToHex(new Color(num5, num6, num7, num8)); text2 += $"{text[i]}"; } return text2; } private static Color HexToColor(string hex) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); ColorUtility.TryParseHtmlString("#" + hex, ref result); return result; } private static string ColorToHex(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Color32 val = Color32.op_Implicit(color); return $"{val.r:X2}{val.g:X2}{val.b:X2}{val.a:X2}"; } public static void ApplySuffix(PlayerControl player) { //IL_0a78: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (Object)(object)player == (Object)null || player.Data.DefaultOutfit.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= player.Data.DefaultOutfit.ColorId) { return; } if (Options.HideAllTagsAndText.GetBool()) { SetRealName(); return; } if (!((InnerNetObject)player).AmOwner && !player.FriendCode.GetDevUser().HasTag() && !IsPlayerModerator(player.FriendCode) && !IsPlayerVIP(player.FriendCode)) { SetRealName(); return; } string text = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out var value) ? value : ""); if (Main.HostRealName != "" && ((InnerNetObject)player).AmOwner) { text = Main.HostRealName; } if (text == "" || !GameStates.IsLobby) { return; } if (((InnerNetObject)player).AmOwner && player.IsModClient()) { if (GameStates.IsOnlineGame || GameStates.IsLocalGame) { text = (Options.HideHostText.GetBool() ? $"{text}" : $"{Translator.GetString("HostText")}{Translator.GetString("Icon")}{text}"); } if (Options.CurrentGameMode == CustomGameMode.FFA) { text = "" + Translator.GetString("ModeFFA") + "\r\n" + text; } } string text2 = ""; if (Options.ApplyVipList.GetValue() == 1 && player.FriendCode != PlayerControl.LocalPlayer.FriendCode && IsPlayerVIP(player.FriendCode)) { string path = "./TOHE-DATA/Tags/VIP_TAGS/" + player.FriendCode + ".txt"; if (!Options.GradientTagsOpt.GetBool()) { string value2 = "ffff00"; if (File.Exists(path)) { string text3 = File.ReadAllText(path); text3.Trim(); if (CheckColorHex(text3)) { value2 = text3; } } text2 = $"{Translator.GetString("VipTag")}"; } else { string text4 = "ffff00"; string text5 = "ffff00"; string text6 = ""; if (File.Exists(path)) { text6 = File.ReadAllText(path); if (text6.Split(" ").Length == 2) { text4 = text6.Split(" ")[0]; text5 = text6.Split(" ")[1]; } } if (!CheckGradientCode(text6)) { text4 = "ffff00"; text5 = "ffff00"; } text2 = ((!(text4 == text5)) ? GradientColorText(text4, text5, Translator.GetString("VipTag")) : $"{Translator.GetString("VipTag")}"); } } if (Options.ApplyModeratorList.GetValue() == 1 && player.FriendCode != PlayerControl.LocalPlayer.FriendCode && IsPlayerModerator(player.FriendCode)) { string path2 = "./TOHE-DATA/Tags/MOD_TAGS/" + player.FriendCode + ".txt"; if (!Options.GradientTagsOpt.GetBool()) { string value3 = "8bbee0"; if (File.Exists(path2)) { string text7 = File.ReadAllText(path2); text7.Trim(); if (CheckColorHex(text7)) { value3 = text7; } } text2 = $"{Translator.GetString("ModTag")}"; } else { string text8 = "8bbee0"; string text9 = "8bbee0"; string text10 = ""; if (File.Exists(path2)) { text10 = File.ReadAllText(path2); if (text10.Split(" ").Length == 2) { text8 = text10.Split(" ")[0]; text9 = text10.Split(" ")[1]; } } if (!CheckGradientCode(text10)) { text8 = "8bbee0"; text9 = "8bbee0"; } text2 = ((!(text8 == text9)) ? GradientColorText(text8, text9, Translator.GetString("ModTag")) : $"{Translator.GetString("ModTag")}"); } } if (((InnerNetObject)player).AmOwner) { text = Options.GetSuffixMode() switch { SuffixModes.TOHE => text += $"\r\nTOHE v{"2.0.3"}", SuffixModes.Streaming => text += $"\r\n{Translator.GetString("SuffixMode.Streaming")}", SuffixModes.Recording => text += $"\r\n{Translator.GetString("SuffixMode.Recording")}", SuffixModes.RoomHost => text += $"\r\n{Translator.GetString("SuffixMode.RoomHost")}", SuffixModes.OriginalName => text += $"\r\n{DataManager.player.Customization.Name}", SuffixModes.DoNotKillMe => text += $"\r\n{Translator.GetString("SuffixModeText.DoNotKillMe")}", SuffixModes.NoAndroidPlz => text += $"\r\n{Translator.GetString("SuffixModeText.NoAndroidPlz")}", SuffixModes.AutoHost => text += $"\r\n{Translator.GetString("SuffixModeText.AutoHost")}", _ => text, }; } text = ((text.Contains("\r\r") || !player.FriendCode.GetDevUser().HasTag() || (!((InnerNetObject)player).AmOwner && !player.IsModClient())) ? (text2 + text) : (player.FriendCode.GetDevUser().GetTag() + "" + text2 + "" + text)); if (text != ((Object)player).name && (int)player.CurrentOutfitType == 0) { player.RpcSetName(text); } void SetRealName() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) string value4; string text11 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value4) ? value4 : ""); if (GameStates.IsLobby && text11 != ((Object)player).name && (int)player.CurrentOutfitType == 0) { player.RpcSetName(text11); } } } public static bool CheckCamoflague(this PlayerControl PC) { bool value; if (!Camouflage.IsCamouflage && !Camouflager.AbilityActivated && !IsActive((SystemTypes)57)) { return Main.CheckShapeshift.TryGetValue(PC.PlayerId, out value) && value; } return true; } public static PlayerControl GetPlayerById(int PlayerId) { return ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl pc) => pc.PlayerId == PlayerId)); } public static List GetPlayerListByIds(this IEnumerable PlayerIdList) { List list = (from x in PlayerIdList?.ToList() select GetPlayerById(x)).ToList(); if (list == null || !list.Any()) { return null; } return list; } public static List GetPlayerListByRole(this CustomRoles role) { return (from x in Main.PlayerStates.Values where x.MainRole == role select x into r select r.PlayerId).GetPlayerListByIds(); } public static IEnumerable GetRoleBasesByType() where t : RoleBase { try { IEnumerable source = Main.PlayerStates.Values.Where((PlayerState x) => x.RoleClass != null); if (source.Any()) { IEnumerable source2 = source.Select((PlayerState x) => x.RoleClass); return source2.OfType().Any() ? source2.OfType() : null; } } catch (Exception ex) { Logger.Exception(ex, "Utils.GetRoleBasesByType", 1681, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } return null; } public static NetworkedPlayerInfo GetPlayerInfoById(int PlayerId) { return ((IEnumerable)GameData.Instance.AllPlayers.ToArray()).FirstOrDefault((Func)((NetworkedPlayerInfo info) => info.PlayerId == PlayerId)); } public static async void NotifyRoles(PlayerControl SpecifySeer = null, PlayerControl SpecifyTarget = null, bool isForMeeting = false, bool NoCache = false, bool ForceLoop = true, bool CamouflageIsForMeeting = false, bool MushroomMixupIsActive = false) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && !GameStates.IsHideNSeek && !OnPlayerLeftPatch.StartingProcessing && Main.AllPlayerControls != null && (!GameStates.IsMeeting || GameEndCheckerForNormal.ShowAllRolesWhenGameEnd)) { await DoNotifyRoles(SpecifySeer, SpecifyTarget, isForMeeting, NoCache, ForceLoop, CamouflageIsForMeeting, MushroomMixupIsActive); } } public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl SpecifyTarget = null, bool isForMeeting = false, bool NoCache = false, bool ForceLoop = true, bool CamouflageIsForMeeting = false, bool MushroomMixupIsActive = false) { //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Invalid comparison between Unknown and I4 //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_05ce: Unknown result type (might be due to invalid IL or missing references) //IL_05d3: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_078b: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_0963: Unknown result type (might be due to invalid IL or missing references) //IL_0968: Unknown result type (might be due to invalid IL or missing references) //IL_0811: Unknown result type (might be due to invalid IL or missing references) //IL_0816: Unknown result type (might be due to invalid IL or missing references) //IL_0840: Unknown result type (might be due to invalid IL or missing references) //IL_0845: Unknown result type (might be due to invalid IL or missing references) //IL_08e3: Unknown result type (might be due to invalid IL or missing references) //IL_08e8: Unknown result type (might be due to invalid IL or missing references) //IL_0909: Unknown result type (might be due to invalid IL or missing references) //IL_090e: Unknown result type (might be due to invalid IL or missing references) //IL_0c83: Unknown result type (might be due to invalid IL or missing references) //IL_0c88: Unknown result type (might be due to invalid IL or missing references) //IL_086c: Unknown result type (might be due to invalid IL or missing references) //IL_0871: Unknown result type (might be due to invalid IL or missing references) //IL_0c45: Unknown result type (might be due to invalid IL or missing references) //IL_0c4a: Unknown result type (might be due to invalid IL or missing references) //IL_0898: Unknown result type (might be due to invalid IL or missing references) //IL_089d: Unknown result type (might be due to invalid IL or missing references) //IL_0e8b: Unknown result type (might be due to invalid IL or missing references) //IL_0e90: Unknown result type (might be due to invalid IL or missing references) //IL_1109: Unknown result type (might be due to invalid IL or missing references) //IL_110e: Unknown result type (might be due to invalid IL or missing references) //IL_1043: Unknown result type (might be due to invalid IL or missing references) //IL_1048: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || GameStates.IsHideNSeek || OnPlayerLeftPatch.StartingProcessing) { return Task.CompletedTask; } if (Main.AllPlayerControls == null) { return Task.CompletedTask; } if (GameStates.IsMeeting && !GameEndCheckerForNormal.ShowAllRolesWhenGameEnd) { return Task.CompletedTask; } HudManagerPatch.NowCallNotifyRolesCount++; HudManagerPatch.LastSetNameDesyncCount = 0; PlayerControl[] array = (PlayerControl[])((!((Object)(object)SpecifySeer != (Object)null)) ? ((Array)Main.AllPlayerControls) : ((Array)new PlayerControl[1] { SpecifySeer })); PlayerControl[] array2 = (PlayerControl[])((!((Object)(object)SpecifyTarget != (Object)null)) ? ((Array)Main.AllPlayerControls) : ((Array)new PlayerControl[1] { SpecifyTarget })); if (!MushroomMixupIsActive) { MushroomMixupIsActive = IsActive((SystemTypes)57); } Logger.Info($" START - Count Seers: {array.Length} & Count Target: {array2.Length}", "DoNotifyRoles", escapeCRLF: true, 1734, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); PlayerControl[] array3 = array; foreach (PlayerControl val in array3) { if ((Object)(object)val == (Object)null || val.Data.Disconnected || val.IsModClient()) { continue; } if (SetUpRoleTextPatch.IsInIntro) { string value = "|"; string text = ""; string value2 = $"{value} {text}{ColorString(Color32.op_Implicit(GetTeamColor(val)), $"{val.GetCustomRole().GetCustomRoleTeam()}")} {value}\n \n\r\n"; string value3 = "" + text + ColorString(Color32.op_Implicit(val.GetRoleColor()), GetRoleName(val.GetCustomRole())) + ""; string text2 = string.Empty; string realName = val.GetRealName(); string text3 = ColorString(Color32.op_Implicit(val.GetRoleColor()), realName); string value4 = $"\n{text}{ColorString(Color32.op_Implicit(val.GetRoleColor()), val.GetRoleInfo())}"; string text4 = "\n\n"; if (!val.GetCustomRole().IsDesyncRole()) { value2 = string.Empty; text4 = "\n"; value4 = $"\n{text}{ColorString(Color32.op_Implicit(val.GetRoleColor()), val.GetRoleInfo())}"; } bool flag = true; CustomRoles[] array4 = val.GetCustomSubRoles().ToArray(); foreach (CustomRoles customRoles in array4) { if (flag) { text2 = text2 + "\n" + text + ColorString(Color32.op_Implicit(GetRoleColor(customRoles)), Translator.GetString($"{customRoles}")) + ""; text4 += "\n"; } else { text2 += $" {text}{ColorString(Color32.op_Implicit(Color.white), "+")} {ColorString(Color32.op_Implicit(GetRoleColor(customRoles)), Translator.GetString($"{customRoles}"))}"; } flag = false; } text3 = $"{value2}{value3}{text2}\r\n{value4}{text4}"; val.RpcSetNamePrivate(text3, val); continue; } string value5 = (isForMeeting ? "1.6" : "1.8"); bool flag2 = isForMeeting; if (flag2) { Platforms platform = val.GetClient().PlatformData.Platform; bool flag3 = platform - 8 <= 2; flag2 = flag3; } if (flag2) { value5 = "70%"; } CustomRoles customRole = val.GetCustomRole(); RoleBase roleClass = val.GetRoleClass(); if (!CamouflageIsForMeeting && MushroomMixupIsActive && val.IsAlive() && !val.Is(Custom_Team.Impostor) && Main.ResetCamPlayerList.Contains(val.PlayerId)) { val.RpcSetNamePrivate("", null, NoCache); } else { SelfMark.Clear(); SelfMark.Append(roleClass?.GetMark(val, val, isForMeeting)); SelfMark.Append(CustomRoleManager.GetMarkOthers(val, val, isForMeeting)); if (val.Is(CustomRoles.Lovers)) { SelfMark.Append(ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Lovers)), "♥")); } if (val.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) { SelfMark.Append(ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Cyber)), "★")); } SelfSuffix.Clear(); SelfSuffix.Append(roleClass?.GetLowerText(val, val, isForMeeting)); SelfSuffix.Append(CustomRoleManager.GetLowerTextOthers(val, val, isForMeeting)); if (Radar.IsEnable) { SelfSuffix.Append(Radar.GetPlayerArrow(val, null, isForMeeting)); } SelfSuffix.Append(roleClass?.GetSuffix(val, val, isForMeeting)); SelfSuffix.Append(CustomRoleManager.GetSuffixOthers(val, val, isForMeeting)); if (Options.CurrentGameMode == CustomGameMode.FFA) { SelfSuffix.Append(FFAManager.GetPlayerArrow(val)); } string realName2 = val.GetRealName(isForMeeting); string progressText = GetProgressText(val); string text5 = $"{val.GetDisplayRoleAndSubName(val)}{progressText}"; string value6 = (val.KnowDeathReason(val) ? (" (" + ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Doctor)), GetVitalText(val.PlayerId)) + ")") : string.Empty); string name = $"{ColorString(Color32.op_Implicit(val.GetRoleColor()), realName2)}{value6}{SelfMark}"; bool flag4 = false; if (MeetingStates.FirstMeeting && Options.ChangeNameToRoleInfo.GetBool() && !isForMeeting && Options.CurrentGameMode != CustomGameMode.FFA) { flag4 = true; val.GetRoleInfo(); string str = string.Empty; string value7 = ""; if (customRole.IsImpostor()) { str = ColorString(Color32.op_Implicit(GetTeamColor(val)), Translator.GetString("TeamImpostor")); } else if (customRole.IsCrewmate()) { str = ColorString(Color32.op_Implicit(GetTeamColor(val)), Translator.GetString("TeamCrewmate")); } else if (customRole.IsNeutral()) { str = ColorString(Color32.op_Implicit(GetTeamColor(val)), Translator.GetString("TeamNeutral")); } else if (customRole.IsMadmate()) { str = ColorString(Color32.op_Implicit(GetTeamColor(val)), Translator.GetString("TeamMadmate")); } name = $"{name}\n \n{value7}{ColorString(Color32.op_Implicit(val.GetRoleColor()), str)}\n{ColorString(Color32.op_Implicit(val.GetRoleColor()), val.GetRoleInfo())}\n"; } if (NameNotifyManager.GetNameNotify(val, out var name2)) { name = name2; } if (Pelican.HasEnabled && Pelican.IsEaten(val.PlayerId)) { name = ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Pelican)), Translator.GetString("EatenByPelican")) ?? ""; } if (CustomRoles.Deathpact.HasEnabled() && Deathpact.IsInActiveDeathpact(val)) { name = Deathpact.GetDeathpactString(val); } if (CustomRoles.Devourer.HasEnabled() && Devourer.HideNameOfTheDevoured(val.PlayerId) && !CamouflageIsForMeeting) { name = Translator.GetString("DevouredName"); } if (CustomRoles.DollMaster.HasEnabled() && customRole != CustomRoles.DollMaster && DollMaster.IsDoll(val.PlayerId)) { name = "■"; } if (!CamouflageIsForMeeting && Camouflage.IsCamouflage) { name = "" + name + ""; } if (!Regex.IsMatch(name, val.GetRealName())) { flag4 = false; } if (Options.CurrentGameMode != CustomGameMode.FFA) { name = (flag4 ? ("\n \n" + text5 + "\r\n" + name) : (text5 + "\r\n" + name)); } else { FFAManager.GetNameNotify(val, ref name); name = $"{progressText}\r\n{name}"; } name += ((SelfSuffix.Length == 0) ? string.Empty : ("\r\n " + SelfSuffix.ToString())); if (!isForMeeting) { name += "\r\n"; } val.RpcSetNamePrivate(name, null, NoCache); } if (!ForceLoop || !(val.Data.IsDead || !val.IsAlive() || array.Length == 1 || array2.Length == 1 || MushroomMixupIsActive || NoCache || ForceLoop)) { continue; } PlayerControl[] array5 = array2; foreach (PlayerControl val2 in array5) { if (val2.PlayerId == val.PlayerId) { continue; } PlayerControl val3 = val2; if ((Object)(object)val != (Object)(object)val3 && (Object)(object)val != (Object)(object)DollMaster.DollMasterTarget) { val3 = DollMaster.SwapPlayerInfo(val2); } if (!CamouflageIsForMeeting && MushroomMixupIsActive && val3.IsAlive() && !val.Is(Custom_Team.Impostor) && Main.ResetCamPlayerList.Contains(val.PlayerId)) { val2.RpcSetNamePrivate("", val, NoCache); continue; } TargetMark.Clear(); TargetMark.Append(roleClass?.GetMark(val, val3, isForMeeting)); TargetMark.Append(CustomRoleManager.GetMarkOthers(val, val3, isForMeeting)); if (val.Is(Custom_Team.Impostor) && val3.Is(CustomRoles.Snitch) && val3.Is(CustomRoles.Madmate) && val3.GetPlayerTaskState().IsTaskFinished) { TargetMark.Append(ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Impostor)), "★")); } if (val3.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) { TargetMark.Append(ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Cyber)), "★")); } if (val.Is(CustomRoles.Lovers) && val3.Is(CustomRoles.Lovers)) { StringBuilder targetMark = TargetMark; StringBuilder stringBuilder = targetMark; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, targetMark); handler.AppendLiteral("♥"); stringBuilder.Append(ref handler); } else if (val.Data.IsDead && !val.Is(CustomRoles.Lovers) && val3.Is(CustomRoles.Lovers)) { StringBuilder targetMark = TargetMark; StringBuilder stringBuilder2 = targetMark; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, targetMark); handler.AppendLiteral("♥"); stringBuilder2.Append(ref handler); } string value8 = (ExtendedPlayerControl.KnowRoleTarget(val, val3, isVanilla: true) ? $"{val.GetDisplayRoleAndSubName(val3)}{GetProgressText(val3)}\r\n" : ""); if (val.IsAlive() && Overseer.IsRevealedPlayer(val, val3) && val3.Is(CustomRoles.Trickster)) { value8 = Overseer.GetRandomRole(val.PlayerId); value8 += TaskState.GetTaskState(); } string text6 = val3.GetRealName(isForMeeting); string text7 = val.GetRoleClass()?.NotifyPlayerName(val, val3, text6, isForMeeting); if (text7 != string.Empty) { text6 = text7; } if (isForMeeting) { if (Options.GuesserMode.GetBool()) { if (val.IsAlive() && val3.IsAlive()) { string text8 = ColorString(Color32.op_Implicit(GetRoleColor(val.GetCustomRole())), val3.PlayerId.ToString()) + " " + text6; if (Options.CrewmatesCanGuess.GetBool() && val.GetCustomRole().IsCrewmate() && !val.Is(CustomRoles.Judge) && !val.Is(CustomRoles.Inspector) && !val.Is(CustomRoles.Lookout) && !val.Is(CustomRoles.Swapper)) { text6 = text8; } else if (val.Is(CustomRoles.NiceGuesser) && !Options.CrewmatesCanGuess.GetBool()) { text6 = text8; } if (Options.ImpostorsCanGuess.GetBool() && (val.GetCustomRole().IsImpostor() || val.GetCustomRole().IsMadmate()) && !val.Is(CustomRoles.Councillor) && !val.Is(CustomRoles.Nemesis)) { text6 = text8; } else if (val.Is(CustomRoles.EvilGuesser) && !Options.ImpostorsCanGuess.GetBool()) { text6 = text8; } if (Options.NeutralKillersCanGuess.GetBool() && val.GetCustomRole().IsNK()) { text6 = text8; } if (Options.PassiveNeutralsCanGuess.GetBool() && val.GetCustomRole().IsNonNK() && !val.Is(CustomRoles.Doomsayer)) { text6 = text8; } } } else if (val.IsAlive() && val3.IsAlive() && (val.Is(CustomRoles.NiceGuesser) || val.Is(CustomRoles.EvilGuesser) || (val.Is(CustomRoles.Guesser) && !val.Is(CustomRoles.Inspector) && !val.Is(CustomRoles.Swapper) && !val.Is(CustomRoles.Lookout)))) { text6 = ColorString(Color32.op_Implicit(GetRoleColor(val.GetCustomRole())), val3.PlayerId.ToString()) + " " + text6; } } text6 = text6.ApplyNameColorData(val, val3, isForMeeting); TargetSuffix.Clear(); TargetSuffix.Append(CustomRoleManager.GetLowerTextOthers(val, val3, isForMeeting)); TargetSuffix.Append(roleClass?.GetSuffix(val, val3, isForMeeting)); TargetSuffix.Append(CustomRoleManager.GetSuffixOthers(val, val3, isForMeeting)); if (TargetSuffix.Length > 0) { TargetSuffix.Insert(0, "\r\n"); } string value9 = (val.KnowDeathReason(val3) ? (" (" + ColorString(Color32.op_Implicit(GetRoleColor(CustomRoles.Doctor)), GetVitalText(val3.PlayerId)) + ")") : string.Empty); if (CustomRoles.Devourer.HasEnabled() && Devourer.HideNameOfTheDevoured(val3.PlayerId) && !CamouflageIsForMeeting) { text6 = Translator.GetString("DevouredName"); } if (!CamouflageIsForMeeting && Camouflage.IsCamouflage) { text6 = "" + text6 + ""; } string name3 = $"{value8}{text6}{value9}{TargetMark}{TargetSuffix}"; val2.RpcSetNamePrivate(name3, val, NoCache); } } Logger.Info(" END", "DoNotifyRoles", escapeCRLF: true, 2095, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); return Task.CompletedTask; static int GetInfoSize(string RoleInfo) { RoleInfo = Regex.Replace(RoleInfo, "<[^>]*>", ""); RoleInfo = Regex.Replace(RoleInfo, "{[^}]*}", ""); int num = 200; int num2 = 100; num -= 3 * RoleInfo.Length; if (num < num2) { num = num2; } return num; } } public static void MarkEveryoneDirtySettings() { PlayerGameOptionsSender.SetDirtyToAll(); } public static void SyncAllSettings() { PlayerGameOptionsSender.SetDirtyToAll(); GameOptionsSender.SendAllGameOptions(); } public static bool DeathReasonIsEnable(this PlayerState.DeathReason reason, bool checkbanned = false) { if (checkbanned) { return !BannedReason(reason); } return reason switch { PlayerState.DeathReason.Eaten => CustomRoles.Pelican.IsEnable(), PlayerState.DeathReason.Spell => CustomRoles.Witch.IsEnable(), PlayerState.DeathReason.Hex => CustomRoles.HexMaster.IsEnable(), PlayerState.DeathReason.Curse => CustomRoles.CursedWolf.IsEnable(), PlayerState.DeathReason.Jinx => CustomRoles.Jinx.IsEnable(), PlayerState.DeathReason.Shattered => CustomRoles.Fragile.IsEnable(), PlayerState.DeathReason.Bite => CustomRoles.Vampire.IsEnable(), PlayerState.DeathReason.Poison => CustomRoles.Poisoner.IsEnable(), PlayerState.DeathReason.Bombed => CustomRoles.Bomber.IsEnable() || CustomRoles.Burst.IsEnable() || CustomRoles.Trapster.IsEnable() || CustomRoles.Fireworker.IsEnable() || CustomRoles.Bastion.IsEnable(), PlayerState.DeathReason.Misfire => CustomRoles.ChiefOfPolice.IsEnable() || CustomRoles.Sheriff.IsEnable() || CustomRoles.Reverie.IsEnable() || CustomRoles.Sheriff.IsEnable() || CustomRoles.Fireworker.IsEnable() || CustomRoles.Hater.IsEnable() || CustomRoles.Pursuer.IsEnable() || CustomRoles.Romantic.IsEnable(), PlayerState.DeathReason.Torched => CustomRoles.Arsonist.IsEnable(), PlayerState.DeathReason.Sniped => CustomRoles.Sniper.IsEnable(), PlayerState.DeathReason.Revenge => CustomRoles.Avanger.IsEnable() || CustomRoles.Retributionist.IsEnable() || CustomRoles.Nemesis.IsEnable() || CustomRoles.Randomizer.IsEnable(), PlayerState.DeathReason.Quantization => CustomRoles.Lightning.IsEnable(), PlayerState.DeathReason.Ashamed => CustomRoles.Workaholic.IsEnable(), PlayerState.DeathReason.PissedOff => CustomRoles.Pestilence.IsEnable() || CustomRoles.Provocateur.IsEnable(), PlayerState.DeathReason.Dismembered => CustomRoles.Butcher.IsEnable(), PlayerState.DeathReason.LossOfHead => CustomRoles.Hangman.IsEnable(), PlayerState.DeathReason.Trialed => CustomRoles.Judge.IsEnable() || CustomRoles.Councillor.IsEnable(), PlayerState.DeathReason.Infected => CustomRoles.Infectious.IsEnable(), PlayerState.DeathReason.Hack => CustomRoles.Glitch.IsEnable(), PlayerState.DeathReason.Pirate => CustomRoles.Pirate.IsEnable(), PlayerState.DeathReason.Shrouded => CustomRoles.Shroud.IsEnable(), PlayerState.DeathReason.Mauled => CustomRoles.Werewolf.IsEnable(), PlayerState.DeathReason.Suicide => CustomRoles.Unlucky.IsEnable() || CustomRoles.Ghoul.IsEnable() || CustomRoles.Terrorist.IsEnable() || CustomRoles.Dictator.IsEnable() || CustomRoles.Addict.IsEnable() || CustomRoles.Mercenary.IsEnable() || CustomRoles.Mastermind.IsEnable() || CustomRoles.Deathpact.IsEnable(), PlayerState.DeathReason.FollowingSuicide => CustomRoles.Lovers.IsEnable(), PlayerState.DeathReason.Execution => CustomRoles.Jailer.IsEnable(), PlayerState.DeathReason.Fall => Options.LadderDeath.GetBool(), PlayerState.DeathReason.Sacrifice => CustomRoles.Bodyguard.IsEnable() || CustomRoles.Revolutionist.IsEnable() || CustomRoles.Hater.IsEnable(), PlayerState.DeathReason.Drained => CustomRoles.Puppeteer.IsEnable(), PlayerState.DeathReason.Trap => CustomRoles.Trapster.IsEnable(), PlayerState.DeathReason.Targeted => CustomRoles.Kamikaze.IsEnable(), PlayerState.DeathReason.Retribution => CustomRoles.Instigator.IsEnable(), PlayerState.DeathReason.WrongAnswer => CustomRoles.Quizmaster.IsEnable(), _ => !BannedReason(reason) && reason switch { PlayerState.DeathReason.Slice => CustomRoles.Hawk.IsEnable(), PlayerState.DeathReason.BloodLet => CustomRoles.Bloodmoon.IsEnable(), PlayerState.DeathReason.Kill => true, _ => true, }, }; static bool BannedReason(PlayerState.DeathReason rso) { switch (rso) { case PlayerState.DeathReason.etc: case PlayerState.DeathReason.Vote: case PlayerState.DeathReason.Gambled: case PlayerState.DeathReason.Overtired: return true; default: return false; } } } public static void AfterMeetingTasks() { ChatManager.ClearLastSysMsg(); if (Diseased.IsEnable) { Diseased.AfterMeetingTasks(); } if (Antidote.IsEnable) { Antidote.AfterMeetingTasks(); } AntiBlackout.AfterMeetingTasks(); PlayerState[] array = Main.PlayerStates.Values.ToArray(); for (int i = 0; i < array.Length; i++) { array[i].RoleClass?.AfterMeetingTasks(); } PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; for (int i = 0; i < allAlivePlayerControls.Length; i++) { allAlivePlayerControls[i].SetKillTimer(); } if (LateExileTask.Any()) { CollectionExtensions.Do>((IEnumerable>)LateExileTask, (Action>)delegate(Action t) { t(obj: true); }); LateExileTask.Clear(); } if (Statue.IsEnable) { Statue.AfterMeetingTasks(); } if (Burst.IsEnable) { Burst.AfterMeetingTasks(); } if (CustomRoles.CopyCat.HasEnabled()) { CopyCat.UnAfterMeetingTasks(); } if (Options.AirshipVariableElectrical.GetBool()) { AirshipElectricalDoors.Initialize(); } DoorsReset.ResetDoors(); ISystemType val = default(ISystemType); VentilationSystem val2 = (ShipStatus.Instance.Systems.TryGetValue((SystemTypes)37, ref val) ? ((Il2CppObjectBase)val).TryCast() : null); if (val2 != null) { val2.PlayersInsideVents.Clear(); val2.IsDirty = true; } } public static void ChangeInt(ref int ChangeTo, int input, int max) { int num = ChangeTo * 10; num += input; ChangeTo = Math.Clamp(num, 0, max); } public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = false) { int num = Main.AllAlivePlayerControls.Count((PlayerControl pc) => pc.Is(Custom_Team.Impostor)); if (Main.AliveImpostorCount != num) { Logger.Info("Number Impostor left: " + num, "CountAliveImpostors", escapeCRLF: true, 2227, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); Main.AliveImpostorCount = num; LastImpostor.SetSubRole(); } if (sendLog) { StringBuilder stringBuilder = new StringBuilder(100); StringBuilder stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler; if (Options.CurrentGameMode != CustomGameMode.FFA) { CountTypes[] allValues = EnumHelper.GetAllValues(); foreach (CountTypes countTypes in allValues) { int num2 = PlayersCount(countTypes); if (num2 != 0) { stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(4, 3, stringBuilder2); handler.AppendFormatted(countTypes); handler.AppendLiteral(":"); handler.AppendFormatted(AlivePlayersCount(countTypes)); handler.AppendLiteral("/"); handler.AppendFormatted(num2); handler.AppendLiteral(", "); stringBuilder3.Append(ref handler); } } } stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(5, 2, stringBuilder2); handler.AppendLiteral("All:"); handler.AppendFormatted(AllAlivePlayersCount); handler.AppendLiteral("/"); handler.AppendFormatted(AllPlayersCount); stringBuilder4.Append(ref handler); Logger.Info(stringBuilder.ToString(), "CountAlivePlayers", escapeCRLF: true, 2245, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } if (((InnerNetClient)AmongUsClient.Instance).AmHost && checkGameEnd) { GameEndCheckerForNormal.Prefix(); } } public static string GetVoteName(byte num) { string result = "invalid"; PlayerControl playerById = GetPlayerById(num); int num2 = Main.AllPlayerControls.Length; if (num < num2 && (Object)(object)playerById != (Object)null) { result = playerById?.GetNameWithRole(); } if (num == 252) { result = "Dead"; } if (num == 253) { result = "Skip"; } if (num == 254) { result = "MissedVote"; } if (num == byte.MaxValue) { result = "HasNotVoted"; } return result; } public static string PadRightV2(this object text, int num) { int num2 = 0; string text2 = text.ToString(); string text3 = text2; foreach (char c in text3) { num2 += ((Encoding.GetEncoding("UTF-8").GetByteCount(c.ToString()) == 1) ? 1 : 2); } return text2?.PadRight(Mathf.Max(num - (num2 - text2.Length), 0)); } public static void DumpLog() { string text = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "/TOHE-logs/"; string value = DateTime.Now.ToString("yyyy-MM-dd_HH.mm.ss"); string text2 = $"{text}TOHE-v{"2024.0813.203.9999"}-{value}.log"; if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } new FileInfo(Environment.CurrentDirectory + "/BepInEx/LogOutput.log").CopyTo(text2); if ((Object)(object)PlayerControl.LocalPlayer != (Object)null) { HudManager instance = DestroyableSingleton.Instance; if (instance != null) { ChatController chat = instance.Chat; if (chat != null) { chat.AddChat(PlayerControl.LocalPlayer, string.Format(Translator.GetString("Message.DumpfileSaved"), $"TOHE - v{"2024.0813.203.9999"}-{value}.log"), true); } } } SendMessage(string.Format(Translator.GetString("Message.DumpcmdUsed"), PlayerControl.LocalPlayer.GetNameWithRole())); Process.Start(new ProcessStartInfo("Explorer.exe") { Arguments = "/e,/select," + text2.Replace("/", "\\") }); } public static string SummaryTexts(byte id, bool disableColor = true, bool check = false) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) string text = Main.AllPlayerNames[id].RemoveHtmlTags().Replace("\r\n", string.Empty); if (id == PlayerControl.LocalPlayer.PlayerId) { text = DataManager.player.Customization.Name; } else { PlayerControl playerById = GetPlayerById(id); text = ((playerById != null) ? playerById.Data.PlayerName : null) ?? text; } TaskState taskState = Main.PlayerStates?[id].TaskState; Main.PlayerStates.TryGetValue(id, out var value); string value2; if (taskState.hasTasks) { Color green = Color.green; Color val = ((taskState.CompletedTasksCount > 0) ? Color.yellow : Color.white); if (Workhorse.IsThisRole(id)) { val = Workhorse.RoleColor; } Color val2 = (taskState.IsTaskFinished ? green : val); if (value.MainRole == CustomRoles.Crewpostor) { val2 = Color.red; } if (value.SubRoles.Contains(CustomRoles.Workhorse)) { GetRoleColor(value.MainRole).ShadeColor(0.5f); } value2 = ColorString(Color32.op_Implicit(val2), $" ({taskState.CompletedTasksCount}/{taskState.AllTasksCount})"); } else { value2 = GetProgressText(id); } string value3 = ((value.deathReason != PlayerState.DeathReason.etc && value.Disconnected) ? ("(" + Translator.GetString("Disconnected") + ")") : string.Empty); string text2 = $"{ColorString(Main.PlayerColors[id], text)} - {GetDisplayRoleAndSubName(id, id, notShowAddOns: true)}{GetSubRolesText(id, disableColor: false, intro: false, summary: true)}{value2} {GetKillCountText(id)} 『{GetVitalText(id, RealKillerColor: true)}』{value3}"; if (Options.CurrentGameMode == CustomGameMode.FFA) { text2 = ColorString(Main.PlayerColors[id], text) + " " + GetKillCountText(id, ffa: true); } if (!check || !GetDisplayRoleAndSubName(id, id, notShowAddOns: true).RemoveHtmlTags().Contains("INVALID:NotAssigned")) { if (!disableColor) { return text2; } return text2.RemoveHtmlTags(); } return "INVALID"; } public static string RemoveHtmlTagsTemplate(this string str) { return Regex.Replace(str, "", ""); } public static string RemoveHtmlTags(this string str) { return Regex.Replace(str, "<[^>]*?>", ""); } public static string RemoveHtmlTagsIfNeccessary(this string str) { if (str.Replace(".Instance; if (!((Object)(object)instance.FullScreen == (Object)null)) { Transform obj2 = ((Component)instance).transform.FindChild("FlashColor_FullScreen"); GameObject obj = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)obj == (Object)null) { obj = Object.Instantiate(((Component)instance.FullScreen).gameObject, ((Component)instance).transform); ((Object)obj).name = "FlashColor_FullScreen"; } ((MonoBehaviour)instance).StartCoroutine(Effects.Lerp(duration, Action.op_Implicit((Action)delegate(float t) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) obj.SetActive(t != 1f); obj.GetComponent().color = new Color(color.r, color.g, color.b, Mathf.Clamp01((-2f * Mathf.Abs(t - 0.5f) + 1f) * color.a / 2f)); }))); } } public static Sprite LoadSprite(string path, float pixelsPerUnit = 1f) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) try { if (CachedSprites.TryGetValue(path + pixelsPerUnit, out var value)) { return value; } Texture2D val = LoadTextureFromResources(path); value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), pixelsPerUnit); Sprite obj = value; ((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x3D); return CachedSprites[path + pixelsPerUnit] = value; } catch { Logger.Error("Failed to read Texture: " + path, "LoadSprite", escapeCRLF: true, 2373, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } return null; } public static Texture2D LoadTextureFromResources(string path) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown try { Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path); Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false); using MemoryStream memoryStream = new MemoryStream(); manifestResourceStream.CopyTo(memoryStream); ImageConversion.LoadImage(val, Il2CppStructArray.op_Implicit(memoryStream.ToArray()), false); return val; } catch { Logger.Error("Failed to read Texture: " + path, "LoadTextureFromResources", escapeCRLF: true, 2390, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\Utils.cs"); } return null; } public static string ColorString(Color32 color, string str) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) return $"{str}"; } public static string ColorStringWithoutEnding(Color32 color, string str) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) return $"{str}"; } public static Color ShadeColor(this Color color, float Darkness = 0f) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) bool num = Darkness >= 0f; if (!num) { Darkness = 0f - Darkness; } float num2 = (num ? 0f : Darkness); float num3 = (color.r + num2) / (Darkness + 1f); float num4 = (color.g + num2) / (Darkness + 1f); float num5 = (color.b + num2) / (Darkness + 1f); return new Color(num3, num4, num5, color.a); } public static void SetChatVisibleForEveryone() { if (GameStates.IsInGame && ((InnerNetClient)AmongUsClient.Instance).AmHost) { MeetingHud.Instance = Object.Instantiate(DestroyableSingleton.Instance.MeetingPrefab); MeetingHud.Instance.ServerStart(PlayerControl.LocalPlayer.PlayerId); ((InnerNetClient)AmongUsClient.Instance).Spawn((InnerNetObject)(object)MeetingHud.Instance, -2, (SpawnFlags)0); MeetingHud.Instance.RpcClose(); } } public static void SetChatVisibleSpecific(this PlayerControl player) { if (GameStates.IsInGame && ((InnerNetClient)AmongUsClient.Instance).AmHost && !GameStates.IsMeeting) { if (((InnerNetObject)player).AmOwner) { DestroyableSingleton.Instance.Chat.SetVisible(true); return; } if (player.IsModClient()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)126, (SendOption)1, ((InnerNetObject)player).OwnerId); val.WritePacked(((InnerNetObject)player).OwnerId); val.Write(true); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); return; } AmongUsClient instance = AmongUsClient.Instance; uint netIdCnt = ((InnerNetClient)instance).NetIdCnt; ((InnerNetClient)instance).NetIdCnt = netIdCnt + 1; uint num = netIdCnt; MessageWriter val2 = MessageWriter.Get((SendOption)1); val2.StartMessage((byte)6); val2.Write(((InnerNetClient)AmongUsClient.Instance).GameId); val2.Write(((InnerNetObject)player).OwnerId); val2.StartMessage((byte)4); val2.WritePacked(1); val2.WritePacked(-2); val2.Write((byte)0); val2.WritePacked(1); val2.WritePacked(num); val2.StartMessage((byte)1); val2.WritePacked(0); val2.EndMessage(); val2.EndMessage(); val2.EndMessage(); val2.StartMessage((byte)6); val2.Write(((InnerNetClient)AmongUsClient.Instance).GameId); val2.Write(((InnerNetObject)player).OwnerId); val2.StartMessage((byte)2); val2.WritePacked(num); val2.Write((byte)22); val2.EndMessage(); val2.EndMessage(); ((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(val2); val2.Recycle(); } } public static int PlayersCount(CountTypes countTypes) { return Main.PlayerStates.Values.Count((PlayerState state) => state.countTypes == countTypes); } public static int AlivePlayersCount(CountTypes countTypes) { return Main.AllAlivePlayerControls.Count((PlayerControl pc) => pc.Is(countTypes)); } } [HarmonyPatch(typeof(HudManager), "Update")] public static class Zoom { private static bool ResetButtons; public static void Postfix() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if ((GameStates.IsShip && !GameStates.IsMeeting && GameStates.IsCanMove && PlayerControl.LocalPlayer.Data.IsDead) || (GameStates.IsLobby && GameStates.IsCanMove)) { if (Camera.main.orthographicSize > 3f) { ResetButtons = true; } if (Input.mouseScrollDelta.y > 0f && Camera.main.orthographicSize > 3f) { SetZoomSize(); } if (Input.mouseScrollDelta.y < 0f && (GameStates.IsDead || GameStates.IsFreePlay || DebugModeManager.AmDebugger || GameStates.IsLobby || PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) && Camera.main.orthographicSize < 18f) { SetZoomSize(times: true); } Flag.NewFlag("Zoom"); } else { Flag.Run(delegate { SetZoomSize(times: false, reset: true); }, "Zoom"); } } private static void SetZoomSize(bool times = false, bool reset = false) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) float num = 1.5f; if (!times) { num = 1f / num; } if (reset) { Camera.main.orthographicSize = 3f; DestroyableSingleton.Instance.UICamera.orthographicSize = 3f; ((Component)DestroyableSingleton.Instance.Chat).transform.localScale = Vector3.one; if (GameStates.IsMeeting) { ((Component)MeetingHud.Instance).transform.localScale = Vector3.one; } } else { Camera main = Camera.main; main.orthographicSize *= num; Camera uICamera = DestroyableSingleton.Instance.UICamera; uICamera.orthographicSize *= num; } HudManager instance = DestroyableSingleton.Instance; if (instance != null) { MeshRenderer shadowQuad = instance.ShadowQuad; if (shadowQuad != null) { GameObject gameObject = ((Component)shadowQuad).gameObject; if (gameObject != null) { gameObject.SetActive((reset || Camera.main.orthographicSize == 3f) && PlayerControl.LocalPlayer.IsAlive()); } } } if (ResetButtons) { ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / (float)Screen.height, Screen.width, Screen.height, Screen.fullScreen); ResetButtons = false; } } public static void OnFixedUpdate() { HudManager instance = DestroyableSingleton.Instance; if (instance == null) { return; } MeshRenderer shadowQuad = instance.ShadowQuad; if (shadowQuad != null) { GameObject gameObject = ((Component)shadowQuad).gameObject; if (gameObject != null) { gameObject.SetActive(Camera.main.orthographicSize == 3f && PlayerControl.LocalPlayer.IsAlive()); } } } } public static class Flag { private static List OneTimeList = new List(); private static List FirstRunList = new List(); public static void Run(Action action, string type, bool firstrun = false) { if (OneTimeList.Contains(type) || (firstrun && !FirstRunList.Contains(type))) { if (!FirstRunList.Contains(type)) { FirstRunList.Add(type); } OneTimeList.Remove(type); action(); } } public static void NewFlag(string type) { if (!OneTimeList.Contains(type)) { OneTimeList.Add(type); } } public static void DeleteFlag(string type) { if (OneTimeList.Contains(type)) { OneTimeList.Remove(type); } } } public class AirshipElectricalDoors { private static ElectricalDoors Instance => ((Il2CppObjectBase)ShipStatus.Instance.Systems[(SystemTypes)18]).Cast(); public static void Initialize() { if (GameStates.AirshipIsActive) { Instance.Initialize(); } } public static byte[] GetClosedDoors() { List list = new List(); if (Instance.Doors == null || ((Il2CppArrayBase)(object)Instance.Doors).Count == 0) { int num = 0; byte[] array = new byte[list.Count]; { foreach (byte item in list) { array[num] = item; num++; } return array; } } for (byte b = 0; b < ((Il2CppArrayBase)(object)Instance.Doors).Count; b++) { StaticDoor val = ((Il2CppArrayBase)(object)Instance.Doors)[(int)b]; if ((Object)(object)val != (Object)null && !val.IsOpen) { list.Add(b); } } return list?.ToArray(); } } [HarmonyPatch(typeof(ElectricalDoors), "Initialize")] internal class ElectricalDoorsInitializePatch { public static void Postfix() { if (!GameStates.IsInGame) { return; } string text = ""; bool flag = true; byte[] closedDoors = AirshipElectricalDoors.GetClosedDoors(); for (int i = 0; i < closedDoors.Length; i++) { byte value = closedDoors[i]; if (flag) { flag = false; text += value; } else { text += $", {value}"; } } Logger.Info("ClosedDoors:" + text, "ElectricalDoors Initialize", escapeCRLF: true, 56, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\AirShipElectricalDoors.cs"); } } [HarmonyPatch(typeof(AirshipStatus), "PrespawnStep")] public static class AirshipStatusPrespawnStepPatch { public static bool Prefix() { if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) { RandomSpawn.AirshipSpawn(PlayerControl.LocalPlayer); return false; } return true; } } [HarmonyPatch] public class ModNews { public int Number; public int BeforeNumber; public string Title; public string SubTitle; public string ShortTitle; public string Text; public string Date; public static List AllModNews = new List(); public static string ModNewsURL = "https://raw.githubusercontent.com/0xDrMoe/TownofHost-Enhanced/main/Resources/Announcements/modNews-"; private static bool downloaded = false; public Announcement ToAnnouncement() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected I4, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown return new Announcement { Number = Number, Title = Title, SubTitle = SubTitle, ShortTitle = ShortTitle, Text = Text, Language = (uint)(int)DataManager.Settings.Language.CurrentLanguage, Date = Date, Id = "ModNews" }; } public ModNews(int Number, string Title, string SubTitle, string ShortTitle, string Text, string Date) { this.Number = Number; this.Title = Title; this.SubTitle = SubTitle; this.ShortTitle = ShortTitle; this.Text = Text; this.Date = Date; AllModNews.Add(this); } [HarmonyPatch(typeof(AnnouncementPopUp), "Init")] [HarmonyPostfix] public static void Initialize_Postfix(ref IEnumerator __result) { __result = Effects.Sequence((IEnumerator[])(object)new IEnumerator[2] { CollectionExtensions.WrapToIl2Cpp(FetchBlacklist()), __result }); static IEnumerator FetchBlacklist() { if (!downloaded) { downloaded = true; string modNewsURL = ModNewsURL; SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; ModNewsURL = modNewsURL + (languageID - 1) switch { 8 => "de_DE.json", 0 => "es_419.json", 11 => "es_ES.json", 6 => "fil_PH.json", 7 => "fr_FR.json", 9 => "it_IT.json", 10 => "ja_JP.json", 3 => "ko_KR.json", 5 => "nl_NL.json", 1 => "pt_BR.json", 4 => "ru_RU.json", 12 => "zh_CN.json", 13 => "zh_TW.json", _ => "en_US.json", }; UnityWebRequest request = UnityWebRequest.Get(ModNewsURL); yield return request.SendWebRequest(); if (!request.isNetworkError && !request.isHttpError) { foreach (JsonElement item in JsonDocument.Parse(request.downloadHandler.text).RootElement.GetProperty("News").EnumerateArray()) { int number = int.Parse(item.GetProperty("Number").GetString()); string @string = item.GetProperty("Title").GetString(); string string2 = item.GetProperty("Subtitle").GetString(); string string3 = item.GetProperty("Short").GetString(); string text = Extensions.ToStringEnumerable((IEnumerable)item.GetProperty("Body").EnumerateArray()).ToString(); string string4 = item.GetProperty("Date").GetString(); new ModNews(number, @string, string2, string3, text, string4); } yield break; } downloaded = false; Logger.Info("ModNews Error Fetch:" + request.responseCode, "ModNews", escapeCRLF: true, 89, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\AnnouncementPatch.cs"); } } } [HarmonyPatch(typeof(PlayerAnnouncementData), "SetAnnouncements")] [HarmonyPrefix] public static bool SetModAnnouncements_Prefix(PlayerAnnouncementData __instance, [HarmonyArgument(0)] ref Il2CppReferenceArray aRange) { Logger.Info("AllModNews:" + AllModNews.Count, "ModNews", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\AnnouncementPatch.cs"); AllModNews.Sort((ModNews a1, ModNews a2) => DateTime.Compare(DateTime.Parse(a2.Date), DateTime.Parse(a1.Date))); List FinalAllNews = new List(); CollectionExtensions.Do((IEnumerable)AllModNews, (Action)delegate(ModNews n) { FinalAllNews.Add(n.ToAnnouncement()); }); foreach (Announcement news in (Il2CppArrayBase)(object)aRange) { if (!AllModNews.Any((ModNews x) => x.Number == news.Number)) { FinalAllNews.Add(news); } } FinalAllNews.Sort((Announcement a1, Announcement a2) => DateTime.Compare(DateTime.Parse(a2.Date), DateTime.Parse(a1.Date))); aRange = new Il2CppReferenceArray((long)FinalAllNews.Count); for (int i = 0; i < FinalAllNews.Count; i++) { ((Il2CppArrayBase)(object)aRange)[i] = FinalAllNews[i]; } return true; } [HarmonyPatch(typeof(AnnouncementPanel), "SetUp")] [HarmonyPostfix] public static void SetUpPanel_Postfix(AnnouncementPanel __instance, [HarmonyArgument(0)] Announcement announcement) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (announcement.Number >= 100000) { GameObject val = new GameObject("ModLabel"); val.transform.SetParent(((Component)__instance).transform); val.transform.localPosition = new Vector3(-0.8f, 0.13f, 0.5f); val.transform.localScale = new Vector3(0.9f, 0.9f, 0.9f); SpriteRenderer obj = val.AddComponent(); obj.sprite = Utils.LoadSprite("TOHE.Resources.Images.CreditsButton.png", 250f); obj.maskInteraction = (SpriteMaskInteraction)1; } } } [HarmonyPatch(typeof(ChatController), "SendChat")] internal class ChatCommands { private static readonly string modLogFiles = "./TOHE-DATA/ModLogs.txt"; private static readonly string modTagsFiles = "./TOHE-DATA/Tags/MOD_TAGS"; private static readonly string sponsorTagsFiles = "./TOHE-DATA/Tags/SPONSOR_TAGS"; private static readonly string vipTagsFiles = "./TOHE-DATA/Tags/VIP_TAGS"; private static readonly Dictionary Pollvotes = new Dictionary(); private static readonly Dictionary PollQuestions = new Dictionary(); private static readonly List PollVoted = new List(); private static float Polltimer = 120f; private static string PollMSG = ""; public const string Csize = "85%"; public const string Asize = "75%"; public static List ChatHistory = new List(); public static bool Prefix(ChatController __instance) { //IL_2dc8: Unknown result type (might be due to invalid IL or missing references) //IL_2d65: Unknown result type (might be due to invalid IL or missing references) //IL_4ece: Unknown result type (might be due to invalid IL or missing references) //IL_4ed3: Unknown result type (might be due to invalid IL or missing references) //IL_1ad0: Unknown result type (might be due to invalid IL or missing references) //IL_1ad6: Invalid comparison between Unknown and I4 //IL_437b: Unknown result type (might be due to invalid IL or missing references) //IL_439d: Unknown result type (might be due to invalid IL or missing references) //IL_3f2f: Unknown result type (might be due to invalid IL or missing references) //IL_43fe: Unknown result type (might be due to invalid IL or missing references) if (!((AbstractChatInputField)__instance.quickChatField).visible && __instance.freeChatField.textArea.text == "") { return false; } if (!GameStates.IsModHost && !((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } __instance.timeSinceLastMessage = 3f; string text = __instance.freeChatField.textArea.text; if (ChatHistory.Count != 0) { List chatHistory = ChatHistory; if (!(chatHistory[chatHistory.Count - 1] != text)) { goto IL_008d; } } ChatHistory.Add(text); goto IL_008d; IL_4f06: bool flag; string text2; if (flag) { Logger.Info("Command Canceled", "ChatCommand", escapeCRLF: true, 1352, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); __instance.freeChatField.textArea.Clear(); __instance.freeChatField.textArea.SetText(text2, ""); __instance.quickChatMenu.Clear(); ((AbstractChatInputField)__instance.quickChatField).Clear(); } return !flag; IL_008d: ChatControllerUpdatePatch.CurrentHistorySelection = ChatHistory.Count; string[] array = text.Split(' '); string text3 = ""; string text4 = ""; flag = false; text2 = ""; Main.isChatCommand = true; Logger.Info(text, "SendChat", escapeCRLF: true, 53, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); if ((Options.NewHideMsg.GetBool() || Blackmailer.HasEnabled) && ((InnerNetClient)AmongUsClient.Instance).AmHost) { ChatManager.SendMessage(PlayerControl.LocalPlayer, text); } if (text.Length >= 4 && text.Substring(0, 3) == "/up") { array[0] = "/up"; } if (!GuessManager.GuesserMsg(PlayerControl.LocalPlayer, text) && !Judge.TrialMsg(PlayerControl.LocalPlayer, text) && !President.EndMsg(PlayerControl.LocalPlayer, text) && !Inspector.InspectCheckMsg(PlayerControl.LocalPlayer, text) && !Pirate.DuelCheckMsg(PlayerControl.LocalPlayer, text) && (!(PlayerControl.LocalPlayer.GetRoleClass() is Councillor councillor) || !councillor.MurderMsg(PlayerControl.LocalPlayer, text)) && !Nemesis.NemesisMsgCheck(PlayerControl.LocalPlayer, text) && !Retributionist.RetributionistMsgCheck(PlayerControl.LocalPlayer, text) && !Medium.MsMsg(PlayerControl.LocalPlayer, text) && (!(PlayerControl.LocalPlayer.GetRoleClass() is Swapper swapper) || !swapper.SwapMsg(PlayerControl.LocalPlayer, text))) { Directory.CreateDirectory(modTagsFiles); Directory.CreateDirectory(vipTagsFiles); Directory.CreateDirectory(sponsorTagsFiles); if (!Blackmailer.CheckBlackmaile(PlayerControl.LocalPlayer) || !PlayerControl.LocalPlayer.IsAlive()) { switch (array[0]) { case "/dump": Utils.DumpLog(); break; case "/v": case "/version": case "/versão": { flag = true; string text5 = ""; PlayerControl localPlayer = PlayerControl.LocalPlayer; string name = "" + Translator.GetString("DefaultSystemMessageTitle") + ""; object obj; if (localPlayer == null) { obj = null; } else { NetworkedPlayerInfo data = localPlayer.Data; obj = ((data != null) ? data.PlayerName : null); } string name2 = (string)obj; try { KeyValuePair[] array2 = Main.playerVersion.OrderBy((KeyValuePair pair) => pair.Key).ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair keyValuePair = array2[i]; ClientData clientById = Utils.GetClientById(keyValuePair.Key); PlayerControl val = ((clientById != null) ? clientById.Character : null); string text6 = text5; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(7, 6); defaultInterpolatedStringHandler.AppendFormatted(keyValuePair.Key); defaultInterpolatedStringHandler.AppendLiteral("/"); object value; if (val != null) { _ = val.PlayerId; value = val.PlayerId.ToString(); } else { value = "null"; } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(val?.GetRealName(isMeeting: false, clientData: true) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(keyValuePair.Value.forkId); defaultInterpolatedStringHandler.AppendLiteral("/"); defaultInterpolatedStringHandler.AppendFormatted(keyValuePair.Value.version); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(keyValuePair.Value.tag); defaultInterpolatedStringHandler.AppendLiteral(")\n"); text5 = text6 + defaultInterpolatedStringHandler.ToStringAndClear(); } if (text5 != "") { localPlayer.SetName(name); DestroyableSingleton.Instance.Chat.AddChat(localPlayer, text5, true); localPlayer.SetName(name2); } } catch (Exception ex) { Logger.Error(ex.Message, "/version", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); text5 = "Error while getting version : " + ex.Message; if (text5 != "") { localPlayer.SetName(name); DestroyableSingleton.Instance.Chat.AddChat(localPlayer, text5, true); localPlayer.SetName(name2); } } break; } default: Main.isChatCommand = false; break; } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Main.isChatCommand = true; switch (array[0]) { case "/ans": case "/asw": case "/answer": Quizmaster.AnswerByChat(PlayerControl.LocalPlayer, array); break; case "/qmquiz": Quizmaster.ShowQuestion(PlayerControl.LocalPlayer); break; case "/win": case "/winner": case "/vencedor": flag = true; if (Main.winnerNameList.Count == 0) { Utils.SendMessage(Translator.GetString("NoInfoExists")); } else { Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList)); } break; case "/l": case "/lastresult": case "/fimdejogo": flag = true; Utils.ShowKillLog(); Utils.ShowLastRoles(); Utils.ShowLastResult(); break; case "/resultados": case "/gr": case "/gameresults": flag = true; Utils.ShowLastResult(); break; case "/kh": case "/killlog": flag = true; Utils.ShowKillLog(); break; case "/sum": case "/результат": case "/rs": case "/rolesummary": case "/sumario": case "/sumário": case "/summary": flag = true; Utils.ShowLastRoles(); break; case "/ghostinfo": flag = true; Utils.SendMessage(Translator.GetString("Message.GhostRoleInfo"), PlayerControl.LocalPlayer.PlayerId); break; case "/rename": case "/renomear": case "/rn": case "/переименовать": flag = true; if (array.Length >= 1) { int i = GeneralExtensions.Join(array.Skip(1), (Func)null, " ").Length; if ((i > 10 || i < 1) ? true : false) { Utils.SendMessage(Translator.GetString("Message.AllowNameLength"), PlayerControl.LocalPlayer.PlayerId); break; } Main.HostRealName = GeneralExtensions.Join(array.Skip(1), (Func)null, " "); Utils.SendMessage(string.Format(Translator.GetString("Message.SetName"), GeneralExtensions.Join(array.Skip(1), (Func)null, " ")), PlayerControl.LocalPlayer.PlayerId); } break; case "/hidename": case "/hn": case "/semnome": { flag = true; Main.HideName.Value = ((array.Length > 1) ? GeneralExtensions.Join(array.Skip(1), (Func)null, " ") : ((ConfigEntryBase)Main.HideName).DefaultValue.ToString()); Color val2 = default(Color); ((TMP_Text)GameStartManagerPatch.GameStartManagerStartPatch.HideName).text = (ColorUtility.TryParseHtmlString(Main.HideColor.Value, ref val2) ? $"{Main.HideName.Value}" : $"{Main.HideName.Value}"); break; } case "/level": case "/nível": case "/nivel": { flag = true; text3 = ((array.Length < 2) ? "" : array[1]); Utils.SendMessage(string.Format(Translator.GetString("Message.SetLevel"), text3), PlayerControl.LocalPlayer.PlayerId); int.TryParse(text3, out var result7); if ((result7 < 1 || result7 > 999) ? true : false) { Utils.SendMessage(Translator.GetString("Message.AllowLevelRange"), PlayerControl.LocalPlayer.PlayerId); break; } uint num4 = Convert.ToUInt32(result7); PlayerControl.LocalPlayer.RpcSetLevel(num4 - 1); break; } case "/now": case "/n": case "/atual": flag = true; switch ((array.Length < 2) ? "" : array[1]) { case "r": case "roles": case "funções": Utils.ShowActiveRoles(); break; case "a": case "all": case "tudo": Utils.ShowAllActiveSettings(); break; default: Utils.ShowActiveSettings(); break; } break; case "/dis": case "/disconnect": case "/desconectar": flag = true; switch ((array.Length < 2) ? "" : array[1]) { case "crew": case "tripulante": ((Behaviour)GameManager.Instance).enabled = false; GameManager.Instance.RpcEndGame((GameOverReason)6, false); break; case "imp": case "impostor": ((Behaviour)GameManager.Instance).enabled = false; GameManager.Instance.RpcEndGame((GameOverReason)5, false); break; default: __instance.AddChat(PlayerControl.LocalPlayer, "crew | imp", true); if ((int)DestroyableSingleton.Instance.currentLanguage.languageID == 2) { __instance.AddChat(PlayerControl.LocalPlayer, "tripulante | impostor", true); } text2 = "/dis"; break; } ShipStatus.Instance.RpcUpdateSystem((SystemTypes)6, (byte)0); break; case "/r": case "/р": case "/role": case "/роль": flag = true; text3 = text.Remove(0, 2); SendRolesInfo(text3, PlayerControl.LocalPlayer.PlayerId); break; case "/up": flag = true; text3 = text.Remove(0, 3); if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp) { Utils.SendMessage(Translator.GetString("InvalidPermissionCMD") ?? "", PlayerControl.LocalPlayer.PlayerId); } else if (!Options.EnableUpMode.GetBool()) { Utils.SendMessage(string.Format(Translator.GetString("Message.YTPlanDisabled"), Translator.GetString("EnableYTPlan")), PlayerControl.LocalPlayer.PlayerId); } else if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); } else { SendRolesInfo(text3, PlayerControl.LocalPlayer.PlayerId, isDev: false, isUp: true); } break; case "/setplayers": case "/maxjogadores": { flag = true; text3 = ((array.Length < 2) ? "" : array[1]); Utils.SendMessage(Translator.GetString("Message.MaxPlayers") + text3); byte maxPlayers = Convert.ToByte(text3); if (GameStates.IsNormalGame) { GameOptionsManager.Instance.currentNormalGameOptions.MaxPlayers = maxPlayers; } else if (GameStates.IsHideNSeek) { GameOptionsManager.Instance.currentHideNSeekGameOptions.MaxPlayers = maxPlayers; } break; } case "/помощь": case "/h": case "/ajuda": case "/help": case "/хелп": case "/хэлп": flag = true; Utils.ShowHelp(PlayerControl.LocalPlayer.PlayerId); break; case "/icons": case "/icon": Utils.SendMessage(Translator.GetString("Command.icons"), PlayerControl.LocalPlayer.PlayerId, Translator.GetString("IconsTitle")); break; case "/iconhelp": Utils.SendMessage(Translator.GetString("Command.icons"), byte.MaxValue, Translator.GetString("IconsTitle")); break; case "/kcount": case "/убийцы": case "/количество": case "/kc": if (!GameStates.IsLobby && Options.EnableKillerLeftCommand.GetBool()) { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; int num6 = allAlivePlayerControls.Count((PlayerControl pc) => pc.Is(Custom_Team.Impostor)); int num7 = allAlivePlayerControls.Count((PlayerControl pc) => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); int num8 = allAlivePlayerControls.Count((PlayerControl pc) => pc.GetCustomRole().IsNK()); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.Append(string.Format(Translator.GetString("Remaining.ImpostorCount"), num6)); if (Options.ShowMadmatesInLeftCommand.GetBool()) { stringBuilder2.Append(string.Format("\n\r" + Translator.GetString("Remaining.MadmateCount"), num7)); } stringBuilder2.Append(string.Format("\n\r" + Translator.GetString("Remaining.NeutralCount"), num8)); Utils.SendMessage(stringBuilder2.ToString(), PlayerControl.LocalPlayer.PlayerId); } break; case "/d": case "/причина": case "/death": case "/morto": case "/умер": { flag = true; Logger.Info($"PlayerControl.LocalPlayer.PlayerId: {PlayerControl.LocalPlayer.PlayerId}", "/death command", escapeCRLF: true, 375, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); if (GameStates.IsLobby) { Logger.Info("IsLobby", "/death command", escapeCRLF: true, 378, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); break; } if (PlayerControl.LocalPlayer.IsAlive()) { Logger.Info("IsAlive", "/death command", escapeCRLF: true, 384, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("DeathCmd.HeyPlayer") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + Translator.GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\n" + Translator.GetString("DeathCmd.NotDead"), PlayerControl.LocalPlayer.PlayerId); break; } if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Vote) { Logger.Info("DeathReason.Vote", "/death command", escapeCRLF: true, 390, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Ejected"), PlayerControl.LocalPlayer.PlayerId); break; } if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) { Logger.Info("DeathReason.Shrouded", "/death command", escapeCRLF: true, 396, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Shrouded"), PlayerControl.LocalPlayer.PlayerId); break; } if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) { Logger.Info("DeathReason.FollowingSuicide", "/death command", escapeCRLF: true, 402, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Lovers"), PlayerControl.LocalPlayer.PlayerId); break; } Logger.Info("GetRealKiller()", "/death command", escapeCRLF: true, 408, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); PlayerControl realKiller = PlayerControl.LocalPlayer.GetRealKiller(); string text17 = (((Object)(object)realKiller == (Object)null) ? "N/A" : realKiller.GetRealName()); string value11 = (((Object)(object)realKiller == (Object)null) ? "N/A" : Utils.GetRoleName(realKiller.GetCustomRole())); Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(PlayerControl.LocalPlayer.PlayerId) + "\n\r\n\r" + Translator.GetString("DeathCmd.KillerName") + "" + text17 + "\n\r" + Translator.GetString("DeathCmd.KillerRole") + "" + $"{value11}" + "", PlayerControl.LocalPlayer.PlayerId); break; } case "/myrole": case "/m": case "/м": case "/minhafunção": case "/мояроль": { flag = true; CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); if (GameStates.IsInGame) { PlayerControl localPlayer2 = PlayerControl.LocalPlayer; string roleInfo = localPlayer2.GetRoleInfo(InfoLong: true); string title = "" + customRole.GetRoleTitle() + "\n"; StringBuilder sb = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder(); string roleColorCode = Utils.GetRoleColorCode(customRole); string title2 = "" + Translator.GetString("YourAddon") + "\n"; if (Options.CustomRoleSpawnChances.TryGetValue(customRole, out var _)) { Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[customRole], ref sb); } string text10 = sb.ToString(); string text11 = $"{Translator.GetString(customRole.ToString())} {Translator.GetString("Settings:")}\n"; sb.Clear().Append("" + text11 + text10 + ""); CustomRoles[] array3 = Main.PlayerStates[localPlayer2.PlayerId].SubRoles.ToArray(); foreach (CustomRoles role in array3) { stringBuilder.Append("\n\n" + role.GetRoleTitle() + role.GetInfoLong() + ""); } if (stringBuilder.ToString() != string.Empty) { string text12 = stringBuilder.ToString().Remove(0, 2); text12 = ((text12.Length > 1200) ? ("" + text12.RemoveHtmlTags() + "") : text12); stringBuilder.Clear().Append(text12); } Utils.SendMessage(roleInfo, localPlayer2.PlayerId, title, logforChatManager: false, noReplay: true); Utils.SendMessage("", localPlayer2.PlayerId, sb.ToString(), logforChatManager: false, noReplay: true); if (stringBuilder.ToString() != string.Empty) { Utils.SendMessage(stringBuilder.ToString(), localPlayer2.PlayerId, title2, logforChatManager: false, noReplay: true); } } else { Utils.SendMessage((PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + Translator.GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); } break; } case "/me": { flag = true; text3 = ((text.Length == 3) ? string.Empty : text.Remove(0, 3)); string text25 = (PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"); string text26 = (PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"); string text27 = (PlayerControl.LocalPlayer.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"); byte result12; if (string.IsNullOrEmpty(text3)) { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + string.Format(Translator.GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(isMeeting: false, clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), text25, text26, text27), true); } else if (byte.TryParse(text3, out result12)) { if (result12 != PlayerControl.LocalPlayer.PlayerId) { PlayerControl playerById5 = Utils.GetPlayerById(result12); if ((Object)(object)playerById5 != (Object)null && playerById5.GetClient() != null) { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + string.Format(Translator.GetString("Message.MeCommandTargetInfo"), playerById5.PlayerId, playerById5.GetRealName(isMeeting: false, clientData: true), playerById5.GetClient().FriendCode, playerById5.GetClient().GetHashedPuid(), playerById5.FriendCode.GetDevUser().GetUserType()), true); } else { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + Translator.GetString("Message.MeCommandInvalidID"), true); } } else { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + string.Format(Translator.GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(isMeeting: false, clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), text25, text26, text27), true); } } else { DestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + Translator.GetString("Message.MeCommandInvalidID"), true); } break; } case "/шаблон": case "/пример": case "/template": case "/t": flag = true; if (array.Length > 1) { TemplateManager.SendTemplate(array[1]); } else { Utils.SendMessage(Translator.GetString("ForExample") + ":\n" + array[0] + " test", PlayerControl.LocalPlayer.PlayerId); } break; case "/mw": case "/messagewait": { flag = true; if (array.Length > 1 && int.TryParse(array[1], out var result9)) { Main.MessageWait.Value = result9; Utils.SendMessage(string.Format(Translator.GetString("Message.SetToSeconds"), result9), 0); break; } Utils.SendMessage($"{Translator.GetString("Message.MessageWaitHelp")}\n{Translator.GetString("ForExample")}:\n{array[0]} 3", 0); break; } case "/tpout": flag = true; if (GameStates.IsLobby) { if (!Options.PlayerCanUseTP.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); } else { PlayerControl.LocalPlayer.RpcTeleport(new Vector2(0.1f, 3.8f)); } } break; case "/tpin": flag = true; if (GameStates.IsLobby) { if (!Options.PlayerCanUseTP.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); } else { PlayerControl.LocalPlayer.RpcTeleport(new Vector2(-0.2f, 1.3f)); } } break; case "/say": case "/s": case "/с": case "/сказать": flag = true; if (array.Length > 1) { Utils.SendMessage(GeneralExtensions.Join(array.Skip(1), (Func)null, " "), byte.MaxValue, $"{Translator.GetString("MessageFromTheHost")} ~ {PlayerControl.LocalPlayer.GetRealName(isMeeting: false, clientData: true)}"); } break; case "/mid": { flag = true; string text29 = Translator.GetString("PlayerIdList"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val5 in allPlayerControls) { if (!((Object)(object)val5 == (Object)null)) { text29 = text29 + "\n" + val5.PlayerId + " → " + val5.GetRealName(); } } Utils.SendMessage(text29, PlayerControl.LocalPlayer.PlayerId); break; } case "/ban": case "/бан": case "/забанить": case "/banir": { flag = true; string text21 = ""; if (array.Length < 3) { Utils.SendMessage(Translator.GetString("BanCommandNoReason"), PlayerControl.LocalPlayer.PlayerId); break; } text3 = array[1]; text21 = string.Join(" ", array.Skip(2)); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result10)) { Utils.SendMessage(Translator.GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } if (result10 == 0) { Utils.SendMessage(Translator.GetString("BanCommandBanHost"), PlayerControl.LocalPlayer.PlayerId); break; } PlayerControl playerById3 = Utils.GetPlayerById(result10); if ((Object)(object)playerById3 == (Object)null) { Utils.SendMessage(Translator.GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(playerById3.GetClientId(), true); string realName2 = playerById3.GetRealName(); string text22 = $"{realName2} {Translator.GetString("BanCommandBanned")}{((Object)PlayerControl.LocalPlayer).name} \nReason: {text21}\n"; if (GameStates.IsInGame) { text22 = text22 + " " + Translator.GetString("BanCommandBannedRole") + " " + Translator.GetString(playerById3.GetCustomRole().ToString()); } Utils.SendMessage(text22); string value12 = PlayerControl.LocalPlayer.FriendCode.ToString(); string value13 = playerById3.FriendCode.ToString(); string value14; string value15 = (Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out value14) ? value14 : ""); string value16; string value17 = (Main.AllPlayerNames.TryGetValue(playerById3.PlayerId, out value16) ? value16 : ""); string text23 = $"[{DateTime.Now}] {value12},{value15} Banned: {value13},{value17} Reason: {text21}"; File.AppendAllText(modLogFiles, text23 + Environment.NewLine); break; } case "/aviso": case "/warn": case "/варн": case "/пред": case "/предупредить": { flag = true; text3 = ((array.Length < 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result11)) { Utils.SendMessage(Translator.GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } if (result11 == 0) { Utils.SendMessage(Translator.GetString("WarnCommandWarnHost"), PlayerControl.LocalPlayer.PlayerId); break; } PlayerControl playerById4 = Utils.GetPlayerById(result11); if ((Object)(object)playerById4 == (Object)null) { Utils.SendMessage(Translator.GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } string value18 = "Reason : Not specified\n"; string realName3 = playerById4.GetRealName(); if (array.Length > 2) { value18 = "Reason : " + string.Join(" ", array.Skip(2)) + "\n"; } else { Utils.SendMessage(Translator.GetString("WarnExample"), PlayerControl.LocalPlayer.PlayerId); } Utils.SendMessage($" {realName3} {Translator.GetString("WarnCommandWarned")} {value18} ~{((Object)PlayerControl.LocalPlayer).name}"); string value19; string value20 = (Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out value19) ? value19 : ""); string value21; string value22 = (Main.AllPlayerNames.TryGetValue(playerById4.PlayerId, out value21) ? value21 : ""); string value23 = PlayerControl.LocalPlayer.FriendCode.ToString(); string value24 = playerById4.FriendCode.ToString(); string hashedPuid2 = playerById4.GetClient().GetHashedPuid(); string text24 = $"[{DateTime.Now}] {value23},{value20} Warned: {value24},{hashedPuid2},{value22} Reason: {value18}"; File.AppendAllText(modLogFiles, text24 + Environment.NewLine); break; } case "/кик": case "/expulsar": case "/кикнуть": case "/выгнать": case "/kick": { flag = true; text3 = ((array.Length < 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result4)) { Utils.SendMessage(Translator.GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } if (result4 == 0) { Utils.SendMessage(Translator.GetString("KickCommandKickHost"), PlayerControl.LocalPlayer.PlayerId); break; } PlayerControl playerById = Utils.GetPlayerById(result4); if ((Object)(object)playerById == (Object)null) { Utils.SendMessage(Translator.GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); break; } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(playerById.GetClientId(), false); string realName = playerById.GetRealName(); string value2 = "Reason : Not specified\n"; if (array.Length > 2) { value2 = "Reason : " + string.Join(" ", array.Skip(2)) + "\n"; } else { Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", PlayerControl.LocalPlayer.PlayerId); } string text8 = $"{realName} {Translator.GetString("KickCommandKicked")} {((Object)PlayerControl.LocalPlayer).name} \n {value2}"; if (GameStates.IsInGame) { text8 = text8 + " " + Translator.GetString("KickCommandKickedRole") + " " + Translator.GetString(playerById.GetCustomRole().ToString()); } Utils.SendMessage(text8); string value3; string value4 = (Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out value3) ? value3 : ""); string value5; string value6 = (Main.AllPlayerNames.TryGetValue(playerById.PlayerId, out value5) ? value5 : ""); string value7 = PlayerControl.LocalPlayer.FriendCode.ToString(); string value8 = playerById.FriendCode.ToString(); string hashedPuid = playerById.GetClient().GetHashedPuid(); string text9 = $"[{DateTime.Now}] {value7},{value4} Kicked: {value8},{hashedPuid},{value6} Reason: {value2}"; File.AppendAllText(modLogFiles, text9 + Environment.NewLine); break; } case "/tagcolor": case "/tagcolour": { flag = true; string value10; string text15 = (Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out value10) ? value10 : ""); if (text15 == "" || text15.Contains('\r') || !PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag()) { break; } if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("ColorCommandNoLobby"), PlayerControl.LocalPlayer.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !Utils.CheckColorHex(text3)) { Logger.Msg(text3 ?? "", "tagcolor", escapeCRLF: true, 745, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("TagColorInvalidHexCode"), PlayerControl.LocalPlayer.PlayerId); break; } string text16 = sponsorTagsFiles + "/" + PlayerControl.LocalPlayer.FriendCode + ".txt"; if (!File.Exists(text16)) { Logger.Msg("File Not exist, creating file at " + text16, "tagcolor", escapeCRLF: true, 752, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(text16).Close(); } File.WriteAllText(text16, text3 ?? ""); break; } case "/exe": case "/мут": case "/повесить": case "/уничтожить": case "/казнить": case "/казнь": flag = true; if (GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); } else { if (array.Length < 2 || !int.TryParse(array[1], out var result5)) { break; } PlayerControl playerById2 = Utils.GetPlayerById(result5); if ((Object)(object)playerById2 != (Object)null) { playerById2.Data.IsDead = true; playerById2.SetDeathReason(PlayerState.DeathReason.etc); playerById2.SetRealKiller(PlayerControl.LocalPlayer); Main.PlayerStates[playerById2.PlayerId].SetDead(); playerById2.RpcExileV2(); MurderPlayerPatch.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, playerById2, GameStates.IsMeeting); if (((InnerNetObject)playerById2).AmOwner) { Utils.SendMessage(Translator.GetString("HostKillSelfByCommand"), byte.MaxValue, "" + Translator.GetString("DefaultSystemMessageTitle") + ""); } else { Utils.SendMessage(string.Format(Translator.GetString("Message.Executed"), playerById2.Data.PlayerName)); } } } break; case "/matar": case "/убить": case "/kill": flag = true; if (GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); } else { if (array.Length < 2 || !int.TryParse(array[1], out var result13)) { break; } PlayerControl playerById6 = Utils.GetPlayerById(result13); if ((Object)(object)playerById6 != (Object)null) { playerById6.RpcMurderPlayer(playerById6); if (((InnerNetObject)playerById6).AmOwner) { Utils.SendMessage(Translator.GetString("HostKillSelfByCommand"), byte.MaxValue, "" + Translator.GetString("DefaultSystemMessageTitle") + ""); } else { Utils.SendMessage(string.Format(Translator.GetString("Message.Executed"), playerById6.Data.PlayerName)); } new LateTask(delegate { Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); }, 0.2f, "Update NotifyRoles players after /kill"); } } break; case "/cor": case "/colour": case "/color": case "/цвет": { flag = true; if (GameStates.IsInGame) { Utils.SendMessage(Translator.GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); break; } text3 = ((array.Length < 2) ? "" : array[1]); byte b = Utils.MsgToColor(text3, isHost: true); if (b == byte.MaxValue) { Utils.SendMessage(Translator.GetString("IllegalColor"), PlayerControl.LocalPlayer.PlayerId); break; } PlayerControl.LocalPlayer.RpcSetColor(b); Utils.SendMessage(string.Format(Translator.GetString("Message.SetColor"), text3), PlayerControl.LocalPlayer.PlayerId); break; } case "/qt": case "/quit": case "/sair": flag = true; Utils.SendMessage(Translator.GetString("Message.CanNotUseByHost"), PlayerControl.LocalPlayer.PlayerId); break; case "/xf": { flag = true; if (GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); break; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val3 in allPlayerControls) { if (!val3.IsAlive()) { val3.RpcSetNameEx(val3.GetRealName(isMeeting: true)); } } ChatUpdatePatch.DoBlockChat = false; Utils.SendMessage(Translator.GetString("Message.TryFixName"), PlayerControl.LocalPlayer.PlayerId); break; } case "/id": case "/айди": { flag = true; string text28 = Translator.GetString("PlayerIdList"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val4 in allPlayerControls) { if (!((Object)(object)val4 == (Object)null)) { text28 = text28 + "\n" + val4.PlayerId + " → " + val4.GetRealName(); } } Utils.SendMessage(text28, PlayerControl.LocalPlayer.PlayerId); break; } case "/setrole": flag = true; text3 = text.Remove(0, 8); SendRolesInfo(text3, PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug); break; case "/changerole": case "/mudarfunção": { flag = true; if (GameStates.IsHideNSeek || !DebugModeManager.AmDebugger || !GameStates.IsInGame || (GameStates.IsOnlineGame && !PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug)) { break; } text3 = text.Remove(0, 11); string text13 = FixRoleNameInput(text3).ToLower().Trim().Replace(" ", string.Empty); Logger.Info(text13, "changerole Input", escapeCRLF: true, 892, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); CustomRoles[] array3 = CustomRolesHelper.AllRoles; for (int i = 0; i < array3.Length; i++) { CustomRoles role2 = array3[i]; if (!role2.IsVanilla()) { string text14 = Translator.GetString(role2.ToString()).ToLower().Trim() .TrimStart('*') .Replace(" ", string.Empty); if (text13 == text14) { PlayerControl.LocalPlayer.GetRoleClass()?.OnRemove(PlayerControl.LocalPlayer.PlayerId); PlayerControl.LocalPlayer.RpcSetRole(role2.GetRoleTypes(), false); PlayerControl.LocalPlayer.RpcSetCustomRole(role2); PlayerControl.LocalPlayer.GetRoleClass().OnAdd(PlayerControl.LocalPlayer.PlayerId); Utils.SendMessage($"Debug Set your role to {role2.ToString()}", PlayerControl.LocalPlayer.PlayerId); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); Utils.MarkEveryoneDirtySettings(); break; } } } break; } case "/end": case "/encerrar": case "/завершить": flag = true; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw); GameManager.Instance.LogicFlow.CheckEndCriteria(); break; case "/cosid": { flag = true; PlayerOutfit defaultOutfit = PlayerControl.LocalPlayer.Data.DefaultOutfit; Logger.Warn($"ColorId: {defaultOutfit.ColorId}", "Get Cos Id", escapeCRLF: true, 922, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Logger.Warn("PetId: " + defaultOutfit.PetId, "Get Cos Id", escapeCRLF: true, 923, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Logger.Warn("HatId: " + defaultOutfit.HatId, "Get Cos Id", escapeCRLF: true, 924, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Logger.Warn("SkinId: " + defaultOutfit.SkinId, "Get Cos Id", escapeCRLF: true, 925, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Logger.Warn("VisorId: " + defaultOutfit.VisorId, "Get Cos Id", escapeCRLF: true, 926, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Logger.Warn("NamePlateId: " + defaultOutfit.NamePlateId, "Get Cos Id", escapeCRLF: true, 927, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); break; } case "/mt": case "/hy": flag = true; if (GameStates.IsMeeting) { MeetingHud.Instance.RpcClose(); } else { PlayerControl.LocalPlayer.NoCheckStartMeeting(null, force: true); } break; case "/cs": flag = true; text3 = text.Remove(0, 3); PlayerControl.LocalPlayer.RPCPlayCustomSound(text3.Trim()); break; case "/sd": { flag = true; text3 = text.Remove(0, 3); if (array.Length >= 1 && int.TryParse(array[1], out var result6)) { RPC.PlaySoundRPC(PlayerControl.LocalPlayer.PlayerId, (Sounds)result6); } break; } case "/poll": { flag = true; if (array.Length == 2 && array[1] == Translator.GetString("Replay") && Pollvotes.Any() && PollMSG != string.Empty) { Utils.SendMessage(PollMSG); break; } PollMSG = string.Empty; Pollvotes.Clear(); PollQuestions.Clear(); PollVoted.Clear(); Polltimer = 120f; if (Main.AllPlayerControls.Length < 3) { Utils.SendMessage(Translator.GetString("Poll.MissingPlayers"), PlayerControl.LocalPlayer.PlayerId); break; } if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Poll.OnlyInLobby"), PlayerControl.LocalPlayer.PlayerId); break; } if (array.SkipWhile((string x) => !x.Contains('?')).ToArray().Length < 3 || !array.Any((string x) => x.Contains('?'))) { Utils.SendMessage(Translator.GetString("PollUsage"), PlayerControl.LocalPlayer.PlayerId); break; } IEnumerable source = array.TakeWhile((string x) => !x.Contains('?')).Concat(array.SkipWhile((string x) => !x.Contains('?')).Take(1)); string text18 = string.Join(" ", source.Skip(1)); bool flag2 = text18.Length > 30; text18 = Utils.ColorString(((Il2CppArrayBase)(object)Palette.PlayerColors)[PlayerControl.LocalPlayer.Data.DefaultOutfit.ColorId], text18); string text19 = Utils.ColorString(new Color32((byte)151, (byte)198, (byte)230, byte.MaxValue), Translator.GetString("PollTitle")); List list2 = array.ToList(); list2.RemoveRange(0, source.ToArray().Length); string[] array4 = list2.ToArray(); string text20 = ""; if (flag2) { text20 = text20 + "" + text18 + "\n\n"; } for (int j = 0; j < Math.Clamp(array4.Length, 2, 5); j++) { text20 += Utils.ColorString(RndCLR(), $"{char.ToUpper((char)(j + 65))}) {array4[j]}\n"); Pollvotes[char.ToUpper((char)(j + 65))] = 0; PollQuestions[char.ToUpper((char)(j + 65))] = "〖 " + array4[j] + " 〗"; } text20 = text20 + "\n" + Translator.GetString("Poll.Begin"); text20 = text20 + "\n" + Translator.GetString("Poll.TimeInfo") + ""; PollMSG = ((!flag2) ? ("" + text18 + "\n\n" + text20) : text20); Logger.Info("Poll message: " + text20, "MEssapoll", escapeCRLF: true, 1101, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(text20, byte.MaxValue, (!flag2) ? text18 : text19); Main.Instance.StartCoroutine(StartPollCountdown()); break; } case "/rps": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); break; } flag = true; text3 = ((array.Length != 2) ? "" : array[1]); if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } if (text3 == "" || !int.TryParse(text3, out var result)) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } if (result < 0 || result > 2) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } int num2 = IRandom.Instance.Next(0, 3); List list = new List { Translator.GetString("Rock"), Translator.GetString("Paper"), Translator.GetString("Scissors") }; if (num2 == result) { Utils.SendMessage(string.Format(Translator.GetString("RpsDraw"), list[num2]), PlayerControl.LocalPlayer.PlayerId); } else if ((num2 == 0 && result == 2) || (num2 == 1 && result == 0) || (num2 == 2 && result == 1)) { Utils.SendMessage(string.Format(Translator.GetString("RpsLose"), list[num2]), PlayerControl.LocalPlayer.PlayerId); } else { Utils.SendMessage(string.Format(Translator.GetString("RpsWin"), list[num2]), PlayerControl.LocalPlayer.PlayerId); } break; } case "/coinflip": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); break; } flag = true; if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) { Utils.SendMessage(Translator.GetString("CoinFlipCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } string arg = ((IRandom.Instance.Next(1, 101) < 51) ? Translator.GetString("Heads") : Translator.GetString("Tails")); Utils.SendMessage(string.Format(Translator.GetString("CoinFlipResult"), arg), PlayerControl.LocalPlayer.PlayerId); break; } case "/gno": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); break; } flag = true; if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); if (text3 == "" || !int.TryParse(text3, out var result8)) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } if (result8 < 0 || result8 > 99) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } int num5 = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] == -1) { IRandom instance = IRandom.Instance; Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = instance.Next(0, 100); num5 = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; } Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]--; if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] == 0 && result8 != num5) { Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; Utils.SendMessage(string.Format(Translator.GetString("GNoLost"), num5), PlayerControl.LocalPlayer.PlayerId); } else if (result8 < num5) { Utils.SendMessage(string.Format(Translator.GetString("GNoLow"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); } else if (result8 > num5) { Utils.SendMessage(string.Format(Translator.GetString("GNoHigh"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); } else { Utils.SendMessage(string.Format(Translator.GetString("GNoWon"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; } break; } case "/rand": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); break; } flag = true; text3 = ((array.Length != 3) ? "" : array[1]); text4 = ((array.Length != 3) ? "" : array[2]); if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) { Utils.SendMessage(Translator.GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } if (text3 == "" || !int.TryParse(text3, out var result2) || text4 == "" || !int.TryParse(text4, out var result3)) { Utils.SendMessage(Translator.GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); break; } int num3 = IRandom.Instance.Next(result2, result3 + 1); Utils.SendMessage(string.Format(Translator.GetString("RandResult"), num3), PlayerControl.LocalPlayer.PlayerId); break; } case "/8ball": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); break; } flag = true; int num = IRandom.Instance.Next(0, 16); string text7 = ""; switch (num) { case 0: text7 = Translator.GetString("8BallYes"); break; case 1: text7 = Translator.GetString("8BallNo"); break; case 2: text7 = Translator.GetString("8BallMaybe"); break; case 3: text7 = Translator.GetString("8BallTryAgainLater"); break; case 4: text7 = Translator.GetString("8BallCertain"); break; case 5: text7 = Translator.GetString("8BallNotLikely"); break; case 6: text7 = Translator.GetString("8BallLikely"); break; case 7: text7 = Translator.GetString("8BallDontCount"); break; case 8: text7 = Translator.GetString("8BallStop"); break; case 9: text7 = Translator.GetString("8BallPossibly"); break; case 10: text7 = Translator.GetString("8BallProbably"); break; case 11: text7 = Translator.GetString("8BallProbablyNot"); break; case 12: text7 = Translator.GetString("8BallBetterNotTell"); break; case 13: text7 = Translator.GetString("8BallCantPredict"); break; case 14: text7 = Translator.GetString("8BallWithoutDoubt"); break; case 15: text7 = Translator.GetString("8BallWithDoubt"); break; } Utils.SendMessage("" + text7 + "", PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("8BallTitle"))); break; } default: Main.isChatCommand = false; break; } } goto IL_4f06; } } Main.isChatCommand = false; flag = true; goto IL_4f06; static void DetermineResults() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) int basenum = Pollvotes.Values.Max(); IEnumerable> winners = Pollvotes.Where((KeyValuePair x) => x.Value == basenum); string text30 = ""; string title3 = Utils.ColorString(new Color32((byte)47, (byte)234, (byte)45, byte.MaxValue), Translator.GetString("PollResultTitle")); if (winners.Count() == 1) { IEnumerable> source2 = Pollvotes.Where((KeyValuePair x) => x.Key != winners.First().Key); text30 = string.Format(Translator.GetString("Poll.Result"), $"{winners.First().Key}{PollQuestions[winners.First().Key]}", winners.First().Value); for (int k = 0; k < source2.Count(); k++) { text30 += $"\n{source2.ElementAt(k).Key} / {source2.ElementAt(k).Value} {PollQuestions[source2.ElementAt(k).Key]}"; } text30 += ""; Utils.SendMessage(text30, byte.MaxValue, title3); } else { int tienum = Pollvotes.Values.Max(); IEnumerable> source3 = Pollvotes.Where((KeyValuePair x) => x.Value == tienum); for (int l = 0; l < source3.Count() - 1; l++) { text30 = text30 + "\n" + source3.ElementAt(l).Key + PollQuestions[source3.ElementAt(l).Key] + " & "; } text30 = text30 + "\n" + source3.Last().Key + PollQuestions[source3.Last().Key]; Utils.SendMessage(string.Format(Translator.GetString("Poll.Tied"), text30, tienum), byte.MaxValue, title3); } Pollvotes.Clear(); PollQuestions.Clear(); PollVoted.Clear(); } static Color32 RndCLR() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) byte num9 = (byte)IRandom.Instance.Next(45, 185); byte b2 = (byte)IRandom.Instance.Next(45, 185); byte b3 = (byte)IRandom.Instance.Next(45, 185); return new Color32(num9, b2, b3, byte.MaxValue); } static IEnumerator StartPollCountdown() { if (!Pollvotes.Any() || !GameStates.IsLobby) { Pollvotes.Clear(); PollQuestions.Clear(); PollVoted.Clear(); } else { bool playervoted = Main.AllPlayerControls.Length - 1 > Pollvotes.Values.Sum(); while (playervoted && Polltimer > 0f) { if (!Pollvotes.Any() || !GameStates.IsLobby) { Pollvotes.Clear(); PollQuestions.Clear(); PollVoted.Clear(); yield break; } playervoted = Main.AllPlayerControls.Length - 1 > Pollvotes.Values.Sum(); Polltimer -= Time.deltaTime; yield return null; } if (!Pollvotes.Any() || !GameStates.IsLobby) { Pollvotes.Clear(); PollQuestions.Clear(); PollVoted.Clear(); } else { Logger.Info($"FINNISHED!! playervote?: {!playervoted} polltime?: {Polltimer <= 0f}", "/poll - StartPollCountdown", escapeCRLF: true, 1009, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); DetermineResults(); } } } } public static string FixRoleNameInput(string text) { text = text.Replace("着", "者").Trim().ToLower(); return text; } public static bool GetRoleByName(string name, out CustomRoles role) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) role = CustomRoles.Crewmate; if (name == "" || name == string.Empty) { return false; } if (((!DestroyableSingleton.InstanceExists) ? 13 : ((int)DestroyableSingleton.Instance.currentLanguage.languageID)) == 13) { MatchCollection matchCollection = new Regex("[一-龥]+$").Matches(name); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { if (!(matchCollection[i].ToString() == "是")) { text += matchCollection[i]; } } name = FixRoleNameInput(text.Replace("是", string.Empty).Trim()); } else { name = name.Trim().ToLower(); } CustomRoles[] allRoles = CustomRolesHelper.AllRoles; for (int j = 0; j < allRoles.Length; j++) { CustomRoles customRoles = allRoles[j]; if (!customRoles.IsVanilla()) { string text2 = Translator.GetString(customRoles.ToString()).ToLower().Trim() .Replace(" ", ""); if (Regex.Replace(name.Replace(" ", ""), "^\\d+", "") == text2) { role = customRoles; return true; } } } return false; } public static void SendRolesInfo(string role, byte playerId, bool isDev = false, bool isUp = false) { if (Options.CurrentGameMode == CustomGameMode.FFA) { Utils.SendMessage(Translator.GetString("ModeDescribe.FFA"), playerId); return; } role = role.Trim().ToLower(); if (role.StartsWith("/r")) { role.Replace("/r", string.Empty); } if (role.StartsWith("/up")) { role.Replace("/up", string.Empty); } if (role.EndsWith("\r\n")) { role.Replace("\r\n", string.Empty); } if (role.EndsWith("\n")) { role.Replace("\n", string.Empty); } if (role.StartsWith("/bt")) { role.Replace("/bt", string.Empty); } if (role == "" || role == string.Empty) { Utils.ShowActiveRoles(playerId); return; } role = FixRoleNameInput(role).ToLower().Trim().Replace(" ", string.Empty); CustomRoles[] allRoles = CustomRolesHelper.AllRoles; for (int i = 0; i < allRoles.Length; i++) { CustomRoles customRoles = allRoles[i]; if (customRoles.IsVanilla()) { continue; } string @string = Translator.GetString(customRoles.ToString()); if (!(role == @string.ToLower().Trim().TrimStart('*') .Replace(" ", string.Empty))) { continue; } string text = ""; if ((isDev || isUp) && GameStates.IsLobby) { text = "▲"; bool flag = customRoles.IsAdditionRole(); if (!flag) { bool flag2 = ((customRoles == CustomRoles.Mini || customRoles == CustomRoles.GM) ? true : false); flag = flag2; } if (flag || customRoles.IsGhostRole()) { text = ""; } if (customRoles.GetCount() < 1 || customRoles.GetMode() == 0) { text = ""; } if (isUp) { if (text == "▲") { Utils.SendMessage(string.Format(Translator.GetString("Message.YTPlanSelected"), @string), playerId); } else { Utils.SendMessage(string.Format(Translator.GetString("Message.YTPlanSelectFailed"), @string), playerId); } } if (text == "▲") { byte key = (byte)((playerId != byte.MaxValue) ? playerId : 0); GhostRoleAssign.forceRole.Remove(key); RoleAssign.SetRoles.Remove(key); RoleAssign.SetRoles.Add(key, customRoles); } if (customRoles.IsGhostRole() && !customRoles.IsAdditionRole() && isDev && customRoles.GetCount() >= 1 && customRoles.GetMode() > 0) { byte key2 = (byte)((playerId != byte.MaxValue) ? playerId : 0); CustomRoles customRoles2 = ((customRoles.GetCustomRoleTeam() != Custom_Team.Impostor) ? CustomRoles.CrewmateTOHE : CustomRoles.ImpostorTOHE); CustomRoles value = customRoles2; RoleAssign.SetRoles.Remove(key2); RoleAssign.SetRoles.Add(key2, value); GhostRoleAssign.forceRole[key2] = customRoles; text = "▲"; } if (isUp) { return; } } string infoLong = customRoles.GetInfoLong(); string title = text + "" + customRoles.GetRoleTitle() + "\n"; StringBuilder sb = new StringBuilder(); string roleColorCode = Utils.GetRoleColorCode(customRoles); if (Options.CustomRoleSpawnChances.ContainsKey(customRoles)) { Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[customRoles], ref sb); string text2 = sb.ToString(); string text3 = $"{Translator.GetString(customRoles.ToString())} {Translator.GetString("Settings:")}\n"; sb.Clear().Append("" + text3 + text2 + ""); } Utils.SendMessage(infoLong, playerId, title, logforChatManager: false, noReplay: true); Utils.SendMessage("", playerId, sb.ToString(), logforChatManager: false, noReplay: true); return; } if (isUp) { Utils.SendMessage(Translator.GetString("Message.YTPlanCanNotFindRoleThePlayerEnter"), playerId); } else { Utils.SendMessage(Translator.GetString("Message.CanNotFindRoleThePlayerEnter"), playerId); } } public static void OnReceiveChat(PlayerControl player, string text, out bool canceled) { //IL_3587: Unknown result type (might be due to invalid IL or missing references) //IL_4124: Unknown result type (might be due to invalid IL or missing references) //IL_4129: Unknown result type (might be due to invalid IL or missing references) //IL_35d7: Unknown result type (might be due to invalid IL or missing references) canceled = false; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if ((Options.NewHideMsg.GetBool() || Blackmailer.HasEnabled) && !((InnerNetObject)(object)player).OwnedByHost()) { ChatManager.SendMessage(player, text); } if (text.StartsWith("\n")) { string text2 = text; text = text2.Substring(1, text2.Length - 1); } string[] array = text.Split(' '); string text3 = ""; string text4 = ""; if (GuessManager.GuesserMsg(player, text)) { canceled = true; Logger.Info("Is Guesser command", "OnReceiveChat", escapeCRLF: true, 1834, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Judge.TrialMsg(player, text)) { canceled = true; Logger.Info("Is Judge command", "OnReceiveChat", escapeCRLF: true, 1835, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (President.EndMsg(player, text)) { canceled = true; Logger.Info("Is President command", "OnReceiveChat", escapeCRLF: true, 1836, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Inspector.InspectCheckMsg(player, text)) { canceled = true; Logger.Info("Is Inspector command", "OnReceiveChat", escapeCRLF: true, 1837, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Pirate.DuelCheckMsg(player, text)) { canceled = true; Logger.Info("Is Pirate command", "OnReceiveChat", escapeCRLF: true, 1838, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (player.GetRoleClass() is Councillor councillor && councillor.MurderMsg(player, text)) { canceled = true; Logger.Info("Is Councillor command", "OnReceiveChat", escapeCRLF: true, 1839, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (player.GetRoleClass() is Swapper swapper && swapper.SwapMsg(player, text)) { canceled = true; Logger.Info("Is Swapper command", "OnReceiveChat", escapeCRLF: true, 1840, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Medium.MsMsg(player, text)) { Logger.Info("Is Medium command", "OnReceiveChat", escapeCRLF: true, 1841, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Nemesis.NemesisMsgCheck(player, text)) { Logger.Info("Is Nemesis Revenge command", "OnReceiveChat", escapeCRLF: true, 1842, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } if (Retributionist.RetributionistMsgCheck(player, text)) { Logger.Info("Is Retributionist Revenge command", "OnReceiveChat", escapeCRLF: true, 1843, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); return; } Directory.CreateDirectory(modTagsFiles); Directory.CreateDirectory(vipTagsFiles); Directory.CreateDirectory(sponsorTagsFiles); if (Blackmailer.CheckBlackmaile(player) && player.IsAlive() && !player.IsModClient()) { Logger.Info($"This player (id {player.PlayerId}) was Blackmailed", "OnReceiveChat", escapeCRLF: true, 1851, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); ChatManager.SendPreviousMessagesToAll(); ChatManager.cancel = false; canceled = true; return; } switch (array[0]) { case "/r": case "/р": case "/role": case "/роль": Logger.Info("Command '/r' was activated", "OnReceiveChat", escapeCRLF: true, 1864, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); text3 = text.Remove(0, 2); SendRolesInfo(text3, player.PlayerId, player.FriendCode.GetDevUser().DeBug); break; case "/m": case "/м": case "/myrole": case "/minhafunção": case "/мояроль": { Logger.Info("Command '/m' was activated", "OnReceiveChat", escapeCRLF: true, 1874, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); CustomRoles customRole = player.GetCustomRole(); if (GameStates.IsInGame) { string roleInfo = player.GetRoleInfo(InfoLong: true); string title = "" + customRole.GetRoleTitle() + "\n"; StringBuilder sb = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder(); string roleColorCode = Utils.GetRoleColorCode(customRole); string title2 = "" + Translator.GetString("YourAddon") + "\n"; if (Options.CustomRoleSpawnChances.TryGetValue(customRole, out var value25)) { Utils.ShowChildrenSettings(value25, ref sb); } string text17 = sb.ToString(); string text18 = $"{Translator.GetString(customRole.ToString())} {Translator.GetString("Settings:")}\n"; sb.Clear().Append("" + text18 + text17 + ""); CustomRoles[] array2 = Main.PlayerStates[player.PlayerId].SubRoles.ToArray(); foreach (CustomRoles role in array2) { stringBuilder.Append("\n\n" + role.GetRoleTitle() + role.GetInfoLong() + ""); } if (stringBuilder.ToString() != string.Empty) { string text19 = stringBuilder.ToString().Remove(0, 2); text19 = ((text19.Length > 1200) ? ("" + text19.RemoveHtmlTags() + "") : text19); stringBuilder.Clear().Append(text19); } Utils.SendMessage(roleInfo, player.PlayerId, title, logforChatManager: false, noReplay: true); Utils.SendMessage("", player.PlayerId, sb.ToString(), logforChatManager: false, noReplay: true); if (stringBuilder.ToString() != string.Empty) { Utils.SendMessage(stringBuilder.ToString(), player.PlayerId, title2, logforChatManager: false, noReplay: true); } Logger.Info("Command '/m' should be send message", "OnReceiveChat", escapeCRLF: true, 1907, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); } else { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), player.PlayerId); } break; } case "/h": case "/help": case "/хелп": case "/хэлп": case "/помощь": case "/ajuda": Utils.ShowHelpToClient(player.PlayerId); break; case "/answer": case "/ans": case "/asw": Quizmaster.AnswerByChat(player, array); break; case "/qmquiz": Quizmaster.ShowQuestion(player); break; case "/l": case "/lastresult": case "/fimdejogo": Utils.ShowKillLog(player.PlayerId); Utils.ShowLastRoles(player.PlayerId); Utils.ShowLastResult(player.PlayerId); break; case "/gameresults": case "/resultados": case "/gr": Utils.ShowLastResult(player.PlayerId); break; case "/killlog": case "/kh": Utils.ShowKillLog(player.PlayerId); break; case "/rolesummary": case "/summary": case "/sumário": case "/sumario": case "/sum": case "/результат": case "/rs": Utils.ShowLastRoles(player.PlayerId); break; case "/ghostinfo": if (GameStates.IsInGame) { Utils.SendMessage(Translator.GetString("Message.OnlyCanUseInLobby"), player.PlayerId); } else { Utils.SendMessage(Translator.GetString("Message.GhostRoleInfo"), player.PlayerId); } break; case "/rename": case "/rn": case "/renomear": case "/переименовать": if (Options.PlayerCanSetName.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().NameCmd || Utils.IsPlayerVIP(player.FriendCode)) { if (GameStates.IsInGame) { Utils.SendMessage(Translator.GetString("Message.OnlyCanUseInLobby"), player.PlayerId); } else if (array.Length >= 1) { int i = GeneralExtensions.Join(array.Skip(1), (Func)null, " ").Length; if ((i > 10 || i < 1) ? true : false) { Utils.SendMessage(Translator.GetString("Message.AllowNameLength"), player.PlayerId); break; } Main.AllPlayerNames[player.PlayerId] = GeneralExtensions.Join(array.Skip(1), (Func)null, " "); Utils.SendMessage(string.Format(Translator.GetString("Message.SetName"), GeneralExtensions.Join(array.Skip(1), (Func)null, " ")), player.PlayerId); } } else { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); } break; case "/n": case "/atual": case "/now": switch ((array.Length < 2) ? "" : array[1]) { case "r": case "roles": case "funções": Utils.ShowActiveRoles(player.PlayerId); break; case "a": case "all": case "tudo": Utils.ShowAllActiveSettings(player.PlayerId); break; default: Utils.ShowActiveSettings(player.PlayerId); break; } break; case "/up": text.Remove(0, 3); if (!Options.EnableUpMode.GetBool()) { Utils.SendMessage(string.Format(Translator.GetString("Message.YTPlanDisabled"), Translator.GetString("EnableYTPlan")), player.PlayerId); } else { Utils.SendMessage(Translator.GetString("Message.OnlyCanBeUsedByHost"), player.PlayerId); } break; case "/winner": case "/win": case "/vencedor": if (Main.winnerNameList.Count == 0) { Utils.SendMessage(Translator.GetString("NoInfoExists"), player.PlayerId); } else { Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList), player.PlayerId); } break; case "/pv": { canceled = true; if (!Pollvotes.Any()) { Utils.SendMessage(Translator.GetString("Poll.Inactive"), player.PlayerId); break; } if (PollVoted.Contains(player.PlayerId)) { Utils.SendMessage(Translator.GetString("Poll.AlreadyVoted"), player.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); char result4 = ' '; if (int.TryParse(text3, out var result5) && Pollvotes.Count - 1 >= result5) { result4 = char.ToUpper((char)(result5 + 65)); } else if (!char.TryParse(text3, out result4) || !Pollvotes.ContainsKey(char.ToUpper(result4))) { Utils.SendMessage(Translator.GetString("Poll.VotingInfo"), player.PlayerId); break; } result4 = char.ToUpper(result4); PollVoted.Add(player.PlayerId); Pollvotes[result4]++; Utils.SendMessage(string.Format(Translator.GetString("Poll.YouVoted"), result4, Pollvotes[result4]), player.PlayerId); Logger.Info($"The new value of {result4} is {Pollvotes[result4]}", "TestPV_CHAR", escapeCRLF: true, 2070, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); break; } case "/icon": case "/icons": Utils.SendMessage(Translator.GetString("Command.icons"), player.PlayerId, Translator.GetString("IconsTitle")); break; case "/kcount": case "/убийцы": case "/количество": case "/kc": if (!GameStates.IsLobby && Options.EnableKillerLeftCommand.GetBool()) { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; int num5 = allAlivePlayerControls.Count((PlayerControl pc) => pc.Is(Custom_Team.Impostor)); int num6 = allAlivePlayerControls.Count((PlayerControl pc) => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); int num7 = allAlivePlayerControls.Count((PlayerControl pc) => pc.GetCustomRole().IsNK()); StringBuilder stringBuilder2 = new StringBuilder(); stringBuilder2.Append(string.Format(Translator.GetString("Remaining.ImpostorCount"), num5)); if (Options.ShowMadmatesInLeftCommand.GetBool()) { stringBuilder2.Append(string.Format("\n\r" + Translator.GetString("Remaining.MadmateCount"), num6)); } stringBuilder2.Append(string.Format("\n\r" + Translator.GetString("Remaining.NeutralCount"), num7)); Utils.SendMessage(stringBuilder2.ToString(), player.PlayerId); } break; case "/d": case "/умер": case "/причина": case "/death": case "/morto": { if (GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), player.PlayerId); break; } if (player.IsAlive()) { Utils.SendMessage(Translator.GetString("DeathCmd.HeyPlayer") + "" + player.GetRealName() + "" + Translator.GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\n" + Translator.GetString("DeathCmd.NotDead"), player.PlayerId); break; } if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Vote) { Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + player.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Ejected"), player.PlayerId); break; } if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) { Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + player.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Shrouded"), player.PlayerId); break; } if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) { Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + player.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.Lovers"), player.PlayerId); break; } PlayerControl realKiller = player.GetRealKiller(); string text22 = (((Object)(object)realKiller == (Object)null) ? "N/A" : realKiller.GetRealName()); string value27 = (((Object)(object)realKiller == (Object)null) ? "N/A" : Utils.GetRoleName(realKiller.GetCustomRole())); Utils.SendMessage(Translator.GetString("DeathCmd.YourName") + "" + player.GetRealName() + "\n\r" + Translator.GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\r" + Translator.GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(player.PlayerId) + "\n\r\n\r" + Translator.GetString("DeathCmd.KillerName") + "" + text22 + "\n\r" + Translator.GetString("DeathCmd.KillerRole") + "" + $"{value27}" + "", player.PlayerId); break; } case "/t": case "/шаблон": case "/пример": case "/template": if (array.Length > 1) { TemplateManager.SendTemplate(array[1], player.PlayerId); } else { Utils.SendMessage(Translator.GetString("ForExample") + ":\n" + array[0] + " test", player.PlayerId); } break; case "/цвет": case "/colour": case "/color": case "/cor": if (Options.PlayerCanSetColor.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().ColorCmd || Utils.IsPlayerVIP(player.FriendCode)) { if (GameStates.IsInGame) { Utils.SendMessage(Translator.GetString("Message.OnlyCanUseInLobby"), player.PlayerId); break; } text3 = ((array.Length < 2) ? "" : array[1]); byte b = Utils.MsgToColor(text3); if (b == byte.MaxValue) { Utils.SendMessage(Translator.GetString("IllegalColor"), player.PlayerId); break; } player.RpcSetColor(b); Utils.SendMessage(string.Format(Translator.GetString("Message.SetColor"), text3), player.PlayerId); } else { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); } break; case "/quit": case "/sair": case "/qt": if (Options.PlayerCanUseQuitCommand.GetBool()) { text3 = ((array.Length < 2) ? "" : array[1]); string text9 = player.PlayerId.ToString(); text9 = ((text9.Length != 1) ? text9.Substring(1, 1) : text9); if (text3.Equals(text9)) { string realName = player.GetRealName(); Utils.SendMessage(string.Format(Translator.GetString("Message.PlayerQuitForever"), realName)); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(player.GetClientId(), true); } else { Utils.SendMessage(string.Format(Translator.GetString("SureUse.quit"), text9), player.PlayerId); } } else { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); } break; case "/айди": case "/id": { if (Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) { break; } string text15 = Translator.GetString("PlayerIdList"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls) { if (!((Object)(object)val2 == (Object)null)) { text15 = text15 + "\n" + val2.PlayerId + " → " + val2.GetRealName(); } } Utils.SendMessage(text15, player.PlayerId); break; } case "/mid": { if (Options.ApplyModeratorList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("midCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("midCommandNoAccess"), player.PlayerId); break; } string text16 = Translator.GetString("PlayerIdList"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val3 in allPlayerControls) { if (!((Object)(object)val3 == (Object)null)) { text16 = text16 + "\n" + val3.PlayerId + " → " + val3.GetRealName(); } } Utils.SendMessage(text16, player.PlayerId); break; } case "/banir": case "/ban": case "/бан": case "/забанить": { if (Options.ApplyModeratorList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("BanCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("BanCommandNoAccess"), player.PlayerId); break; } if (array.Length < 3) { Utils.SendMessage(Translator.GetString("BanCommandNoReason"), player.PlayerId); break; } text3 = array[1]; string value11 = string.Join(" ", array.Skip(2)); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result7)) { Utils.SendMessage(Translator.GetString("BanCommandInvalidID"), player.PlayerId); break; } if (result7 == 0) { Utils.SendMessage(Translator.GetString("BanCommandBanHost"), player.PlayerId); break; } PlayerControl playerById3 = Utils.GetPlayerById(result7); if ((Object)(object)playerById3 == (Object)null) { Utils.SendMessage(Translator.GetString("BanCommandInvalidID"), player.PlayerId); break; } if (Utils.IsPlayerModerator(playerById3.FriendCode)) { Utils.SendMessage(Translator.GetString("BanCommandBanMod"), player.PlayerId); break; } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(playerById3.GetClientId(), true); string realName3 = playerById3.GetRealName(); string text12 = $"{realName3} {Translator.GetString("BanCommandBanned")}{((Object)player).name} \nReason: {value11}\n"; if (GameStates.IsInGame) { text12 = text12 + " " + Translator.GetString("BanCommandBannedRole") + " " + Translator.GetString(playerById3.GetCustomRole().ToString()); } Utils.SendMessage(text12); string value12; string value13 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value12) ? value12 : ""); string value14; string value15 = (Main.AllPlayerNames.TryGetValue(playerById3.PlayerId, out value14) ? value14 : ""); string value16 = player.FriendCode.ToString(); string value17 = playerById3.FriendCode.ToString(); string hashedPuid2 = playerById3.GetClient().GetHashedPuid(); string text13 = $"[{DateTime.Now}] {value16},{value13} Banned: {value17},{hashedPuid2},{value15} Reason: {value11}"; File.AppendAllText(modLogFiles, text13 + Environment.NewLine); break; } case "/warn": case "/варн": case "/пред": case "/aviso": case "/предупредить": { if (Options.ApplyModeratorList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("WarnCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("WarnCommandNoAccess"), player.PlayerId); break; } text3 = ((array.Length < 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result8)) { Utils.SendMessage(Translator.GetString("WarnCommandInvalidID"), player.PlayerId); break; } if (result8 == 0) { Utils.SendMessage(Translator.GetString("WarnCommandWarnHost"), player.PlayerId); break; } PlayerControl playerById4 = Utils.GetPlayerById(result8); if ((Object)(object)playerById4 == (Object)null) { Utils.SendMessage(Translator.GetString("WarnCommandInvalidID"), player.PlayerId); break; } if (Utils.IsPlayerModerator(playerById4.FriendCode)) { Utils.SendMessage(Translator.GetString("WarnCommandWarnMod"), player.PlayerId); break; } string value18 = "Reason : Not specified\n"; string realName4 = playerById4.GetRealName(); if (array.Length > 2) { value18 = "Reason : " + string.Join(" ", array.Skip(2)) + "\n"; } else { Utils.SendMessage("Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", player.PlayerId); } Utils.SendMessage($" {realName4} {Translator.GetString("WarnCommandWarned")} {value18} ~{((Object)player).name}"); string value19; string value20 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value19) ? value19 : ""); string value21; string value22 = (Main.AllPlayerNames.TryGetValue(playerById4.PlayerId, out value21) ? value21 : ""); string value23 = player.FriendCode.ToString(); string value24 = playerById4.FriendCode.ToString(); string hashedPuid3 = playerById4.GetClient().GetHashedPuid(); string text14 = $"[{DateTime.Now}] {value23},{value20} Warned: {value24},{hashedPuid3},{value22} Reason: {value18}"; File.AppendAllText(modLogFiles, text14 + Environment.NewLine); break; } case "/kick": case "/кикнуть": case "/выгнать": case "/кик": case "/expulsar": { if (Options.ApplyModeratorList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("KickCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("KickCommandNoAccess"), player.PlayerId); break; } text3 = ((array.Length < 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !byte.TryParse(text3, out var result6)) { Utils.SendMessage(Translator.GetString("KickCommandInvalidID"), player.PlayerId); break; } if (result6 == 0) { Utils.SendMessage(Translator.GetString("KickCommandKickHost"), player.PlayerId); break; } PlayerControl playerById2 = Utils.GetPlayerById(result6); if ((Object)(object)playerById2 == (Object)null) { Utils.SendMessage(Translator.GetString("KickCommandInvalidID"), player.PlayerId); break; } if (Utils.IsPlayerModerator(playerById2.FriendCode)) { Utils.SendMessage(Translator.GetString("KickCommandKickMod"), player.PlayerId); break; } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(playerById2.GetClientId(), false); string realName2 = playerById2.GetRealName(); string value4 = "Reason : Not specified\n"; if (array.Length > 2) { value4 = "Reason : " + string.Join(" ", array.Skip(2)) + "\n"; } else { Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", player.PlayerId); } string text10 = $"{realName2} {Translator.GetString("KickCommandKicked")} {((Object)player).name} \n {value4}"; if (GameStates.IsInGame) { text10 = text10 + " " + Translator.GetString("KickCommandKickedRole") + " " + Translator.GetString(playerById2.GetCustomRole().ToString()); } Utils.SendMessage(text10); string value5; string value6 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value5) ? value5 : ""); string value7; string value8 = (Main.AllPlayerNames.TryGetValue(playerById2.PlayerId, out value7) ? value7 : ""); string value9 = player.FriendCode.ToString(); string value10 = playerById2.FriendCode.ToString(); string hashedPuid = playerById2.GetClient().GetHashedPuid(); string text11 = $"[{DateTime.Now}] {value9},{value6} Kicked: {value10},{hashedPuid},{value8} Reason: {value4}"; File.AppendAllText(modLogFiles, text11 + Environment.NewLine); break; } case "/modcolour": case "/modcolor": { if (Options.ApplyModeratorList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("ColorCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("ColorCommandNoAccess"), player.PlayerId); break; } if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("ColorCommandNoLobby"), player.PlayerId); break; } if (!Options.GradientTagsOpt.GetBool()) { text3 = ((array.Length != 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !Utils.CheckColorHex(text3)) { Logger.Msg(text3 ?? "", "modcolor", escapeCRLF: true, 2479, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("ColorInvalidHexCode"), player.PlayerId); break; } string path3 = modTagsFiles + "/" + player.FriendCode + ".txt"; if (!File.Exists(path3)) { Logger.Warn($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor", escapeCRLF: true, 2486, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(path3).Close(); } File.WriteAllText(path3, text3 ?? ""); break; } text3 = ((array.Length < 3) ? "" : (array[1] + " " + array[2])); Regex regex2 = new Regex("^[0-9A-Fa-f]{6}\\s[0-9A-Fa-f]{6}$"); if (string.IsNullOrEmpty(text3) || !regex2.IsMatch(text3)) { Logger.Msg(text3 ?? "", "modcolor", escapeCRLF: true, 2499, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("ColorInvalidGradientCode"), player.PlayerId); break; } string path4 = modTagsFiles + "/" + player.FriendCode + ".txt"; if (!File.Exists(path4)) { Logger.Msg($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor", escapeCRLF: true, 2506, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(path4).Close(); } File.WriteAllText(path4, text3 ?? ""); break; } case "/vipcolour": case "/vipcolor": { if (Options.ApplyVipList.GetValue() == 0) { Utils.SendMessage(Translator.GetString("VipColorCommandDisabled"), player.PlayerId); break; } if (!Utils.IsPlayerVIP(player.FriendCode)) { Utils.SendMessage(Translator.GetString("VipColorCommandNoAccess"), player.PlayerId); break; } if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("VipColorCommandNoLobby"), player.PlayerId); break; } if (!Options.GradientTagsOpt.GetBool()) { text3 = ((array.Length != 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !Utils.CheckColorHex(text3)) { Logger.Msg(text3 ?? "", "vipcolor", escapeCRLF: true, 2536, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("VipColorInvalidHexCode"), player.PlayerId); break; } string path = vipTagsFiles + "/" + player.FriendCode + ".txt"; if (!File.Exists(path)) { Logger.Warn($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor", escapeCRLF: true, 2543, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(path).Close(); } File.WriteAllText(path, text3 ?? ""); break; } text3 = ((array.Length < 3) ? "" : (array[1] + " " + array[2])); Regex regex = new Regex("^[0-9A-Fa-f]{6}\\s[0-9A-Fa-f]{6}$"); if (string.IsNullOrEmpty(text3) || !regex.IsMatch(text3)) { Logger.Msg(text3 ?? "", "vipcolor", escapeCRLF: true, 2556, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("VipColorInvalidGradientCode"), player.PlayerId); break; } string path2 = vipTagsFiles + "/" + player.FriendCode + ".txt"; if (!File.Exists(path2)) { Logger.Msg($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor", escapeCRLF: true, 2563, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(path2).Close(); } File.WriteAllText(path2, text3 ?? ""); break; } case "/tagcolour": case "/tagcolor": { string value26; string text20 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value26) ? value26 : ""); if (text20 == "" || text20.Contains('\r') || !player.FriendCode.GetDevUser().HasTag()) { break; } if (!GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("ColorCommandNoLobby"), player.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); if (string.IsNullOrEmpty(text3) || !Utils.CheckColorHex(text3)) { Logger.Msg(text3 ?? "", "tagcolor", escapeCRLF: true, 2585, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); Utils.SendMessage(Translator.GetString("TagColorInvalidHexCode"), player.PlayerId); break; } string text21 = sponsorTagsFiles + "/" + player.FriendCode + ".txt"; if (!File.Exists(text21)) { Logger.Msg("File Not exist, creating file at " + text21, "tagcolor", escapeCRLF: true, 2592, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ChatCommandPatch.cs"); File.Create(text21).Close(); } File.WriteAllText(text21, text3 ?? ""); break; } case "/xf": { if (GameStates.IsLobby) { Utils.SendMessage(Translator.GetString("Message.CanNotUseInLobby"), player.PlayerId); break; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!val.IsAlive()) { val.RpcSetNameEx(val.GetRealName(isMeeting: true)); } } ChatUpdatePatch.DoBlockChat = false; Utils.SendMessage(Translator.GetString("Message.TryFixName"), player.PlayerId); break; } case "/tpout": if (GameStates.IsLobby) { if (!Options.PlayerCanUseTP.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); } else { player.RpcTeleport(new Vector2(0.1f, 3.8f)); } } break; case "/tpin": if (GameStates.IsLobby) { if (!Options.PlayerCanUseTP.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); } else { player.RpcTeleport(new Vector2(-0.2f, 1.3f)); } } break; case "/s": case "/с": case "/сказать": case "/say": if (player.FriendCode.GetDevUser().IsDev) { if (array.Length > 1) { Utils.SendMessage(GeneralExtensions.Join(array.Skip(1), (Func)null, " "), byte.MaxValue, $"{Translator.GetString("MessageFromDev")} ~ {player.GetRealName(isMeeting: false, clientData: true)}"); } } else if (player.FriendCode.IsDevUser() && !dbConnect.IsBooster(player.FriendCode)) { if (array.Length > 1) { Utils.SendMessage(GeneralExtensions.Join(array.Skip(1), (Func)null, " "), byte.MaxValue, $"{Translator.GetString("MessageFromSponsor")} ~ {player.GetRealName(isMeeting: false, clientData: true)}"); } } else { if (!Utils.IsPlayerModerator(player.FriendCode)) { break; } if (Options.ApplyModeratorList.GetValue() == 0 || !Options.AllowSayCommand.GetBool()) { Utils.SendMessage(Translator.GetString("SayCommandDisabled"), player.PlayerId); break; } if (array.Length > 1) { Utils.SendMessage(GeneralExtensions.Join(array.Skip(1), (Func)null, " "), byte.MaxValue, $"{Translator.GetString("MessageFromModerator")} ~ {player.GetRealName(isMeeting: false, clientData: true)}"); } string value; string value2 = (Main.AllPlayerNames.TryGetValue(player.PlayerId, out value) ? value : ""); string value3 = player.FriendCode.ToString(); string text8 = $"[{DateTime.Now}] {value3},{value2} used /s: {GeneralExtensions.Join(array.Skip(1), (Func)null, " ")}"; File.AppendAllText(modLogFiles, text8 + Environment.NewLine); } break; case "/rps": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); if (!GameStates.IsLobby && player.IsAlive()) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), player.PlayerId); break; } if (text3 == "" || !int.TryParse(text3, out var result9)) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), player.PlayerId); break; } if (result9 < 0 || result9 > 2) { Utils.SendMessage(Translator.GetString("RpsCommandInfo"), player.PlayerId); break; } int num2 = IRandom.Instance.Next(0, 3); List list = new List { Translator.GetString("Rock"), Translator.GetString("Paper"), Translator.GetString("Scissors") }; if (num2 == result9) { Utils.SendMessage(string.Format(Translator.GetString("RpsDraw"), list[num2]), player.PlayerId); } else if ((num2 == 0 && result9 == 2) || (num2 == 1 && result9 == 0) || (num2 == 2 && result9 == 1)) { Utils.SendMessage(string.Format(Translator.GetString("RpsLose"), list[num2]), player.PlayerId); } else { Utils.SendMessage(string.Format(Translator.GetString("RpsWin"), list[num2]), player.PlayerId); } break; } case "/coinflip": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); break; } if (!GameStates.IsLobby && player.IsAlive()) { Utils.SendMessage(Translator.GetString("CoinflipCommandInfo"), player.PlayerId); break; } string arg = ((IRandom.Instance.Next(1, 101) < 51) ? Translator.GetString("Heads") : Translator.GetString("Tails")); Utils.SendMessage(string.Format(Translator.GetString("CoinFlipResult"), arg), player.PlayerId); break; } case "/gno": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); break; } if (!GameStates.IsLobby && player.IsAlive()) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), player.PlayerId); break; } text3 = ((array.Length != 2) ? "" : array[1]); if (text3 == "" || !int.TryParse(text3, out var result10)) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), player.PlayerId); break; } if (result10 < 0 || result10 > 99) { Utils.SendMessage(Translator.GetString("GNoCommandInfo"), player.PlayerId); break; } int num3 = Main.GuessNumber[player.PlayerId][0]; if (Main.GuessNumber[player.PlayerId][0] == -1) { IRandom instance = IRandom.Instance; Main.GuessNumber[player.PlayerId][0] = instance.Next(0, 100); num3 = Main.GuessNumber[player.PlayerId][0]; } Main.GuessNumber[player.PlayerId][1]--; if (Main.GuessNumber[player.PlayerId][1] == 0 && result10 != num3) { Main.GuessNumber[player.PlayerId][0] = -1; Main.GuessNumber[player.PlayerId][1] = 7; Utils.SendMessage(string.Format(Translator.GetString("GNoLost"), num3), player.PlayerId); } else if (result10 < num3) { Utils.SendMessage(string.Format(Translator.GetString("GNoLow"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); } else if (result10 > num3) { Utils.SendMessage(string.Format(Translator.GetString("GNoHigh"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); } else { Utils.SendMessage(string.Format(Translator.GetString("GNoWon"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); Main.GuessNumber[player.PlayerId][0] = -1; Main.GuessNumber[player.PlayerId][1] = 7; } break; } case "/rand": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); break; } text3 = ((array.Length != 3) ? "" : array[1]); text4 = ((array.Length != 3) ? "" : array[2]); if (!GameStates.IsLobby && player.IsAlive()) { Utils.SendMessage(Translator.GetString("RandCommandInfo"), player.PlayerId); break; } if (text3 == "" || !int.TryParse(text3, out var result2) || text4 == "" || !int.TryParse(text4, out var result3)) { Utils.SendMessage(Translator.GetString("RandCommandInfo"), player.PlayerId); break; } int num = IRandom.Instance.Next(result2, result3 + 1); Utils.SendMessage(string.Format(Translator.GetString("RandResult"), num), player.PlayerId); break; } case "/8ball": { if (!Options.CanPlayMiniGames.GetBool()) { Utils.SendMessage(Translator.GetString("DisableUseCommand"), player.PlayerId); break; } canceled = true; int num4 = IRandom.Instance.Next(0, 16); string text23 = ""; switch (num4) { case 0: text23 = Translator.GetString("8BallYes"); break; case 1: text23 = Translator.GetString("8BallNo"); break; case 2: text23 = Translator.GetString("8BallMaybe"); break; case 3: text23 = Translator.GetString("8BallTryAgainLater"); break; case 4: text23 = Translator.GetString("8BallCertain"); break; case 5: text23 = Translator.GetString("8BallNotLikely"); break; case 6: text23 = Translator.GetString("8BallLikely"); break; case 7: text23 = Translator.GetString("8BallDontCount"); break; case 8: text23 = Translator.GetString("8BallStop"); break; case 9: text23 = Translator.GetString("8BallPossibly"); break; case 10: text23 = Translator.GetString("8BallProbably"); break; case 11: text23 = Translator.GetString("8BallProbablyNot"); break; case 12: text23 = Translator.GetString("8BallBetterNotTell"); break; case 13: text23 = Translator.GetString("8BallCantPredict"); break; case 14: text23 = Translator.GetString("8BallWithoutDoubt"); break; case 15: text23 = Translator.GetString("8BallWithDoubt"); break; } Utils.SendMessage("" + text23 + "", player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("8BallTitle"))); break; } case "/me": { string text5 = (player.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"); string text6 = (player.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"); string text7 = (player.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"); text3 = ((text.Length == 3) ? string.Empty : text.Remove(0, 3)); byte result; if (string.IsNullOrEmpty(text3)) { Utils.SendMessage((player.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + string.Format(Translator.GetString("Message.MeCommandInfo"), player.PlayerId, player.GetRealName(isMeeting: false, clientData: true), player.GetClient().FriendCode, player.GetClient().GetHashedPuid(), player.FriendCode.GetDevUser().GetUserType(), text5, text6, text7), player.PlayerId); } else if (Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) { Utils.SendMessage(Translator.GetString("Message.MeCommandNoPermission"), player.PlayerId); } else if (byte.TryParse(text3, out result)) { if (result != player.PlayerId) { PlayerControl playerById = Utils.GetPlayerById(result); if ((Object)(object)playerById != (Object)null && playerById.GetClient() != null) { Utils.SendMessage(string.Format(Translator.GetString("Message.MeCommandTargetInfo"), playerById.PlayerId, playerById.GetRealName(isMeeting: false, clientData: true), playerById.GetClient().FriendCode, playerById.GetClient().GetHashedPuid(), playerById.FriendCode.GetDevUser().GetUserType()) ?? "", player.PlayerId); } else { Utils.SendMessage(Translator.GetString("Message.MeCommandInvalidID") ?? "", player.PlayerId); } } else { Utils.SendMessage(string.Format(Translator.GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(isMeeting: false, clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), text5, text6, text7) ?? "", player.PlayerId); } } else { Utils.SendMessage(Translator.GetString("Message.MeCommandInvalidID") ?? "", player.PlayerId); } break; } default: SpamManager.CheckSpam(player, text); break; } } } [HarmonyPatch(typeof(ChatController), "Update")] internal class ChatUpdatePatch { public static bool DoBlockChat; public static ChatController Instance; public static void Postfix(ChatController __instance) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || Main.MessagesToSend.Count == 0 || (Main.MessagesToSend[0].Item2 == byte.MaxValue && (float)Main.MessageWait.Value > __instance.timeSinceLastMessage) || DoBlockChat) { return; } if (Instance == null) { Instance = __instance; } if (Main.DarkTheme.Value) { ChatBubble obj = ((Il2CppObjectBase)__instance.chatBubblePool.Prefab).Cast(); ((TMP_Text)obj.TextArea).overrideColorTags = false; ((Graphic)obj.TextArea).color = Color.white; obj.Background.color = Color.black; } PlayerControl val = PlayerControl.LocalPlayer; if (GameStates.IsInGame || val.Data.IsDead) { val = (from x in Main.AllAlivePlayerControls.ToArray() orderby x.PlayerId select x).FirstOrDefault() ?? (from x in Main.AllPlayerControls.ToArray() orderby x.PlayerId select x).FirstOrDefault() ?? val; } if ((Object)(object)val == (Object)null) { return; } var (text, b, text2) = Main.MessagesToSend[0]; if (b != byte.MaxValue && GameStates.IsLobby && (Object)(object)Utils.GetPlayerInfoById(b) != (Object)null && Utils.GetPlayerInfoById(b).DefaultOutfit.ColorId == -1) { (string, byte, string) item = Main.MessagesToSend[0]; Main.MessagesToSend.RemoveAt(0); Main.MessagesToSend.Add(item); return; } Main.MessagesToSend.RemoveAt(0); int num = ((b == byte.MaxValue) ? (-1) : Utils.GetPlayerById(b).GetClientId()); string playerName = val.Data.PlayerName; if (num == -1) { val.SetName(text2); DestroyableSingleton.Instance.Chat.AddChat(val, text, false); val.SetName(playerName); } CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(num); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(text2) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(text).EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(val.Data.PlayerName) .EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); __instance.timeSinceLastMessage = 0f; } } [HarmonyPatch(typeof(ChatController), "AddChat")] internal class AddChatPatch { public static void Postfix(string chatText) { _ = ((InnerNetClient)AmongUsClient.Instance).AmHost; } } [HarmonyPatch(typeof(FreeChatInputField), "UpdateCharCount")] internal class UpdateCharCountPatch { public static void Postfix(FreeChatInputField __instance) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) int length = __instance.textArea.text.Length; ((TMP_Text)__instance.charCountText).SetText($"{length}/{__instance.textArea.characterLimit}", true); if (length < (((InnerNetClient)AmongUsClient.Instance).AmHost ? 888 : 250)) { ((Graphic)__instance.charCountText).color = Color.black; } else if (length < (((InnerNetClient)AmongUsClient.Instance).AmHost ? 999 : 300)) { ((Graphic)__instance.charCountText).color = new Color(1f, 1f, 0f, 1f); } else { ((Graphic)__instance.charCountText).color = Color.red; } } } [HarmonyPatch(typeof(PlayerControl), "RpcSendChat")] internal class RpcSendChatPatch { public static bool Prefix(PlayerControl __instance, string chatText, ref bool __result) { if (string.IsNullOrWhiteSpace(chatText)) { __result = false; return false; } if (!GameStates.IsModHost) { __result = false; return true; } int count = ((Object)PlayerControl.LocalPlayer).name.Count((char x) => x == '\n'); chatText = new StringBuilder(chatText).Insert(0, "\n", count).ToString(); if (((InnerNetClient)AmongUsClient.Instance).AmClient && Object.op_Implicit((Object)(object)DestroyableSingleton.Instance)) { DestroyableSingleton.Instance.Chat.AddChat(__instance, chatText, true); } if (chatText.Contains("who", StringComparison.OrdinalIgnoreCase)) { DestroyableSingleton.Instance.SendWho(); } MessageWriter obj = ((InnerNetClient)AmongUsClient.Instance).StartRpc(((InnerNetObject)__instance).NetId, (byte)13, (SendOption)0); obj.Write(chatText); obj.EndMessage(); __result = true; return false; } } [HarmonyPatch(typeof(ChatController), "Update")] internal class ChatControllerUpdatePatch { public static int CurrentHistorySelection = -1; private static readonly Dictionary replaceDic = new Dictionary { { "(", " (" }, { ")", ") " }, { ",", ", " }, { ":", ": " }, { "[", "【" }, { "]", "】" }, { "‘", " '" }, { "’", "' " }, { "“", " ''" }, { "”", "'' " }, { "!", "! " }, { Environment.NewLine, " " } }; public static void Prefix() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (((InnerNetClient)AmongUsClient.Instance).AmHost && (int)DataManager.Settings.Multiplayer.ChatMode == 2) { DataManager.Settings.Multiplayer.ChatMode = (QuickChatModes)1; } } public static void Postfix(ChatController __instance) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (Main.DarkTheme.Value) { ((AbstractChatInputField)__instance.freeChatField).background.color = Color32.op_Implicit(new Color32((byte)40, (byte)40, (byte)40, byte.MaxValue)); StringExtensions.Color(__instance.freeChatField.textArea.compoText, Color.white); ((Graphic)__instance.freeChatField.textArea.outputText).color = Color.white; ((AbstractChatInputField)__instance.quickChatField).background.color = Color32.op_Implicit(new Color32((byte)40, (byte)40, (byte)40, byte.MaxValue)); ((Graphic)__instance.quickChatField.text).color = Color.white; } else { ((Graphic)__instance.freeChatField.textArea.outputText).color = Color.black; } if (!__instance.freeChatField.textArea.hasFocus || !GameStates.IsModHost) { return; } __instance.freeChatField.textArea.characterLimit = (((InnerNetClient)AmongUsClient.Instance).AmHost ? 999 : 300); if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)99)) { ClipboardHelper.PutClipboardString(__instance.freeChatField.textArea.text); } if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)118) && !string.IsNullOrEmpty(GUIUtility.systemCopyBuffer)) { string text = GUIUtility.systemCopyBuffer; foreach (KeyValuePair item in replaceDic) { text = text.Replace(item.Key, item.Value); } if ((__instance.freeChatField.textArea.text + text).Length < __instance.freeChatField.textArea.characterLimit) { __instance.freeChatField.textArea.SetText(__instance.freeChatField.textArea.text + text, ""); } else { int num = __instance.freeChatField.textArea.characterLimit - __instance.freeChatField.textArea.text.Length; if (num > 0) { string text2 = text.Substring(0, num); __instance.freeChatField.textArea.SetText(__instance.freeChatField.textArea.text + text2, ""); } } } if ((Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) && Input.GetKeyDown((KeyCode)120)) { ClipboardHelper.PutClipboardString(__instance.freeChatField.textArea.text); __instance.freeChatField.textArea.SetText("", ""); } if (Input.GetKeyDown((KeyCode)273) && ChatCommands.ChatHistory.Any()) { CurrentHistorySelection = Mathf.Clamp(--CurrentHistorySelection, 0, ChatCommands.ChatHistory.Count - 1); __instance.freeChatField.textArea.SetText(ChatCommands.ChatHistory[CurrentHistorySelection], ""); } if (Input.GetKeyDown((KeyCode)274) && ChatCommands.ChatHistory.Any()) { CurrentHistorySelection++; if (CurrentHistorySelection < ChatCommands.ChatHistory.Count) { __instance.freeChatField.textArea.SetText(ChatCommands.ChatHistory[CurrentHistorySelection], ""); } else { __instance.freeChatField.textArea.SetText("", ""); } } } } [HarmonyPatch(typeof(GameManager), "CheckEndGameViaTasks")] internal class CheckEndGameViaTasksForNormalPatch { public static bool Prefix(ref bool __result) { __result = false; return false; } } [HarmonyPatch(typeof(LogicGameFlowNormal), "CheckEndCriteria")] internal class GameEndCheckerForNormal { private class NormalGameEndPredicate : GameEndPredicate { public override bool CheckForEndGame(out GameOverReason reason) { reason = (GameOverReason)3; if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default) { return false; } if (CheckGameEndByLivingPlayers(out reason) || CheckGameEndByTask(out reason) || CheckGameEndBySabotage(out reason)) { return true; } return false; } public static bool CheckGameEndByLivingPlayers(out GameOverReason reason) { reason = (GameOverReason)3; if (Sunnyboy.HasEnabled && Sunnyboy.CheckGameEnd()) { return false; } Dictionary dictionary = new Dictionary(); PlayerControl[] array = Main.AllAlivePlayerControls.ToArray(); int num = 0; int num2 = 0; int num3 = 0; PlayerControl[] array2 = array; foreach (PlayerControl val in array2) { if ((Object)(object)val == (Object)null) { continue; } num = (Paranoia.IsExistInGame(val) ? 1 : 0); CountTypes countTypes = Main.PlayerStates[val.PlayerId].countTypes; switch (countTypes) { case CountTypes.Impostor: num2++; num2 += num; continue; case CountTypes.Crew: num3++; num3 += num; continue; case CountTypes.OutOfGame: case CountTypes.None: continue; } if (dictionary.ContainsKey(countTypes)) { dictionary[countTypes]++; } else { dictionary[countTypes] = 1; } dictionary[countTypes] += num; } int totalNKAlive = dictionary.Sum((KeyValuePair kvp) => kvp.Value); if (num3 == 0 && num2 == 0 && totalNKAlive == 0) { reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.None); return true; } if (Main.AllAlivePlayerControls.Length != 0 && Main.AllAlivePlayerControls.All((PlayerControl p) => p.Is(CustomRoles.Lovers))) { reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Lovers); return true; } if (totalNKAlive == 0) { if (num3 <= num2) { reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Impostor); } else if (num2 == 0) { reason = (GameOverReason)0; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Crewmate); } else if (num3 > num2) { return false; } return true; } if (num2 >= 1) { return false; } if (num3 > totalNKAlive) { return false; } KeyValuePair[] array3 = dictionary.Where((KeyValuePair kvp) => kvp.Value == totalNKAlive).ToArray(); switch (array3.Length) { case 1: { CustomRoles neutralCustomRoleFromCountType = array3.First().Key.GetNeutralCustomRoleFromCountType(); reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(neutralCustomRoleFromCountType.GetNeutralCustomWinnerFromRole()); CustomWinnerHolder.WinnerRoles.Add(neutralCustomRoleFromCountType); break; } case 0: return false; } return true; } } public static GameEndPredicate predicate; public static bool ShowAllRolesWhenGameEnd; public static bool ShouldNotCheck; public static bool ForEndGame; private const float EndGameDelay = 0.3f; public static bool Prefix() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Invalid comparison between Unknown and I4 //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_12b5: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Invalid comparison between Unknown and I4 //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_0733: Unknown result type (might be due to invalid IL or missing references) //IL_07a4: Unknown result type (might be due to invalid IL or missing references) //IL_0665: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (predicate == null || ShouldNotCheck) { return false; } if (Options.NoGameEnd.GetBool()) { CustomWinner winnerTeam = CustomWinnerHolder.WinnerTeam; if (winnerTeam != CustomWinner.Draw && winnerTeam != CustomWinner.Error) { return false; } } ShowAllRolesWhenGameEnd = false; GameOverReason reason = (GameOverReason)3; predicate.CheckForEndGame(out reason); if (Options.CurrentGameMode == CustomGameMode.FFA) { if (CustomWinnerHolder.WinnerIds.Count > 0 || CustomWinnerHolder.WinnerTeam != CustomWinner.Default) { ((Behaviour)ShipStatus.Instance).enabled = false; StartEndGame(reason); predicate = null; } return false; } if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default) { NameNotifyManager.Reset(); CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl pc) { Camouflage.RpcSetSkin(pc, ForceRevert: true, RevertToDefault: true, GameEnd: true); }); ShowAllRolesWhenGameEnd = true; Utils.DoNotifyRoles(null, null, isForMeeting: false, NoCache: true); Logger.Info("Start end game", "CheckEndCriteria.Prefix", escapeCRLF: true, 70, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); if ((int)reason == 4 && (CustomRoles.Jackal.RoleExist() || CustomRoles.Sidekick.RoleExist()) && Jackal.CanWinBySabotageWhenNoImpAlive.GetBool() && !Main.AllAlivePlayerControls.Any((PlayerControl x) => x.GetCustomRole().IsImpostorTeam())) { reason = (GameOverReason)3; CustomWinnerHolder.WinnerIds.Clear(); CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Jackal); CustomWinnerHolder.WinnerRoles.Add(CustomRoles.Jackal); } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { CountTypes countTypes = Main.PlayerStates[val.PlayerId].countTypes; switch (CustomWinnerHolder.WinnerTeam) { case CustomWinner.Crewmate: if ((val.Is(Custom_Team.Crewmate) && (countTypes == CountTypes.Crew || val.Is(CustomRoles.Soulless))) || (val.Is(CustomRoles.Admired) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId))) { if ((int)reason != 0 && (int)reason != 1) { reason = (GameOverReason)0; } CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Impostor: if (((val.Is(Custom_Team.Impostor) || val.GetCustomRole().IsMadmate()) && (countTypes == CountTypes.Impostor || val.Is(CustomRoles.Soulless))) || (val.Is(CustomRoles.Madmate) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId))) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Cultist: if ((val.Is(CustomRoles.Charmed) || val.Is(CustomRoles.Cultist)) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.CursedSoul: if (val.Is(CustomRoles.Soulless) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Infectious: if ((val.Is(CustomRoles.Infected) || val.Is(CustomRoles.Infectious)) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.PlagueDoctor: if (val.Is(CustomRoles.PlagueDoctor) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Virus: if ((val.Is(CustomRoles.Contagious) || val.Is(CustomRoles.Virus)) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Jackal: if ((val.Is(CustomRoles.Sidekick) || val.Is(CustomRoles.Recruit) || val.Is(CustomRoles.Jackal)) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.Spiritcaller: if (val.Is(CustomRoles.EvilSpirit) && !CustomWinnerHolder.WinnerIds.Contains(val.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } break; case CustomWinner.RuthlessRomantic: if (val.Is(CustomRoles.RuthlessRomantic) && !CustomWinnerHolder.WinnerIds.Contains(Romantic.BetPlayer[val.PlayerId])) { CustomWinnerHolder.WinnerIds.Add(Romantic.BetPlayer[val.PlayerId]); } break; } } CustomWinner winnerTeam = CustomWinnerHolder.WinnerTeam; if (winnerTeam != CustomWinner.Draw && winnerTeam != CustomWinner.None && winnerTeam != CustomWinner.Error) { allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls) { switch (val2.GetCustomRole()) { case CustomRoles.Stalker: if (val2.IsAlive() && ((CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor && !((object)(GameOverReason)(ref reason)).Equals((object)(GameOverReason)4)) || CustomWinnerHolder.WinnerTeam == CustomWinner.Stalker || (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate && !((object)(GameOverReason)(ref reason)).Equals((object)(GameOverReason)1) && Stalker.IsWinKill[val2.PlayerId] && Stalker.SnatchesWin.GetBool())) && !CustomWinnerHolder.CheckForConvertedWinner(val2.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Stalker); CustomWinnerHolder.WinnerIds.Add(val2.PlayerId); } break; case CustomRoles.Specter: if (val2.GetPlayerTaskState().IsTaskFinished && !val2.IsAlive() && Specter.SnatchesWin.GetBool()) { reason = (GameOverReason)3; if (!CustomWinnerHolder.CheckForConvertedWinner(val2.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Specter); CustomWinnerHolder.WinnerIds.Add(val2.PlayerId); } } break; case CustomRoles.CursedSoul: if (val2.IsAlive()) { reason = (GameOverReason)3; if (!CustomWinnerHolder.CheckForConvertedWinner(val2.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.CursedSoul); CustomWinnerHolder.WinnerRoles.Add(CustomRoles.Soulless); CustomWinnerHolder.WinnerIds.Add(val2.PlayerId); } else { CustomWinnerHolder.WinnerRoles.Add(CustomRoles.Soulless); } } break; } } if (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate) { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => (Object)(object)x != (Object)null && x.GetCustomRole().IsCrewmate() && x.Is(CustomRoles.Egoist)).ToArray(); if (array.Length != 0) { reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Egoist); allPlayerControls = array; foreach (PlayerControl val3 in allPlayerControls) { CustomWinnerHolder.WinnerIds.Add(val3.PlayerId); } } } if (CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor) { PlayerControl[] array2 = Main.AllAlivePlayerControls.Where((PlayerControl x) => (Object)(object)x != (Object)null && x.GetCustomRole().IsImpostor() && x.Is(CustomRoles.Egoist)).ToArray(); if (array2.Length != 0) { reason = (GameOverReason)3; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Egoist); allPlayerControls = array2; foreach (PlayerControl val4 in allPlayerControls) { CustomWinnerHolder.WinnerIds.Add(val4.PlayerId); } } } if (CustomRoles.God.RoleExist()) { IEnumerable enumerable = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.God)); if (enumerable.Any()) { bool flag = false; allPlayerControls = enumerable.ToArray(); for (int i = 0; i < allPlayerControls.Length; i++) { if (CustomWinnerHolder.CheckForConvertedWinner(allPlayerControls[i].PlayerId)) { flag = true; break; } } if (!flag) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.God); CollectionExtensions.Do(enumerable, (Action)delegate(PlayerControl p) { CustomWinnerHolder.WinnerIds.Add(p.PlayerId); }); } } } if (CustomRoles.Lovers.RoleExist() && !((object)(GameOverReason)(ref reason)).Equals((object)(GameOverReason)1) && (Main.LoversPlayers.ToArray().All((PlayerControl p) => p.IsAlive()) || !Options.LoverSuicide.GetBool())) { bool flag2; switch (CustomWinnerHolder.WinnerTeam) { case CustomWinner.Crewmate: case CustomWinner.Impostor: case CustomWinner.Jackal: case CustomWinner.Pelican: flag2 = true; break; default: flag2 = false; break; } if (flag2) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Lovers); CollectionExtensions.Do(Main.AllPlayerControls.Where((PlayerControl p) => p.Is(CustomRoles.Lovers)), (Action)delegate(PlayerControl p) { CustomWinnerHolder.WinnerIds.Add(p.PlayerId); }); } } allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val5 in allPlayerControls) { switch (val5.GetCustomRole()) { case CustomRoles.Opportunist: if (val5.IsAlive()) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Opportunist); } break; case CustomRoles.Pixie: if (!CustomWinnerHolder.CheckForConvertedWinner(val5.PlayerId)) { Pixie.PixieWinCondition(val5); } break; case CustomRoles.Shaman: if (val5.IsAlive()) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Shaman); } break; case CustomRoles.Taskinator: if (val5.IsAlive() && CustomWinnerHolder.WinnerTeam != 0) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Taskinator); } break; case CustomRoles.Pursuer: if (val5.IsAlive()) { winnerTeam = CustomWinnerHolder.WinnerTeam; if (winnerTeam != CustomWinner.Jester && winnerTeam != CustomWinner.Lovers && winnerTeam != CustomWinner.Terrorist && winnerTeam != CustomWinner.Executioner && winnerTeam != CustomWinner.Collector && winnerTeam != CustomWinner.Innocent && winnerTeam != CustomWinner.Youtuber) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Pursuer); } } break; case CustomRoles.Sunnyboy: if (!val5.IsAlive()) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Sunnyboy); } break; case CustomRoles.Maverick: if (val5.IsAlive() && Main.PlayerStates[val5.PlayerId].RoleClass is Maverick maverick && maverick.NumKills >= Maverick.MinKillsForWin.GetInt()) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Maverick); } break; case CustomRoles.Specter: if (!Specter.SnatchesWin.GetBool() && !val5.IsAlive() && val5.GetPlayerTaskState().IsTaskFinished) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Specter); } break; case CustomRoles.Provocateur: { if (Provocateur.Provoked.TryGetValue(val5.PlayerId, out var value5) && !CustomWinnerHolder.WinnerIds.Contains(value5)) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Provocateur); } break; } case CustomRoles.Hater: if (Hater.isWon) { CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Hater); byte[] array3 = Hater.playerIdList.ToArray(); foreach (byte item in array3) { CustomWinnerHolder.WinnerIds.Add(item); } } break; case CustomRoles.Romantic: { if (Romantic.BetPlayer.TryGetValue(val5.PlayerId, out var value6) && (CustomWinnerHolder.WinnerIds.Contains(value6) || (Main.PlayerStates.TryGetValue(value6, out var value7) && CustomWinnerHolder.WinnerRoles.Contains(value7.MainRole)))) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Romantic); } break; } case CustomRoles.VengefulRomantic: if (VengefulRomantic.hasKilledKiller) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.WinnerIds.Add(Romantic.BetPlayer[val5.PlayerId]); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.VengefulRomantic); } break; case CustomRoles.Lawyer: { if (Lawyer.Target.TryGetValue(val5.PlayerId, out var value3) && (CustomWinnerHolder.WinnerIds.Contains(value3) || (Main.PlayerStates.TryGetValue(value3, out var value4) && CustomWinnerHolder.WinnerRoles.Contains(value4.MainRole)))) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Lawyer); } break; } case CustomRoles.Follower: { if (Follower.BetPlayer.TryGetValue(val5.PlayerId, out var value) && (CustomWinnerHolder.WinnerIds.Contains(value) || (Main.PlayerStates.TryGetValue(value, out var value2) && CustomWinnerHolder.WinnerRoles.Contains(value2.MainRole)))) { CustomWinnerHolder.WinnerIds.Add(val5.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Follower); } break; } } } if (CustomWinnerHolder.WinnerTeam == CustomWinner.Youtuber) { PlayerControl val6 = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl x) => x.Is(CustomRoles.Youtuber) && CustomWinnerHolder.WinnerIds.Contains(x.PlayerId))); if ((Object)(object)val6 != (Object)null && Youtuber.KillerWinsWithYouTuber.GetBool()) { PlayerControl realKiller = val6.GetRealKiller(); if ((Object)(object)realKiller != (Object)null && !CustomWinnerHolder.WinnerIds.Contains(realKiller.PlayerId)) { CustomWinnerHolder.WinnerIds.Add(realKiller.PlayerId); } } } if (CustomWinnerHolder.WinnerTeam != CustomWinner.Lovers) { allPlayerControls = Main.AllPlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Lovers)).ToArray(); foreach (PlayerControl val7 in allPlayerControls) { if (CustomWinnerHolder.WinnerIds.Any((byte x) => Utils.GetPlayerById(x).Is(CustomRoles.Lovers))) { CustomWinnerHolder.WinnerIds.Add(val7.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Lovers); } } } if (CustomWinnerHolder.WinnerTeam == CustomWinner.Lovers || CustomWinnerHolder.AdditionalWinnerTeams.Contains(AdditionalWinners.Lovers)) { CollectionExtensions.Do(Main.AllPlayerControls.Where((PlayerControl p) => p.Is(CustomRoles.Lovers) && !CustomWinnerHolder.WinnerIds.Contains(p.PlayerId)), (Action)delegate(PlayerControl p) { CustomWinnerHolder.WinnerIds.Add(p.PlayerId); }); } if (Options.NeutralWinTogether.GetBool() && !CustomWinnerHolder.WinnerIds.Any((byte x) => (Object)(object)Utils.GetPlayerById(x) != (Object)null && (Utils.GetPlayerById(x).GetCustomRole().IsCrewmate() || Utils.GetPlayerById(x).GetCustomRole().IsImpostor()))) { allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val8 in allPlayerControls) { if (val8.GetCustomRole().IsNeutral() && !CustomWinnerHolder.WinnerIds.Contains(val8.PlayerId) && !CustomWinnerHolder.WinnerRoles.Contains(val8.GetCustomRole())) { CustomWinnerHolder.WinnerIds.Add(val8.PlayerId); } } } else if (!Options.NeutralWinTogether.GetBool() && Options.NeutralRoleWinTogether.GetBool()) { foreach (byte winnerId in CustomWinnerHolder.WinnerIds) { PlayerControl playerById = Utils.GetPlayerById(winnerId); if ((Object)(object)playerById == (Object)null || !playerById.GetCustomRole().IsNeutral()) { continue; } allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val9 in allPlayerControls) { if (!CustomWinnerHolder.WinnerIds.Contains(val9.PlayerId) && val9.GetCustomRole() == playerById.GetCustomRole()) { CustomWinnerHolder.WinnerIds.Add(val9.PlayerId); } } } } allPlayerControls = Main.AllPlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Hurried)).ToArray(); foreach (PlayerControl val10 in allPlayerControls) { if (!Hurried.CheckWinState(val10) && CustomWinnerHolder.WinnerIds.Contains(val10.PlayerId)) { CustomWinnerHolder.WinnerIds.Remove(val10.PlayerId); Logger.Info("Removed " + val10.GetNameWithRole() + " from winner ids", "Hurried Win Check", escapeCRLF: true, 402, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); } } } Main.AllPlayerControls.Where((PlayerControl pc) => pc.Is(CustomRoles.SchrodingersCat)).ToList().ForEach(SchrodingersCat.SchrodingerWinCondition); ((Behaviour)ShipStatus.Instance).enabled = false; StartEndGame(reason); predicate = null; } return false; } public static void StartEndGame(GameOverReason reason) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)103, (SendOption)1, -1); CustomWinnerHolder.WriteTo(val); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); ((MonoBehaviour)AmongUsClient.Instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoEndGame(AmongUsClient.Instance, reason))); } private static IEnumerator CoEndGame(AmongUsClient self, GameOverReason reason) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) CollectionExtensions.Do((IEnumerable)CustomRoleManager.AllEnabledRoles, (Action)delegate(RoleBase roleClass) { roleClass.OnCoEndGame(); }); ForEndGame = true; List ReviveRequiredPlayerIds = new List(); CustomWinner winnerTeam = CustomWinnerHolder.WinnerTeam; PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl pc in allPlayerControls) { if (winnerTeam == CustomWinner.Draw) { SetGhostRole(ToGhostImpostor: true); continue; } bool num = CustomWinnerHolder.WinnerIds.Contains(pc.PlayerId) || CustomWinnerHolder.WinnerRoles.Contains(pc.GetCustomRole()); bool flag = ((object)(GameOverReason)(ref reason)).Equals((object)(GameOverReason)0) || ((object)(GameOverReason)(ref reason)).Equals((object)(GameOverReason)1); SetGhostRole(num ^ flag); void SetGhostRole(bool ToGhostImpostor) { bool isDead = pc.Data.IsDead; if (!isDead) { ReviveRequiredPlayerIds.Add(pc.PlayerId); } if (ToGhostImpostor) { Logger.Info(pc.GetNameWithRole().RemoveHtmlTags() + ": changed to ImpostorGhost", "ResetRoleAndEndGame", escapeCRLF: true, 456, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); pc.RpcSetRole((RoleTypes)7, false); } else { Logger.Info(pc.GetNameWithRole().RemoveHtmlTags() + ": changed to CrewmateGhost", "ResetRoleAndEndGame", escapeCRLF: true, 461, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); pc.RpcSetRole((RoleTypes)6, false); } pc.Data.IsDead = isDead; } } bool flag2 = ((winnerTeam == CustomWinner.Crewmate || winnerTeam == CustomWinner.Impostor) ? true : false); SetEverythingUpPatch.LastWinsReason = (flag2 ? Translator.GetString($"GameOverReason.{reason}") : ""); yield return (object)new WaitForSeconds(0.3f); if (ReviveRequiredPlayerIds.Count > 0) { for (int j = 0; j < ReviveRequiredPlayerIds.Count; j++) { byte b = ReviveRequiredPlayerIds[j]; NetworkedPlayerInfo playerById = GameData.Instance.GetPlayerById(b); playerById.IsDead = false; playerById.MarkDirty(); ((InnerNetClient)AmongUsClient.Instance).SendAllStreamedObjects(); } yield return (object)new WaitForSeconds(0.3f); } Utils.DoNotifyRoles(null, null, isForMeeting: false, NoCache: true); GameManager.Instance.RpcEndGame(reason, false); } public static void SetPredicateToNormal() { predicate = new NormalGameEndPredicate(); } public static void SetPredicateToFFA() { predicate = new FFAGameEndPredicate(); } } internal class FFAGameEndPredicate : GameEndPredicate { public override bool CheckForEndGame(out GameOverReason reason) { reason = (GameOverReason)3; if (CustomWinnerHolder.WinnerIds.Count > 0) { return false; } if (CheckGameEndByLivingPlayers(out reason)) { return true; } return false; } public static bool CheckGameEndByLivingPlayers(out GameOverReason reason) { reason = (GameOverReason)3; if (FFAManager.RoundTime <= 0) { PlayerControl val = (from x in Main.AllPlayerControls where !x.Is(CustomRoles.GM) && (Object)(object)x != (Object)null orderby FFAManager.GetRankOfScore(x.PlayerId) select x).First(); byte b = (byte)((!((Object)(object)val == (Object)null)) ? val.PlayerId : 0); Logger.Warn("Winner: " + Utils.GetPlayerById(b).GetRealName().RemoveHtmlTags(), "FFA", escapeCRLF: true, 636, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); CustomWinnerHolder.WinnerIds = new HashSet { b }; Main.DoBlockNameChange = true; return true; } if (Main.AllAlivePlayerControls.Length == 1) { PlayerControl val2 = Main.AllAlivePlayerControls.FirstOrDefault(); Logger.Info("Winner: " + val2.GetRealName().RemoveHtmlTags(), "FFA", escapeCRLF: true, 648, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); CustomWinnerHolder.WinnerIds = new HashSet { val2.PlayerId }; Main.DoBlockNameChange = true; return true; } if (Main.AllAlivePlayerControls.Length == 0) { FFAManager.RoundTime = 0; Logger.Warn("No players alive. Force ending the game", "FFA", escapeCRLF: true, 659, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); return false; } return false; } } public abstract class GameEndPredicate { public abstract bool CheckForEndGame(out GameOverReason reason); public virtual bool CheckGameEndByTask(out GameOverReason reason) { reason = (GameOverReason)3; if (Options.DisableTaskWin.GetBool() || TaskState.InitialTotalTasks == 0) { return false; } if (Options.DisableTaskWinIfAllCrewsAreDead.GetBool() && !Main.AllAlivePlayerControls.Any((PlayerControl x) => x.Is(Custom_Team.Crewmate))) { return false; } if (Options.DisableTaskWinIfAllCrewsAreConverted.GetBool() && Main.AllPlayerControls.Where(delegate(PlayerControl x) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected I4, but got Unknown bool flag = x.Is(Custom_Team.Crewmate); if (flag) { RoleTypes roleTypes = x.GetCustomRole().GetRoleTypes(); bool flag2; switch ((int)roleTypes) { case 0: case 2: case 3: case 4: case 6: case 8: case 10: flag2 = true; break; default: flag2 = false; break; } flag = flag2; } return flag; }).All((PlayerControl x) => x.GetCustomSubRoles().Any((CustomRoles y) => y.IsConverted()))) { return false; } if (GameData.Instance.TotalTasks <= GameData.Instance.CompletedTasks) { reason = (GameOverReason)1; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Crewmate); Logger.Info("Game End By Completed All Tasks", "CheckGameEndBySabotage", escapeCRLF: true, 687, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); return true; } return false; } public virtual bool CheckGameEndBySabotage(out GameOverReason reason) { reason = (GameOverReason)3; if (ShipStatus.Instance.Systems == null) { return false; } Dictionary systems = ShipStatus.Instance.Systems; LifeSuppSystemType val; if (systems.ContainsKey((SystemTypes)8) && (val = ((Il2CppObjectBase)systems[(SystemTypes)8]).TryCast()) != null && val.Countdown < 0f) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Impostor); reason = (GameOverReason)4; val.Countdown = 10000f; Logger.Info("Game End By LifeSupp Sabotage", "CheckGameEndBySabotage", escapeCRLF: true, 708, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); return true; } ISystemType val2 = null; if (systems.ContainsKey((SystemTypes)3)) { val2 = systems[(SystemTypes)3]; } else if (systems.ContainsKey((SystemTypes)21)) { val2 = systems[(SystemTypes)21]; } else if (systems.ContainsKey((SystemTypes)58)) { val2 = systems[(SystemTypes)58]; } ICriticalSabotage val3; if (val2 != null && (val3 = ((Il2CppObjectBase)val2).TryCast()) != null && val3.Countdown < 0f) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Impostor); reason = (GameOverReason)4; val3.ClearSabotage(); Logger.Info("Game End By Critical Sabotage", "CheckGameEndBySabotage", escapeCRLF: true, 725, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CheckGameEndPatch.cs"); return true; } return false; } } [HarmonyPatch(typeof(OptionsMenuBehaviour), "Start")] public static class OptionsMenuBehaviourStartPatch { private static ClientOptionItem UnlockFPS; private static ClientOptionItem ShowFPS; private static ClientOptionItem EnableGM; private static ClientOptionItem AutoStart; private static ClientOptionItem DarkTheme; private static ClientOptionItem DisableLobbyMusic; private static ClientOptionItem ShowTextOverlay; private static ClientOptionItem HorseMode; private static ClientOptionItem ForceOwnLanguage; private static ClientOptionItem ForceOwnLanguageRoleName; private static ClientOptionItem EnableCustomButton; private static ClientOptionItem EnableCustomSoundEffect; private static ClientOptionItem EnableCustomDecorations; private static ClientOptionItem SwitchVanilla; public static void Postfix(OptionsMenuBehaviour __instance) { if (!((Object)(object)__instance.DisableMouseMovement == (Object)null)) { Main.SwitchVanilla.Value = false; if (Main.ResetOptions || !DebugModeManager.AmDebugger) { Main.ResetOptions = false; Main.VersionCheat.Value = false; Main.GodMode.Value = false; Main.AutoRehost.Value = false; } if (UnlockFPS == null || (Object)(object)UnlockFPS.ToggleButton == (Object)null) { UnlockFPS = ClientOptionItem.Create("UnlockFPS", Main.UnlockFPS, __instance, UnlockFPSButtonToggle); } if (ShowFPS == null || (Object)(object)ShowFPS.ToggleButton == (Object)null) { ShowFPS = ClientOptionItem.Create("ShowFPS", Main.ShowFPS, __instance); } if (EnableGM == null || (Object)(object)EnableGM.ToggleButton == (Object)null) { EnableGM = ClientOptionItem.Create("GM", Main.EnableGM, __instance); } if (AutoStart == null || (Object)(object)AutoStart.ToggleButton == (Object)null) { AutoStart = ClientOptionItem.Create("AutoStart", Main.AutoStart, __instance, AutoStartButtonToggle); } if (DarkTheme == null || (Object)(object)DarkTheme.ToggleButton == (Object)null) { DarkTheme = ClientOptionItem.Create("DarkTheme", Main.DarkTheme, __instance); } if (DisableLobbyMusic == null || (Object)(object)DisableLobbyMusic.ToggleButton == (Object)null) { DisableLobbyMusic = ClientOptionItem.Create("DisableLobbyMusic", Main.DisableLobbyMusic, __instance); } if (ShowTextOverlay == null || (Object)(object)ShowTextOverlay.ToggleButton == (Object)null) { ShowTextOverlay = ClientOptionItem.Create("ShowTextOverlay", Main.ShowTextOverlay, __instance); } if (HorseMode == null || (Object)(object)HorseMode.ToggleButton == (Object)null) { HorseMode = ClientOptionItem.Create("HorseMode", Main.HorseMode, __instance, SwitchHorseMode); } if (ForceOwnLanguage == null || (Object)(object)ForceOwnLanguage.ToggleButton == (Object)null) { ForceOwnLanguage = ClientOptionItem.Create("ForceOwnLanguage", Main.ForceOwnLanguage, __instance); } if (ForceOwnLanguageRoleName == null || (Object)(object)ForceOwnLanguageRoleName.ToggleButton == (Object)null) { ForceOwnLanguageRoleName = ClientOptionItem.Create("ForceOwnLanguageRoleName", Main.ForceOwnLanguageRoleName, __instance); } if (EnableCustomButton == null || (Object)(object)EnableCustomButton.ToggleButton == (Object)null) { EnableCustomButton = ClientOptionItem.Create("EnableCustomButton", Main.EnableCustomButton, __instance); } if (EnableCustomSoundEffect == null || (Object)(object)EnableCustomSoundEffect.ToggleButton == (Object)null) { EnableCustomSoundEffect = ClientOptionItem.Create("EnableCustomSoundEffect", Main.EnableCustomSoundEffect, __instance); } if (EnableCustomDecorations == null || (Object)(object)EnableCustomDecorations.ToggleButton == (Object)null) { EnableCustomDecorations = ClientOptionItem.Create("EnableCustomDecorations", Main.EnableCustomDecorations, __instance); } if (SwitchVanilla == null || (Object)(object)SwitchVanilla.ToggleButton == (Object)null) { SwitchVanilla = ClientOptionItem.Create("SwitchVanilla", Main.SwitchVanilla, __instance, SwitchVanillaButtonToggle); } } static void AutoStartButtonToggle() { if (!Main.AutoStart.Value && GameStates.IsCountDown) { DestroyableSingleton.Instance.ResetStartState(); Logger.SendInGame(Translator.GetString("CancelStartCountDown")); } } static void SwitchHorseMode() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) HorseMode.UpdateToggle(); Enumerator enumerator = PlayerControl.AllPlayerControls.GetEnumerator(); while (enumerator.MoveNext()) { PlayerControl current = enumerator.Current; current.MyPhysics.SetBodyType(current.BodyType); if ((int)current.BodyType == 0) { ((Component)current.cosmetics.currentBodySprite.BodySprite).transform.localScale = new Vector3(0.5f, 0.5f, 1f); } } } static void SwitchVanillaButtonToggle() { Harmony.UnpatchAll(); ((BasePlugin)Main.Instance).Unload(); } static void UnlockFPSButtonToggle() { Application.targetFrameRate = (Main.UnlockFPS.Value ? 165 : 60); Logger.SendInGame(string.Format(Translator.GetString("FPSSetTo"), Application.targetFrameRate)); } } } [HarmonyPatch(typeof(OptionsMenuBehaviour), "Close")] public static class OptionsMenuBehaviourClosePatch { public static void Postfix() { SpriteRenderer customBackground = ClientOptionItem.CustomBackground; if (customBackground != null) { ((Component)customBackground).gameObject.SetActive(false); } } } [HarmonyPatch(typeof(GameStartManager), "MakePublic")] internal class MakePublicPatch { public static bool Prefix() { if (!Main.AllowPublicRoom) { string @string = Translator.GetString("DisabledByProgram"); Logger.Info(@string, "MakePublicPatch", escapeCRLF: true, 17, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ClientPatch.cs"); Logger.SendInGame(@string); return false; } if (ModUpdater.isBroken || (ModUpdater.hasUpdate && ModUpdater.forceUpdate) || !VersionChecker.IsSupported) { string text = ""; if (!VersionChecker.IsSupported) { text = Translator.GetString("UnsupportedVersion"); } if (ModUpdater.isBroken) { text = Translator.GetString("ModBrokenMessage"); } if (ModUpdater.hasUpdate) { text = Translator.GetString("CanNotJoinPublicRoomNoLatest"); } Logger.Info(text, "MakePublicPatch", escapeCRLF: true, 27, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ClientPatch.cs"); Logger.SendInGame(text); return false; } return true; } } [HarmonyPatch(typeof(MMOnlineManager), "Start")] internal class MMOnlineManagerStartPatch { public static void Postfix() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) if ((!ModUpdater.hasUpdate || !ModUpdater.forceUpdate) && !ModUpdater.isBroken && VersionChecker.IsSupported) { return; } GameObject val = GameObject.Find("FindGameButton"); if (Object.op_Implicit((Object)(object)val)) { if (val != null) { val.SetActive(false); } _ = ((Component)val.transform.parent).gameObject; TextMeshPro textObj = Object.Instantiate(((Component)val.transform.FindChild("Text_TMP")).GetComponent()); textObj.transform.position = new Vector3(1f, -0.3f, 0f); ((Object)textObj).name = "CanNotJoinPublic"; string message = ""; if (!VersionChecker.IsSupported) { message = Translator.GetString("UnsupportedVersion"); } else if (ModUpdater.isBroken) { message = Translator.GetString("ModBrokenMessage"); } else if (ModUpdater.hasUpdate) { message = Translator.GetString("CanNotJoinPublicRoomNoLatest"); } new LateTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)textObj).text = "" + Utils.ColorString(Color32.op_Implicit(Color.red), message) + ""; }, 0.01f, "Can Not Join Public"); } } } [HarmonyPatch(typeof(SplashManager), "Update")] internal class SplashLogoAnimatorPatch { public static void Prefix(SplashManager __instance) { if (DebugModeManager.AmDebugger) { __instance.sceneChanger.AllowFinishLoadingScene(); __instance.startedSceneLoad = true; } } } [HarmonyPatch(typeof(EOSManager), "IsAllowedOnline")] internal class RunLoginPatch { public static int ClickCount; public static int checkCount; public static bool isAllowedOnline; public static void Prefix(ref bool canOnline) { } public static void Postfix(ref bool canOnline) { isAllowedOnline = canOnline; if (DestroyableSingleton.Instance.loginFlowFinished) { string friendCode = DestroyableSingleton.Instance.friendCode; Main.Instance.StartCoroutine(dbConnect.Init()); if (friendCode == null || friendCode == "") { DestroyableSingleton.Instance.attemptAuthAgain = true; Logger.Info("friendcode not found", "EOSManager", escapeCRLF: true, 103, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ClientPatch.cs"); canOnline = false; } } } } [HarmonyPatch(typeof(BanMenu), "SetVisible")] internal class BanMenuSetVisiblePatch { public static bool Prefix(BanMenu __instance, bool show) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } show &= Object.op_Implicit((Object)(object)PlayerControl.LocalPlayer) && (Object)(object)PlayerControl.LocalPlayer.Data != (Object)null; ((Component)__instance.BanButton).gameObject.SetActive(((InnerNetClient)AmongUsClient.Instance).CanBan()); ((Component)__instance.KickButton).gameObject.SetActive(((InnerNetClient)AmongUsClient.Instance).CanKick()); ((Component)__instance.MenuButton).gameObject.SetActive(show); return false; } } [HarmonyPatch(typeof(InnerNetClient), "CanBan")] internal class InnerNetClientCanBanPatch { public static bool Prefix(InnerNetClient __instance, ref bool __result) { __result = __instance.AmHost; return false; } } [HarmonyPatch(typeof(InnerNetClient), "KickPlayer")] internal class KickPlayerPatch { public static Dictionary AttemptedKickPlayerList = new Dictionary(); public static bool Prefix(InnerNetClient __instance, int clientId, bool ban) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (((InnerNetClient)AmongUsClient.Instance).ClientId == clientId) { Logger.SendInGame(string.Format("Game Attempting to {0} Host, Blocked the attempt.", ban ? "Ban" : "Kick")); Logger.Info("How the fuck host are kicking it self", "KickPlayerPatch", escapeCRLF: true, 140, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ClientPatch.cs"); return false; } string hashedPuid = ((InnerNetClient)AmongUsClient.Instance).GetClient(clientId).GetHashedPuid(); if (!AttemptedKickPlayerList.ContainsKey(hashedPuid)) { AttemptedKickPlayerList.Add(hashedPuid, 0); } else if (AttemptedKickPlayerList[hashedPuid] < 10) { Logger.Fatal("Kick player Request too fast! Canceled.", "KickPlayerPatch", escapeCRLF: true, 149, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ClientPatch.cs"); return false; } if (ban) { BanManager.AddBanPlayer(((InnerNetClient)AmongUsClient.Instance).GetRecentClient(clientId)); } return true; } } [HarmonyPatch(typeof(InnerNetClient), "SendAllStreamedObjects")] internal class InnerNetObjectSerializePatch { public static void Prefix() { try { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { GameOptionsSender.SendAllGameOptions(); } } catch { } } } [HarmonyPatch(typeof(ControllerManager), "Update")] internal class ControllerManagerUpdatePatch { private static readonly (int, int)[] resolutions = new(int, int)[6] { (480, 270), (640, 360), (800, 450), (1280, 720), (1600, 900), (1920, 1080) }; private static int resolutionIndex = 0; private static int addonInfoIndex = -1; private static int addonSettingsIndex = -1; public static void Postfix() { //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_0a47: Unknown result type (might be due to invalid IL or missing references) //IL_0a4c: Unknown result type (might be due to invalid IL or missing references) //IL_0b07: Unknown result type (might be due to invalid IL or missing references) //IL_0d8d: Unknown result type (might be due to invalid IL or missing references) //IL_0d92: Unknown result type (might be due to invalid IL or missing references) //IL_0d97: Unknown result type (might be due to invalid IL or missing references) //IL_0dbb: Unknown result type (might be due to invalid IL or missing references) try { if (!RehostManager.IsAutoRehostDone && GetKeysDown((KeyCode)304, (KeyCode)99)) { Logger.Info("User canceled Auto Rehost!", "ControllerManager", escapeCRLF: true, 30, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); RehostManager.IsAutoRehostDone = true; } if (EndGameManagerPatch.IsRestarting && GetKeysDown((KeyCode)304, (KeyCode)99)) { Logger.Info("User canceled Auto Play Again!", "ControllerManager", escapeCRLF: true, 36, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); EndGameManagerPatch.IsRestarting = false; } if (Input.GetKeyDown((KeyCode)282) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); PlayerControl localPlayer = PlayerControl.LocalPlayer; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Translator.GetString(customRole.ToString()) + Utils.GetRoleMode(customRole) + localPlayer.GetRoleInfo(InfoLong: true)); DestroyableSingleton.Instance.ShowPopUp(stringBuilder.ToString() + "tohe"); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs", 73, "Postfix"); throw; } } if (Input.GetKeyDown((KeyCode)283) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { PlayerControl localPlayer2 = PlayerControl.LocalPlayer; if (Main.PlayerStates[localPlayer2.PlayerId].SubRoles.Count == 0) { return; } List list = new List(); CustomRoles[] array = Main.PlayerStates[localPlayer2.PlayerId].SubRoles.Where((CustomRoles x) => x != CustomRoles.Charmed).ToArray(); foreach (CustomRoles customRoles in array) { list.Add(Translator.GetString($"{customRoles}") + Utils.GetRoleMode(customRoles) + Translator.GetString($"{customRoles}InfoLong")); } addonInfoIndex++; if (addonInfoIndex >= list.Count) { addonInfoIndex = 0; } DestroyableSingleton.Instance.ShowPopUp(list[addonInfoIndex] + "tohe"); } catch (Exception ex2) { Utils.ThrowException(ex2, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs", 97, "Postfix"); throw; } } if (Input.GetKeyDown((KeyCode)284) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { CustomRoles customRole2 = PlayerControl.LocalPlayer.GetCustomRole(); StringBuilder sb = new StringBuilder(); if (Options.CustomRoleSpawnChances.TryGetValue(customRole2, out var value)) { Utils.ShowChildrenSettings(value, ref sb); } DestroyableSingleton.Instance.ShowPopUp(sb.ToString().Trim()); } catch (Exception ex3) { Utils.ThrowException(ex3, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs", 114, "Postfix"); } } if (Input.GetKeyDown((KeyCode)285) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { PlayerControl localPlayer3 = PlayerControl.LocalPlayer; if (Main.PlayerStates[localPlayer3.PlayerId].SubRoles.Count == 0) { return; } StringBuilder sb2 = new StringBuilder(); List list2 = new List(); CustomRoles[] array = Main.PlayerStates[localPlayer3.PlayerId].SubRoles.Where((CustomRoles x) => x != CustomRoles.Charmed).ToArray(); foreach (CustomRoles key in array) { if (Options.CustomRoleSpawnChances.TryGetValue(key, out var value2)) { Utils.ShowChildrenSettings(value2, ref sb2); } list2.Add(sb2.ToString()); } addonSettingsIndex++; if (addonSettingsIndex >= list2.Count) { addonSettingsIndex = 0; } DestroyableSingleton.Instance.ShowPopUp(list2[addonSettingsIndex] + "tohe"); } catch (Exception ex4) { Utils.ThrowException(ex4, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs", 141, "Postfix"); } } if (GetKeysDown((KeyCode)292, (KeyCode)308)) { resolutionIndex++; if (resolutionIndex >= resolutions.Length) { resolutionIndex = 0; } ResolutionManager.SetResolution(resolutions[resolutionIndex].Item1, resolutions[resolutionIndex].Item2, false); } if (GetKeysDown((KeyCode)286, (KeyCode)116)) { Logger.Info("Reloaded Custom Translation File Colors", "KeyCommand", escapeCRLF: true, 155, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); Translator.LoadLangs(); Logger.SendInGame("Reloaded Custom Translation File"); } if (GetKeysDown((KeyCode)286, (KeyCode)120)) { Logger.Info("Exported Custom Translation and Role File", "KeyCommand", escapeCRLF: true, 162, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); Translator.ExportCustomTranslation(); Main.ExportCustomRoleColors(); Logger.SendInGame("Exported Custom Translation and Role File"); } if (GetKeysDown((KeyCode)282, (KeyCode)306)) { Logger.Info("Send logs", "KeyCommand", escapeCRLF: true, 170, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); Utils.DumpLog(); } if (GetKeysDown((KeyCode)308, (KeyCode)99) && !Input.GetKey((KeyCode)304) && !GameStates.IsNotJoined) { Utils.CopyCurrentSettings(); } if (GetKeysDown((KeyCode)291)) { Process.Start(Environment.CurrentDirectory); } KeyCode[] array2 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array2)) { DestroyableSingleton.Instance.Chat.SetVisible(true); } if (Input.GetKeyDown((KeyCode)112) && (Object)(object)PlayerControl.LocalPlayer != (Object)null) { Vector2 truePosition = PlayerControl.LocalPlayer.GetTruePosition(); Logger.Info(((object)(Vector2)(ref truePosition)).ToString(), "GetLocalPlayerPos GetTruePosition()", escapeCRLF: true, 193, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); Vector3 position = ((Component)PlayerControl.LocalPlayer).transform.position; Logger.Info(((object)(Vector3)(ref position)).ToString(), "GetLocalPlayerPos transform.position", escapeCRLF: true, 194, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } KeyCode[] array3 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array3, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array3) && GameStates.IsInGame) { NameNotifyManager.Notice.Clear(); Utils.DoNotifyRoles(); CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw); GameManager.Instance.LogicFlow.CheckEndCriteria(); if (GameStates.IsHideNSeek) { GameEndCheckerForNormal.StartEndGame((GameOverReason)5); } } KeyCode[] array4 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array4, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array4) && GameStates.IsInGame) { if (GameStates.IsHideNSeek) { return; } if (GameStates.IsMeeting) { foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)MeetingHud.Instance.playerStates) { if (!((Object)(object)item == (Object)null) && item.VotedFor < 253) { MeetingHud.Instance.RpcClearVote((int)item.TargetPlayerId); } } List list3 = new List(); MeetingHud.Instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(list3.ToArray()), (NetworkedPlayerInfo)null, true); MeetingHud.Instance.RpcClose(); } else { PlayerControl.LocalPlayer.NoCheckStartMeeting(null, force: true); } } if (Input.GetKeyDown((KeyCode)304) && GameStates.IsCountDown && !DestroyableSingleton.Instance.Chat.IsOpenOrOpening) { if (Main.AllPlayerControls.Where((PlayerControl p) => p.Data.DefaultOutfit.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= p.Data.DefaultOutfit.ColorId).ToArray().Any()) { DestroyableSingleton.Instance.ResetStartState(); Logger.SendInGame(Translator.GetString("Error.InvalidColorPreventStart")); Logger.Info("Invalid Color Detected on force start!", "KeyCommand", escapeCRLF: true, 246, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); } else { Logger.Info("Countdown timer changed to 0", "KeyCommand", escapeCRLF: true, 250, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); DestroyableSingleton.Instance.countDownTimer = 0f; } } if (Input.GetKeyDown((KeyCode)99) && GameStates.IsCountDown) { Logger.Info("Reset Countdown", "KeyCommand", escapeCRLF: true, 258, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); DestroyableSingleton.Instance.ResetStartState(); Logger.SendInGame(Translator.GetString("CancelStartCountDown")); } if (GetKeysDown((KeyCode)110, (KeyCode)306) && !Input.GetKey((KeyCode)304)) { Main.isChatCommand = true; Utils.ShowActiveSettings(); } if (GameStates.IsLobby) { KeyCode[] array5 = new KeyCode[4]; RuntimeHelpers.InitializeArray(array5, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array5)) { CollectionExtensions.Do(from x in OptionItem.AllOptions.ToArray() where x.Id > 0 select x, (Action)delegate(OptionItem x) { x.SetValueNoRpc(x.DefaultValue); }); Logger.SendInGame(Translator.GetString("RestTOHESetting")); } } KeyCode[] array6 = new KeyCode[4]; RuntimeHelpers.InitializeArray(array6, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array6) && GameStates.IsInGame) { PlayerControl.LocalPlayer.Data.IsDead = true; PlayerControl.LocalPlayer.SetDeathReason(PlayerState.DeathReason.etc); PlayerControl.LocalPlayer.SetRealKiller(PlayerControl.LocalPlayer); Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); PlayerControl.LocalPlayer.RpcExileV2(); MurderPlayerPatch.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, PlayerControl.LocalPlayer, GameStates.IsMeeting); Utils.SendMessage(Translator.GetString("HostKillSelfByCommand"), byte.MaxValue, "" + Translator.GetString("DefaultSystemMessageTitle") + ""); } KeyCode[] array7 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array7, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array7) && GameStates.IsInGame && PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) { ((MonoBehaviour)DestroyableSingleton.Instance).StartCoroutine(DestroyableSingleton.Instance.CoFadeFullScreen(Color.clear, Color.black, 0.2f, false)); ((MonoBehaviour)DestroyableSingleton.Instance).StartCoroutine(DestroyableSingleton.Instance.CoShowIntro()); } if (GetKeysDown((KeyCode)283, (KeyCode)306)) { Logger.isAlsoInGame = !Logger.isAlsoInGame; Logger.SendInGame($"In-game output log:{Logger.isAlsoInGame}"); } if (!DebugModeManager.IsDebugMode) { return; } KeyCode[] array8 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array8, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array8)) { Utils.FlashColor(new Color(1f, 0f, 0f, 0.3f)); if (Constants.ShouldPlaySfx()) { RPC.PlaySound(PlayerControl.LocalPlayer.PlayerId, Sounds.KillSound); } } KeyCode[] array9 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array9, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array9) && GameStates.IsMeeting && !GameStates.IsOnlineGame) { MeetingHud.Instance.RpcClearVote(((InnerNetClient)AmongUsClient.Instance).ClientId); } KeyCode[] array10 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array10, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array10) && GameStates.IsInGame) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)16, (byte)79); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)16, (byte)80); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)16, (byte)81); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)16, (byte)82); } KeyCode[] array11 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array11, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array11) && GameStates.IsInGame) { PlayerControl.LocalPlayer.SetKillTimer(0f); } KeyCode[] array12 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array12, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array12) && GameStates.IsInGame) { foreach (PlayerTask item2 in PlayerControl.LocalPlayer.myTasks.ToArray()) { PlayerControl.LocalPlayer.RpcCompleteTask(item2.Id); } } if (Input.GetKeyDown((KeyCode)121)) { RPC.SyncCustomSettingsRPC(); Logger.SendInGame(Translator.GetString("SyncCustomSettingsRPC")); } if (Input.GetKeyDown((KeyCode)61)) { Main.VisibleTasksCount = !Main.VisibleTasksCount; DestroyableSingleton.Instance.Notifier.AddDisconnectMessage($"VisibleTaskCount has been changed to {Main.VisibleTasksCount}"); } if (Input.GetKeyDown((KeyCode)99) && !GameStates.IsLobby) { Enumerator enumerator3 = PlayerControl.AllPlayerControls.GetEnumerator(); while (enumerator3.MoveNext()) { PlayerControl current3 = enumerator3.Current; if (!((InnerNetObject)current3).AmOwner) { current3.MyPhysics.RpcEnterVent(2); } } } if (Input.GetKeyDown((KeyCode)98)) { Enumerator enumerator3 = PlayerControl.AllPlayerControls.GetEnumerator(); while (enumerator3.MoveNext()) { PlayerControl current4 = enumerator3.Current; if (!((InnerNetObject)current4).AmOwner) { current4.MyPhysics.RpcExitVent(2); } } } KeyCode[] array13 = new KeyCode[3]; RuntimeHelpers.InitializeArray(array13, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); if (GetKeysDown((KeyCode[])(object)array13) && !GameStates.IsLobby && PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) { Vector2 position2 = Vector2.op_Implicit(((Component)PlayerControl.LocalPlayer.NetTransform).transform.position); Enumerator enumerator3 = PlayerControl.AllPlayerControls.GetEnumerator(); while (enumerator3.MoveNext()) { PlayerControl current5 = enumerator3.Current; if (!((InnerNetObject)current5).AmOwner) { current5.RpcTeleport(position2); position2.x += 0.5f; } } } if (Input.GetKeyDown((KeyCode)110)) { VentilationSystem.Update((Operation)0, 0); } } catch (Exception ex5) { Utils.ThrowException(ex5, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs", 414, "Postfix"); } } private static bool GetKeysDown(params KeyCode[] keys) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (((IEnumerable)keys).Any((Func)Input.GetKeyDown) && ((IEnumerable)keys).All((Func)Input.GetKey)) { Logger.Info($"Shortcut Key:{((IEnumerable)keys).First((Func)Input.GetKeyDown)} in [{string.Join(",", keys)}]", "GetKeysDown", escapeCRLF: true, 422, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ControlPatch.cs"); return true; } return false; } private static bool ORGetKeysDown(params KeyCode[] keys) { return ((IEnumerable)keys).Any((Func)Input.GetKeyDown); } } [HarmonyPatch(typeof(ConsoleJoystick), "HandleHUD")] internal class ConsoleJoystickHandleHUDPatch { public static void Postfix() { HandleHUDPatch.Postfix(ConsoleJoystick.player); } } [HarmonyPatch(typeof(KeyboardJoystick), "HandleHud")] internal class KeyboardJoystickHandleHUDPatch { public static void Postfix() { HandleHUDPatch.Postfix(KeyboardJoystick.player); } } internal class HandleHUDPatch { public static void Postfix(Player player) { if (!GameStates.IsInGame || GameStates.IsHideNSeek) { return; } if (player.GetButtonDown(8)) { NetworkedPlayerInfo data = PlayerControl.LocalPlayer.Data; if (data != null) { RoleBehaviour role = data.Role; if (((role != null) ? new bool?(role.IsImpostor) : null) == false && PlayerControl.LocalPlayer.CanUseKillButton()) { ((ActionButton)DestroyableSingleton.Instance.KillButton).DoClick(); } } } if (!player.GetButtonDown(50)) { return; } NetworkedPlayerInfo data2 = PlayerControl.LocalPlayer.Data; if (data2 != null) { RoleBehaviour role2 = data2.Role; if (((role2 != null) ? new bool?(role2.IsImpostor) : null) == false && PlayerControl.LocalPlayer.CanUseImpostorVentButton()) { ((ActionButton)DestroyableSingleton.Instance.ImpostorVentButton).DoClick(); } } } } [HarmonyPatch(typeof(PingTracker), "Update")] internal class PingTrackerUpdatePatch { public static PingTracker Instance; private static int DelayUpdate = 0; private static readonly StringBuilder sb = new StringBuilder(); private static bool Prefix(PingTracker __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) try { if (Instance == null) { Instance = __instance; } DelayUpdate--; if (DelayUpdate > 0 && sb.Length > 0) { ChangeText(__instance); __instance.aspectPosition.DistanceFromEdge = GetPingPosition(); ((TMP_Text)__instance.text).text = sb.ToString(); return false; } DelayUpdate = 500; ChangeText(__instance); sb.Clear(); sb.Append(Main.credentialsText); int ping = ((InnerNetClient)AmongUsClient.Instance).Ping; string value = "#ff4500"; if (ping < 30) { value = "#44dfcc"; } else if (ping < 100) { value = "#7bc690"; } else if (ping < 200) { value = "#f3920e"; } else if (ping < 400) { value = "#ff146e"; } StringBuilder stringBuilder = sb; StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(75, 3, stringBuilder); handler.AppendLiteral("\r\nPing: "); handler.AppendFormatted(ping); handler.AppendLiteral(" ms\r\nServer: "); handler.AppendFormatted(Utils.GetRegionName()); handler.AppendLiteral(""); stringBuilder2.Append(ref handler); if (!GameStates.IsModHost) { stringBuilder = sb; StringBuilder stringBuilder3 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.red), Translator.GetString("Warning.NoModHost"))); stringBuilder3.Append(ref handler); } if (Main.ShowFPS.Value) { float num = 1f / Time.deltaTime; Color val = Color.green; if (num < 20f) { val = Color.red; } else if (num < 40f) { val = Color.yellow; } stringBuilder = sb; StringBuilder stringBuilder4 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(val), Utils.ColorString(Color32.op_Implicit(Color.cyan), Translator.GetString("FPSGame")) + (int)num)); stringBuilder4.Append(ref handler); } if (Main.ShowTextOverlay.Value) { StringBuilder stringBuilder5 = new StringBuilder(); if (Options.LowLoadMode.GetBool()) { stringBuilder = stringBuilder5; StringBuilder stringBuilder6 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.green), Translator.GetString("Overlay.LowLoadMode"))); stringBuilder6.Append(ref handler); } if (Options.NoGameEnd.GetBool()) { stringBuilder = stringBuilder5; StringBuilder stringBuilder7 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.red), Translator.GetString("Overlay.NoGameEnd"))); stringBuilder7.Append(ref handler); } if (Options.GuesserMode.GetBool()) { stringBuilder = stringBuilder5; StringBuilder stringBuilder8 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.yellow), Translator.GetString("Overlay.GuesserMode"))); stringBuilder8.Append(ref handler); } if (Options.AllowConsole.GetBool() && PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) { stringBuilder = stringBuilder5; StringBuilder stringBuilder9 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.red), Translator.GetString("Overlay.AllowConsole"))); stringBuilder9.Append(ref handler); } if (DebugModeManager.IsDebugMode) { stringBuilder = stringBuilder5; StringBuilder stringBuilder10 = stringBuilder; handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder); handler.AppendLiteral("\r\n"); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Color.green), Translator.GetString("Overlay.DebugMode"))); stringBuilder10.Append(ref handler); } if (stringBuilder5.Length > 0) { sb.Append(stringBuilder5); } } __instance.aspectPosition.DistanceFromEdge = GetPingPosition(); ((TMP_Text)__instance.text).text = sb.ToString(); return false; } catch { DelayUpdate = 0; sb.Clear(); return false; } } private static Vector3 GetPingPosition() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = DestroyableSingleton.Instance.SettingsButton.transform.localPosition; float num = localPosition.x - 1.58f; float num2 = localPosition.y + 3.2f; if (!Main.ShowTextOverlay.Value) { num2 += 0.1f; } Vector3 result = default(Vector3); if (((InnerNetClient)AmongUsClient.Instance).IsGameStarted) { num = ((!Object.op_Implicit((Object)(object)DestroyableSingleton.Instance) || ((Behaviour)DestroyableSingleton.Instance.Chat).isActiveAndEnabled) ? (num + 0.1f) : (num + 0.7f)); ((Vector3)(ref result))..ctor(num, num2, 0f); } else { ((Vector3)(ref result))..ctor(num, num2, 0f); } return result; } private static void ChangeText(PingTracker __instance) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 ((TMP_Text)__instance.text).alignment = (TextAlignmentOptions)516; ((TMP_Text)__instance.text).outlineColor = Color32.op_Implicit(Color.black); if (Main.ShowTextOverlay.Value || Main.ShowFPS.Value) { SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; TextMeshPro text = __instance.text; float outlineWidth = (((int)languageID != 5 && (int)languageID != 11 && languageID - 13 > 1) ? 0.4f : 0.25f); ((TMP_Text)text).outlineWidth = outlineWidth; } else { ((TMP_Text)__instance.text).outlineWidth = 0.4f; } } } [HarmonyPatch(typeof(VersionShower), "Start")] internal class VersionShowerStartPatch { private static TextMeshPro SpecialEventText; private static void Postfix(VersionShower __instance) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) Main.credentialsText = $"{Main.ModName} v{"2.0.3"}"; string text = ""; Main.credentialsText += "\r\nBy The Enhanced Network"; text = "Release"; Logger.Info($"v{"2024.0813.203.9999"}, {text}:{"main"}:({"f6840257"}), link [{"https://github.com/0xDrMoe/TownofHost-Enhanced"}], dirty: [{0}]", "TOHE version", escapeCRLF: true, 165, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\CredentialsPatch.cs"); if (Main.IsAprilFools) { Main.credentialsText = "Town Of Host v11.45.14"; } TextMeshPro obj = Object.Instantiate(__instance.text); ((TMP_Text)obj).text = Main.credentialsText; ((TMP_Text)obj).alignment = (TextAlignmentOptions)516; obj.transform.position = new Vector3(1f, 2.67f, -2f); float num2 = (((TMP_Text)obj).fontSizeMin = 2f); float fontSize = (((TMP_Text)obj).fontSizeMax = num2); ((TMP_Text)obj).fontSize = fontSize; ErrorText.Create(__instance.text); if (Main.hasArgumentException && (Object)(object)ErrorText.Instance != (Object)null) { ErrorText.Instance.AddError(ErrorCode.Main_DictionaryError); } VersionChecker.Check(); if ((Object)(object)SpecialEventText == (Object)null && (Object)(object)MainMenuManagerStartPatch.ToheLogo != (Object)null) { SpecialEventText = Object.Instantiate(__instance.text, ((Component)MainMenuManagerStartPatch.ToheLogo).transform); ((Object)SpecialEventText).name = "SpecialEventText"; ((TMP_Text)SpecialEventText).text = ""; ((Graphic)SpecialEventText).color = Color.white; ((TMP_Text)SpecialEventText).fontSizeMin = 3f; ((TMP_Text)SpecialEventText).alignment = (TextAlignmentOptions)514; SpecialEventText.transform.localPosition = new Vector3(0f, 0.8f, 0f); } if ((Object)(object)SpecialEventText != (Object)null) { ((Behaviour)SpecialEventText).enabled = (Object)(object)MainMenuManagerStartPatch.amongUsLogo != (Object)null; } if (Main.IsInitialRelease) { ((TMP_Text)SpecialEventText).text = "Happy Birthday to " + Main.ModName + "!"; Color color = default(Color); if (ColorUtility.TryParseHtmlString(Main.ModColor, ref color)) { ((Graphic)SpecialEventText).color = color; } } } } [HarmonyPatch(typeof(ModManager), "LateUpdate")] internal class ModManagerLateUpdatePatch { public static void Prefix(ModManager __instance) { __instance.ShowModStamp(); LateTask.Update(Time.deltaTime); CheckMurderPatch.Update(); } public static void Postfix(ModManager __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) float num = (DestroyableSingleton.InstanceExists ? 1.8f : 0.9f); ((Component)__instance.ModStamp).transform.position = AspectPosition.ComputeWorldPosition(__instance.localCamera, (EdgeAlignments)10, new Vector3(0.4f, num, __instance.localCamera.nearClipPlane + 0.1f)); } } [HarmonyPatch(typeof(AmongUsClient), "OnDisconnected")] internal class OnDisconnectedPatch { public static void Postfix() { Main.VisibleTasksCount = false; } } internal class ExileControllerWrapUpPatch { [HarmonyPatch(typeof(ExileController), "WrapUp")] private class BaseExileControllerPatch { public static void Postfix(ExileController __instance) { try { WrapUpPostfix(__instance.initData.networkedPlayer); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs", 22, "Postfix"); } finally { WrapUpFinalizer(__instance.initData.networkedPlayer); } } } [HarmonyPatch(typeof(AirshipExileController), "WrapUpAndSpawn")] private class AirshipExileControllerPatch { public static void Postfix(AirshipExileController __instance) { try { WrapUpPostfix(((ExileController)__instance).initData.networkedPlayer); } catch (Exception value) { Logger.Error($"Error after exiled: {value}", "WrapUpAndSpawn", escapeCRLF: true, 42, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs"); } finally { WrapUpFinalizer(((ExileController)__instance).initData.networkedPlayer); } } } [HarmonyPatch(typeof(PbExileController), "PlayerSpin")] private class PolusExileHatFixPatch { public static void Prefix(PbExileController __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ((Component)((ExileController)__instance).Player.cosmetics.hat).transform.localPosition = new Vector3(-0.2f, 0.6f, 1.1f); } } public static NetworkedPlayerInfo AntiBlackout_LastExiled; private static void WrapUpPostfix(NetworkedPlayerInfo exiled) { if (AntiBlackout.BlackOutIsActive) { exiled = AntiBlackout_LastExiled; } if (!GameStates.AirshipIsActive) { foreach (PlayerState value in Main.PlayerStates.Values) { value.HasSpawned = true; } } bool DecidedWinner = false; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } AntiBlackout.RestoreIsDead(doSend: false, "WrapUpPostfix"); List list = Utils.GetRoleBasesByType()?.ToList(); if (list != null) { Logger.Info($"{!list.Any((Collector x) => x.CollectorWin(check: false))}", "!Collector.CollectorWin(false)", escapeCRLF: true, 69, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs"); } Logger.Info($"{(Object)(object)exiled != (Object)null}", "exiled != null", escapeCRLF: true, 70, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs"); if ((list == null || !list.Any((Collector x) => x.CollectorWin(check: false))) && (Object)(object)exiled != (Object)null) { if (Main.ResetCamPlayerList.Contains(exiled.PlayerId)) { exiled.Object?.ResetPlayerCam(1f); } exiled.IsDead = true; exiled.PlayerId.SetDeathReason(PlayerState.DeathReason.Vote); RoleBase roleClass2 = Utils.GetPlayerById(exiled.PlayerId).GetRoleClass(); string emptyString = string.Empty; roleClass2?.CheckExile(exiled, ref DecidedWinner, isMeetingHud: false, ref emptyString); CollectionExtensions.Do((IEnumerable)CustomRoleManager.AllEnabledRoles, (Action)delegate(RoleBase roleClass) { roleClass.CheckExileTarget(exiled, ref DecidedWinner, isMeetingHud: false, ref emptyString); }); if (CustomWinnerHolder.WinnerTeam != CustomWinner.Terrorist) { Main.PlayerStates[exiled.PlayerId].SetDead(); } } if (((InnerNetClient)AmongUsClient.Instance).AmHost && Main.IsFixedCooldown) { Main.RefixCooldownDelay = Options.DefaultKillCooldown - 3f; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { val.GetRoleClass()?.OnPlayerExiled(val, exiled); if (val.GetCustomRole().IsImpostor() && !val.IsAlive() && AntiBlackout.BlackOutIsActive) { val.ResetPlayerCam(1f); } val.RpcRemovePet(); val.ResetKillCooldown(); val.RpcResetAbilityCooldown(); } Main.MeetingIsStarted = false; Main.MeetingsPassed++; FallFromLadder.Reset(); Utils.CountAlivePlayers(sendLog: true, Options.CurrentGameMode == CustomGameMode.Standard); Utils.AfterMeetingTasks(); Utils.SyncAllSettings(); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); if (!RandomSpawn.IsRandomSpawn() && Options.CurrentGameMode != CustomGameMode.FFA) { return; } new LateTask(delegate { RandomSpawn.SpawnMap spawnMap = Utils.GetActiveMapId() switch { 0 => new RandomSpawn.SkeldSpawnMap(), 1 => new RandomSpawn.MiraHQSpawnMap(), 2 => new RandomSpawn.PolusSpawnMap(), 3 => new RandomSpawn.DleksSpawnMap(), 5 => new RandomSpawn.FungleSpawnMap(), _ => null, }; if (spawnMap != null) { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)spawnMap.RandomTeleport); } }, 0.8f, "Random Spawn After Meeting"); } private static void WrapUpFinalizer(NetworkedPlayerInfo exiled) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { new LateTask(delegate { exiled = AntiBlackout_LastExiled; AntiBlackout.SendGameData("WrapUpFinalizer"); if (AntiBlackout.BlackOutIsActive && (Object)(object)exiled != (Object)null && (Object)(object)exiled.Object != (Object)null) { exiled.Object.RpcExileV2(); } }, 0.8f, "Restore IsDead Task"); new LateTask(delegate { CollectionExtensions.Do>((IEnumerable>)Main.AfterMeetingDeathPlayers, (Action>)delegate(KeyValuePair x) { PlayerControl playerById = Utils.GetPlayerById(x.Key); PlayerState playerState = Main.PlayerStates[x.Key]; Logger.Info($"{playerById.GetNameWithRole().RemoveHtmlTags()} died with {x.Value}", "AfterMeetingDeath", escapeCRLF: true, 174, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs"); playerState.deathReason = x.Value; playerState.SetDead(); playerById?.RpcExileV2(); if (x.Value == PlayerState.DeathReason.Suicide) { playerById?.SetRealKiller(playerById, NotOverRide: true); } if (Main.ResetCamPlayerList.Contains(x.Key)) { playerById?.ResetPlayerCam(1f); } MurderPlayerPatch.AfterPlayerDeathTasks(playerById, playerById, inMeeting: true); }); Main.AfterMeetingDeathPlayers.Clear(); }, 0.8f, "AfterMeetingDeathPlayers Task"); } GameStates.AlreadyDied |= !Utils.IsAllAlive; RemoveDisableDevicesPatch.UpdateDisableDevices(); SoundManager.Instance.ChangeAmbienceVolume(DataManager.Settings.Audio.AmbienceVolume); new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameOver) { DestroyableSingleton.Instance.SetHudActive(true); } }, 0.8f, "Set Hud Active"); Logger.Info("Start of Task Phase", "Phase", escapeCRLF: true, 209, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ExilePatch.cs"); } } [HarmonyPatch(typeof(GameManager), "Serialize")] internal class GameManagerSerializeFix { public static bool Prefix(GameManager __instance, [HarmonyArgument(0)] MessageWriter writer, [HarmonyArgument(1)] bool initialState, ref bool __result) { bool flag = false; for (int i = 0; i < __instance.LogicComponents.Count; i++) { GameLogicComponent val = __instance.LogicComponents[i]; if (initialState || val.IsDirty) { flag = true; writer.StartMessage((byte)i); if (val.Serialize(writer, initialState)) { writer.EndMessage(); } else { writer.CancelMessage(); } val.ClearDirtyFlag(); } } ((InnerNetObject)__instance).ClearDirtyBits(); __result = flag; return false; } } [HarmonyPatch(typeof(LogicOptions), "Serialize")] internal class LogicOptionsSerializePatch { public static bool Prefix(ref bool __result, [HarmonyArgument(1)] bool initialState) { if (!initialState) { __result = false; return false; } return true; } } public static class ModGameOptionsMenu { public static int TabIndex = 0; public static Dictionary OptionList = new Dictionary(); public static Dictionary BehaviourList = new Dictionary(); public static Dictionary CategoryHeaderList = new Dictionary(); } [HarmonyPatch(typeof(GameOptionsMenu))] public static class GameOptionsMenuPatch { public static GameOptionsMenu Instance; [HarmonyPatch("Initialize")] [HarmonyPrefix] private static bool InitializePrefix(GameOptionsMenu __instance) { if (Instance == null) { Instance = __instance; } if (ModGameOptionsMenu.TabIndex < 3) { return true; } if (__instance.Children == null || __instance.Children.Count == 0) { ((Component)__instance.MapPicker).gameObject.SetActive(false); __instance.Children = new List(); __instance.CreateSettings(); __instance.cachedData = GameOptionsManager.Instance.CurrentGameOptions; for (int i = 0; i < __instance.Children.Count; i++) { __instance.Children[i].OnValueChanged = Action.op_Implicit((Action)__instance.ValueChanged); } __instance.InitializeControllerNavigation(); } return false; } [HarmonyPatch("Initialize")] [HarmonyPostfix] private static void InitializePostfix() { GameObject obj = GameObject.Find("PlayerOptionsMenu(Clone)"); if (obj != null) { Transform obj2 = obj.transform.FindChild("Background"); if (obj2 != null) { ((Component)obj2).gameObject.SetActive(false); } } } [HarmonyPatch("CreateSettings")] [HarmonyPrefix] private static bool CreateSettingsPrefix(GameOptionsMenu __instance) { if (Instance == null) { Instance = __instance; } if (ModGameOptionsMenu.TabIndex < 3) { return true; } __instance.scrollBar.SetYBoundsMax(CalculateScrollBarYBoundsMax()); ((MonoBehaviour)__instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoRoutine())); return false; static float CalculateScrollBarYBoundsMax() { float num2 = 2f; foreach (OptionItem allOption in OptionItem.AllOptions) { if (allOption.Tab == (TabGroup)(ModGameOptionsMenu.TabIndex - 3)) { bool flag2 = !allOption.IsHiddenOn(Options.CurrentGameMode) && (allOption.Parent == null || (!allOption.Parent.IsHiddenOn(Options.CurrentGameMode) && allOption.Parent.GetBool())); if (allOption is TextOptionItem) { num2 -= 0.63f; } else if (flag2) { if (allOption.IsHeader) { num2 -= 0.3f; } num2 -= 0.45f; } } } return 0f - num2 - 1.65f; } IEnumerator CoRoutine() { TabGroup modTab = (TabGroup)(ModGameOptionsMenu.TabIndex - 3); float num = 2f; for (int index = 0; index < OptionItem.AllOptions.Count; index++) { OptionItem optionItem = OptionItem.AllOptions[index]; if (optionItem.Tab == modTab) { bool flag = !optionItem.IsHiddenOn(Options.CurrentGameMode) && (optionItem.Parent == null || (!optionItem.Parent.IsHiddenOn(Options.CurrentGameMode) && optionItem.Parent.GetBool())); if (optionItem is TextOptionItem) { CategoryHeaderMasked val = Object.Instantiate(__instance.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer); val.SetHeader((StringNames)3351, 20); ((TMP_Text)val.Title).text = optionItem.GetName(); ((Component)val).transform.localScale = Vector3.one * 0.68f; ((Component)val).transform.localPosition = new Vector3(-0.913f, num, -2f); TextMeshPro component = ((Component)((Component)val).transform.FindChild("HeaderText")).GetComponent(); ((TMP_Text)component).fontStyle = (FontStyles)1; ((TMP_Text)component).outlineWidth = 0.17f; ((Component)val).gameObject.SetActive(flag); ModGameOptionsMenu.CategoryHeaderList.TryAdd(index, val); if (flag) { num -= 0.63f; } } else if (optionItem.IsHeader && flag) { num -= 0.3f; } if (!(optionItem is TextOptionItem)) { BaseGameSetting setting = GetSetting(optionItem); if (!((Object)(object)setting == (Object)null)) { OptionTypes type = setting.Type; OptionBehaviour val2; switch (type - 1) { case 0: val2 = (OptionBehaviour)(object)Object.Instantiate(__instance.checkboxOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer); ((Component)val2).transform.localPosition = new Vector3(0.952f, num, -2f); OptionBehaviourSetSizeAndPosition(val2, optionItem, setting.Type); val2.SetClickMask(__instance.ButtonClickMask); val2.SetUpFromData(setting, 20); ModGameOptionsMenu.OptionList.TryAdd(val2, index); break; case 2: val2 = (OptionBehaviour)(object)Object.Instantiate(__instance.stringOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer); ((Component)val2).transform.localPosition = new Vector3(0.952f, num, -2f); OptionBehaviourSetSizeAndPosition(val2, optionItem, setting.Type); val2.SetClickMask(__instance.ButtonClickMask); val2.SetUpFromData(setting, 20); ModGameOptionsMenu.OptionList.TryAdd(val2, index); break; case 3: case 4: val2 = (OptionBehaviour)(object)Object.Instantiate(__instance.numberOptionOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer); ((Component)val2).transform.localPosition = new Vector3(0.952f, num, -2f); OptionBehaviourSetSizeAndPosition(val2, optionItem, setting.Type); val2.SetClickMask(__instance.ButtonClickMask); val2.SetUpFromData(setting, 20); ModGameOptionsMenu.OptionList.TryAdd(val2, index); break; default: continue; } ((Component)val2).transform.localPosition = new Vector3(0.952f, num, -2f); val2.SetClickMask(__instance.ButtonClickMask); val2.SetUpFromData(setting, 20); ModGameOptionsMenu.OptionList.TryAdd(val2, index); ModGameOptionsMenu.BehaviourList.TryAdd(index, val2); ((Component)val2).gameObject.SetActive(flag); val2.OnValueChanged = Action.op_Implicit((Action)__instance.ValueChanged); __instance.Children.Add(val2); if (flag) { num -= 0.45f; } if (index % 50 == 0) { yield return null; } } } } } yield return null; __instance.ControllerSelectable.Clear(); foreach (UiElement componentsInChild in ((Component)__instance.scrollBar).GetComponentsInChildren()) { __instance.ControllerSelectable.Add(componentsInChild); } } } private static void OptionBehaviourSetSizeAndPosition(OptionBehaviour optionBehaviour, OptionItem option, OptionTypes type) { //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Expected I4, but got Unknown //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04bd: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0454: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0f, 0f); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, 0f, 0f); Color color = default(Color); ((Color)(ref color))..ctor(0.8f, 0.8f, 0.8f); float num = 5.7f; if (option.Parent?.Parent?.Parent != null) { ((Vector3)(ref val2))..ctor(-0.18f, 0f, 0f); ((Vector3)(ref val))..ctor(0.3f, 0f, 0f); ((Color)(ref color))..ctor(0.8f, 0.8f, 0.2f); num = 5.1f; } else if (option.Parent?.Parent != null) { ((Vector3)(ref val2))..ctor(-0.12f, 0f, 0f); ((Vector3)(ref val))..ctor(0.2f, 0f, 0f); ((Color)(ref color))..ctor(0.5f, 0.2f, 0.8f); num = 5.3f; } else if (option.Parent != null) { ((Vector3)(ref val2))..ctor(-0.05f, 0f, 0f); ((Vector3)(ref val))..ctor(0.1f, 0f, 0f); ((Color)(ref color))..ctor(0.2f, 0.8f, 0.8f); num = 5.5f; } Transform obj = ((Component)optionBehaviour).transform.FindChild("LabelBackground"); ((Component)obj).GetComponent().color = color; obj.localScale += new Vector3(1f, -0.2f, 0f) + val2; obj.localPosition += new Vector3(-0.6f, 0f, 0f) + val; Transform obj2 = ((Component)optionBehaviour).transform.FindChild("Title Text"); obj2.localPosition += new Vector3(-0.7f, 0f, 0f) + val; ((Component)obj2).GetComponent().sizeDelta = new Vector2(num, 0.37f); TextMeshPro component = ((Component)obj2).GetComponent(); ((TMP_Text)component).alignment = (TextAlignmentOptions)4097; ((TMP_Text)component).fontStyle = (FontStyles)1; ((TMP_Text)component).outlineWidth = 0.17f; switch (type - 1) { case 0: ((Component)optionBehaviour).transform.FindChild("Toggle").localPosition = new Vector3(1.46f, -0.042f); return; case 2: { Transform obj6 = ((Component)optionBehaviour).transform.FindChild("PlusButton"); obj6.localPosition += new Vector3(option.IsText ? 500f : 1.7f, option.IsText ? 500f : 0f, option.IsText ? 500f : 0f); Transform obj7 = ((Component)optionBehaviour).transform.FindChild("MinusButton"); obj7.localPosition += new Vector3(option.IsText ? 500f : 0.9f, option.IsText ? 500f : 0f, option.IsText ? 500f : 0f); Transform obj8 = ((Component)optionBehaviour).transform.FindChild("Value_TMP (1)"); obj8.localPosition += new Vector3(1.3f, 0f, 0f); ((Component)obj8).GetComponent().sizeDelta = new Vector2(2.3f, 0.4f); break; } case 3: case 4: { Transform obj3 = ((Component)optionBehaviour).transform.FindChild("PlusButton"); obj3.localPosition += new Vector3(option.IsText ? 500f : 1.7f, option.IsText ? 500f : 0f, option.IsText ? 500f : 0f); Transform obj4 = ((Component)optionBehaviour).transform.FindChild("MinusButton"); obj4.localPosition += new Vector3(option.IsText ? 500f : 0.9f, option.IsText ? 500f : 0f, option.IsText ? 500f : 0f); Transform obj5 = ((Component)optionBehaviour).transform.FindChild("Value_TMP"); obj5.localPosition += new Vector3(1.3f, 0f, 0f); break; } } Transform obj9 = ((Component)optionBehaviour).transform.FindChild("ValueBox"); obj9.localScale += new Vector3(0.2f, 0f, 0f); obj9.localPosition += new Vector3(1.3f, 0f, 0f); } public static void ReOpenSettings(bool IsPresset) { GameSettingMenu.Instance.Close(); new LateTask(delegate { if (GameStates.IsLobby) { GameObject val = GameObject.Find("Host Buttons"); if (!((Object)(object)val == (Object)null)) { ((PassiveUiElement)((Component)val.transform.FindChild("Edit")).GetComponent()).ReceiveClickDown(); } } }, 0.1f, "Click Edit Button"); new LateTask(delegate { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 if (GameStates.IsLobby && !((Object)(object)GameSettingMenu.Instance == (Object)null)) { GameSettingMenu.Instance.ChangeTab(IsPresset ? 3 : 4, (int)Controller.currentTouchType == 0); } }, 0.28f, "Change Tab"); } [HarmonyPatch("ValueChanged")] [HarmonyPrefix] private static bool ValueChangedPrefix(GameOptionsMenu __instance, OptionBehaviour option) { if ((Object)(object)__instance == (Object)null || ModGameOptionsMenu.TabIndex < 3) { return true; } int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue(option, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; if (optionItem != null && optionItem.Children.Count > 0) { ReCreateSettings(__instance); } } return false; } private static void ReCreateSettings(GameOptionsMenu __instance) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (ModGameOptionsMenu.TabIndex < 3) { return; } TabGroup tabGroup = (TabGroup)(ModGameOptionsMenu.TabIndex - 3); float num = 2f; CategoryHeaderMasked val = default(CategoryHeaderMasked); OptionBehaviour val2 = default(OptionBehaviour); for (int i = 0; i < OptionItem.AllOptions.Count; i++) { OptionItem optionItem = OptionItem.AllOptions[i]; if (optionItem.Tab != tabGroup) { continue; } bool flag = !optionItem.IsHiddenOn(Options.CurrentGameMode) && (optionItem.Parent == null || (!optionItem.Parent.IsHiddenOn(Options.CurrentGameMode) && optionItem.Parent.GetBool())); if (ModGameOptionsMenu.CategoryHeaderList.TryGetValue(i, ref val)) { ((Component)val).transform.localPosition = new Vector3(-0.903f, num, -2f); ((Component)val).gameObject.SetActive(flag); if (flag) { num -= 0.63f; } } else if (optionItem.IsHeader && flag) { num -= 0.3f; } if (ModGameOptionsMenu.BehaviourList.TryGetValue(i, ref val2)) { ((Component)val2).transform.localPosition = new Vector3(0.952f, num, -2f); ((Component)val2).gameObject.SetActive(flag); if (flag) { num -= 0.45f; } } } __instance.ControllerSelectable.Clear(); foreach (UiElement componentsInChild in ((Component)__instance.scrollBar).GetComponentsInChildren()) { __instance.ControllerSelectable.Add(componentsInChild); } __instance.scrollBar.SetYBoundsMax(0f - num - 1.65f); } private static BaseGameSetting GetSetting(OptionItem item) { BaseGameSetting val; if (!(item is BooleanOptionItem)) { IntegerOptionItem integerOptionItem = item as IntegerOptionItem; if (integerOptionItem == null) { FloatOptionItem floatOptionItem = item as FloatOptionItem; if (floatOptionItem == null) { StringOptionItem stringOptionItem = item as StringOptionItem; if (stringOptionItem == null) { PresetOptionItem presetOptionItem = item as PresetOptionItem; val = (BaseGameSetting)(object)((presetOptionItem == null) ? null : CreateAndInvoke(delegate { StringGameSetting obj5 = ScriptableObject.CreateInstance(); ((BaseGameSetting)obj5).Type = (OptionTypes)3; obj5.Values = Il2CppStructArray.op_Implicit((StringNames[])(object)new StringNames[presetOptionItem.ValuePresets]); obj5.Index = presetOptionItem.GetInt(); return obj5; })); } else { val = (BaseGameSetting)(object)CreateAndInvoke(delegate { StringGameSetting obj4 = ScriptableObject.CreateInstance(); ((BaseGameSetting)obj4).Type = (OptionTypes)3; obj4.Values = Il2CppStructArray.op_Implicit((StringNames[])(object)new StringNames[stringOptionItem.Selections.Length]); obj4.Index = stringOptionItem.GetInt(); return obj4; }); } } else { val = (BaseGameSetting)(object)CreateAndInvoke(delegate { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown FloatGameSetting obj3 = ScriptableObject.CreateInstance(); ((BaseGameSetting)obj3).Type = (OptionTypes)4; obj3.Value = floatOptionItem.GetFloat(); obj3.Increment = floatOptionItem.Rule.Step; obj3.ValidRange = new FloatRange(floatOptionItem.Rule.MinValue, floatOptionItem.Rule.MaxValue); obj3.ZeroIsInfinity = false; obj3.SuffixType = (NumberSuffixes)1; obj3.FormatString = string.Empty; return obj3; }); } } else { val = (BaseGameSetting)(object)CreateAndInvoke(delegate { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown IntGameSetting obj2 = ScriptableObject.CreateInstance(); ((BaseGameSetting)obj2).Type = (OptionTypes)5; obj2.Value = integerOptionItem.GetInt(); obj2.Increment = integerOptionItem.Rule.Step; obj2.ValidRange = new IntRange(integerOptionItem.Rule.MinValue, integerOptionItem.Rule.MaxValue); obj2.ZeroIsInfinity = false; obj2.SuffixType = (NumberSuffixes)1; obj2.FormatString = string.Empty; return obj2; }); } } else { val = (BaseGameSetting)(object)CreateAndInvoke(delegate { CheckboxGameSetting obj = ScriptableObject.CreateInstance(); ((BaseGameSetting)obj).Type = (OptionTypes)1; return obj; }); } BaseGameSetting val2 = val; if ((Object)(object)val2 != (Object)null) { val2.Title = (StringNames)198; } return val2; static t CreateAndInvoke(Func func) where t : BaseGameSetting { return func(); } } } [HarmonyPatch(typeof(ToggleOption))] public static class ToggleOptionPatch { [HarmonyPatch("Initialize")] [HarmonyPrefix] private static bool InitializePrefix(ToggleOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; ((TMP_Text)__instance.TitleText).text = optionItem.GetName(); ((Renderer)__instance.CheckMark).enabled = optionItem.GetBool(); return false; } return true; } [HarmonyPatch("UpdateValue")] [HarmonyPrefix] private static bool UpdateValuePrefix(ToggleOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem.AllOptions[index].SetValue(((OptionBehaviour)__instance).GetBool() ? 1 : 0); return false; } return true; } } [HarmonyPatch(typeof(NumberOption))] public static class NumberOptionPatch { private static int IncrementMultiplier { get { if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { return 5; } if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) { return 10; } return 1; } } [HarmonyPatch("Initialize")] [HarmonyPrefix] private static bool InitializePrefix(NumberOption __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown StringNames title = ((OptionBehaviour)__instance).Title; switch (title - 133) { case 3: __instance.ValidRange = new FloatRange(0f, 600f); __instance.Value = (float)Math.Round(__instance.Value, 2); break; case 9: case 10: case 11: __instance.ValidRange = new FloatRange(0f, 90f); __instance.Value = (float)Math.Round(__instance.Value, 2); break; case 7: __instance.ValidRange = new FloatRange(0f, 180f); __instance.Increment = 0.5f; __instance.Value = (float)Math.Round(__instance.Value, 2); break; case 4: case 5: case 6: __instance.Increment = 0.05f; __instance.Value = (float)Math.Round(__instance.Value, 2); break; case 0: if (DebugModeManager.IsDebugMode) { __instance.ValidRange.min = 0f; } break; } int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; ((TMP_Text)__instance.TitleText).text = optionItem.GetName(); __instance.AdjustButtonsActiveState(); return false; } return true; } [HarmonyPatch("UpdateValue")] [HarmonyPrefix] private static bool UpdateValuePrefix(NumberOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; if (optionItem is IntegerOptionItem integerOptionItem) { integerOptionItem.SetValue(integerOptionItem.Rule.GetNearestIndex(((OptionBehaviour)__instance).GetInt())); } else if (optionItem is FloatOptionItem floatOptionItem) { floatOptionItem.SetValue(floatOptionItem.Rule.GetNearestIndex(((OptionBehaviour)__instance).GetFloat())); } return false; } return true; } [HarmonyPatch("FixedUpdate")] [HarmonyPrefix] private static bool FixedUpdatePrefix(NumberOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem item = OptionItem.AllOptions[index]; if (__instance.oldValue != __instance.Value) { __instance.oldValue = __instance.Value; ((TMP_Text)__instance.ValueText).text = GetValueString(__instance, __instance.Value, item); } return false; } return true; } public static string GetValueString(NumberOption __instance, float value, OptionItem item) { if (__instance.ZeroIsInfinity && Mathf.Abs(value) < 0.0001f) { return ""; } if (item != null) { return item.GetString(); } return value.ToString(__instance.FormatString); } [HarmonyPatch("Increase")] [HarmonyPrefix] public static bool IncreasePrefix(NumberOption __instance) { if (__instance.Value == __instance.ValidRange.max) { __instance.Value = __instance.ValidRange.min; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } float num = (float)IncrementMultiplier * __instance.Increment; if (__instance.Value + num < __instance.ValidRange.max) { __instance.Value += num; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } return true; } [HarmonyPatch("Decrease")] [HarmonyPrefix] public static bool DecreasePrefix(NumberOption __instance) { if (__instance.Value == __instance.ValidRange.min) { __instance.Value = __instance.ValidRange.max; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } float num = (float)IncrementMultiplier * __instance.Increment; if (__instance.Value - num > __instance.ValidRange.min) { __instance.Value -= num; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } return true; } } [HarmonyPatch(typeof(StringOption))] public static class StringOptionPatch { [HarmonyPatch("Initialize")] [HarmonyPrefix] private static bool InitializePrefix(StringOption __instance) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Invalid comparison between Unknown and I4 int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; string name = optionItem.GetName(); SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; if (EnumHelper.GetAllValues().Any((CustomRoles x) => Translator.GetString($"{x}") == name.RemoveHtmlTags())) { name = "" + name + ""; ((TMP_Text)__instance.TitleText).fontWeight = (FontWeight)900; TextMeshPro titleText = __instance.TitleText; float outlineWidth = (((int)languageID != 5 && (int)languageID != 11 && languageID - 13 > 1) ? 0.35f : 0.15f); ((TMP_Text)titleText).outlineWidth = outlineWidth; } ((TMP_Text)__instance.TitleText).text = name; __instance.AdjustButtonsActiveState(); return false; } return true; } [HarmonyPatch("UpdateValue")] [HarmonyPrefix] private static bool UpdateValuePrefix(StringOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; optionItem.SetValue(((OptionBehaviour)__instance).GetInt()); if (optionItem is PresetOptionItem || (optionItem is StringOptionItem && optionItem.Name == "GameMode")) { if (Options.GameMode.GetInt() == 2 && !GameStates.IsHideNSeek) { Options.GameMode.SetValue(0); } else if (Options.GameMode.GetInt() != 2 && GameStates.IsHideNSeek) { Options.GameMode.SetValue(2); } GameOptionsMenuPatch.ReOpenSettings(optionItem.Name != "GameMode"); } return false; } return true; } [HarmonyPatch("FixedUpdate")] [HarmonyPrefix] private static bool FixedUpdatePrefix(StringOption __instance) { int index = default(int); if (ModGameOptionsMenu.OptionList.TryGetValue((OptionBehaviour)(object)__instance, ref index)) { OptionItem optionItem = OptionItem.AllOptions[index]; if (optionItem is StringOptionItem stringOptionItem) { if (__instance.oldValue != __instance.Value) { __instance.oldValue = __instance.Value; ((TMP_Text)__instance.ValueText).text = stringOptionItem.GetString(); } } else if (optionItem is PresetOptionItem presetOptionItem && __instance.oldValue != __instance.Value) { __instance.oldValue = __instance.Value; ((TMP_Text)__instance.ValueText).text = presetOptionItem.GetString(); } return false; } return true; } [HarmonyPatch("Increase")] [HarmonyPrefix] public static bool IncreasePrefix(StringOption __instance) { if (__instance.Value == ((Il2CppArrayBase)(object)__instance.Values).Length - 1) { __instance.Value = 0; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged?.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } return true; } [HarmonyPatch("Decrease")] [HarmonyPrefix] public static bool DecreasePrefix(StringOption __instance) { if (__instance.Value == 0) { __instance.Value = ((Il2CppArrayBase)(object)__instance.Values).Length - 1; __instance.UpdateValue(); ((OptionBehaviour)__instance).OnValueChanged?.Invoke((OptionBehaviour)(object)__instance); __instance.AdjustButtonsActiveState(); return false; } return true; } } [HarmonyPatch(typeof(RoleOptionSetting), "UpdateValuesAndText")] internal class ChanceChangePatch { public static void Postfix(RoleOptionSetting __instance) { string text = " (" + Translator.GetString("Disabled") + ")"; foreach (PassiveButton componentsInChild in ((Component)__instance).GetComponentsInChildren()) { ((Component)componentsInChild).gameObject.SetActive(false); } if (!((TMP_Text)__instance.titleText).text.Contains(text)) { TextMeshPro titleText = __instance.titleText; ((TMP_Text)titleText).text = ((TMP_Text)titleText).text + text; } if (__instance.roleChance != 0 || __instance.roleMaxCount != 0) { __instance.roleChance = 0; __instance.roleMaxCount = 0; ((OptionBehaviour)__instance).OnValueChanged.Invoke((OptionBehaviour)(object)__instance); } } } [HarmonyPatch(typeof(GameSettingMenu))] public class GameSettingMenuPatch { private static readonly Vector3 ButtonPositionLeft = new Vector3(-3.9f, -0.4f, 0f); private static readonly Vector3 ButtonPositionRight = new Vector3(-2.4f, -0.4f, 0f); private static readonly Vector3 ButtonSize = new Vector3(0.45f, 0.6f, 1f); private static GameOptionsMenu TemplateGameOptionsMenu; private static PassiveButton TemplateGameSettingsButton; private static Dictionary ModSettingsButtons = new Dictionary(); private static Dictionary ModSettingsTabs = new Dictionary(); [HarmonyPatch("Start")] [HarmonyPrefix] [HarmonyPriority(800)] public static void StartPostfix(GameSettingMenu __instance) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Expected O, but got Unknown TabGroup[] second = Options.CurrentGameMode switch { CustomGameMode.HidenSeekTOHE => Enum.GetValues().Skip(3).ToArray(), CustomGameMode.FFA => Enum.GetValues().Skip(2).ToArray(), _ => Array.Empty(), }; ModSettingsButtons = new Dictionary(); Color color = default(Color); Vector3 val2 = default(Vector3); foreach (TabGroup tab in EnumHelper.GetAllValues().Except(second)) { PassiveButton val = Object.Instantiate(TemplateGameSettingsButton, ((Component)__instance.GameSettingsButton).transform.parent); ((Component)val).gameObject.SetActive(true); ((Object)val).name = "Button_" + tab; TextMeshPro componentInChildren = ((Component)val).GetComponentInChildren(); ((MonoBehaviour)(object)componentInChildren).DestroyTranslator(); string text = tab switch { TabGroup.SystemSettings => Main.ModColor, TabGroup.ModSettings => "#59ef83", TabGroup.ModifierSettings => "#EF59AF", TabGroup.ImpostorRoles => "#f74631", TabGroup.CrewmateRoles => "#8cffff", TabGroup.NeutralRoles => "#7f8c8d", TabGroup.Addons => "#ff9ace", _ => "#ffffff", }; ((TMP_Text)componentInChildren).fontStyle = (FontStyles)16; ((TMP_Text)componentInChildren).text = $"{Translator.GetString("TabGroup." + tab)}"; ColorUtility.TryParseHtmlString(text, ref color); val.inactiveSprites.GetComponent().color = color; val.activeSprites.GetComponent().color = color; val.selectedSprites.GetComponent().color = color; ((Vector3)(ref val2))..ctor(0f, 0.5f * (float)((int)(tab + 1) / 2), 0f); ((Component)val).transform.localPosition = (((int)(tab + 1) % 2 == 0) ? ButtonPositionLeft : ButtonPositionRight) - val2; ((Component)val).transform.localScale = ButtonSize; PassiveButton component = ((Component)val).GetComponent(); component.OnClick = new ButtonClickedEvent(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { __instance.ChangeTab((int)(tab + 3), false); })); ModSettingsButtons.Add(tab, val); } ModGameOptionsMenu.OptionList = new Dictionary(); ModGameOptionsMenu.BehaviourList = new Dictionary(); ModGameOptionsMenu.CategoryHeaderList = new Dictionary(); ModSettingsTabs = new Dictionary(); TabGroup[] allValues = EnumHelper.GetAllValues(); for (int i = 0; i < allValues.Length; i++) { TabGroup key = allValues[i]; GameOptionsMenu val3 = Object.Instantiate(TemplateGameOptionsMenu, ((Component)__instance.GameSettingsTab).transform.parent); ((Object)val3).name = "tab_" + key; ((Component)val3).gameObject.SetActive(false); ModSettingsTabs.Add(key, val3); } allValues = EnumHelper.GetAllValues(); foreach (TabGroup key2 in allValues) { if (ModSettingsButtons.TryGetValue(key2, out var value)) { __instance.ControllerSelectable.Add((UiElement)(object)value); } } } private static void SetDefaultButton(GameSettingMenu __instance) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) ((Component)__instance.GamePresetsButton).gameObject.SetActive(false); PassiveButton gameSettingsButton = __instance.GameSettingsButton; ((Component)gameSettingsButton).transform.localPosition = new Vector3(-3f, -0.5f, 0f); TextMeshPro componentInChildren = ((Component)gameSettingsButton).GetComponentInChildren(); ((MonoBehaviour)(object)componentInChildren).DestroyTranslator(); ((TMP_Text)componentInChildren).fontStyle = (FontStyles)16; ((TMP_Text)componentInChildren).text = Translator.GetString("TabVanilla.GameSettings"); ((Component)gameSettingsButton).transform.localPosition = ButtonPositionLeft; ((Component)gameSettingsButton).transform.localScale = ButtonSize; ((Component)__instance.RoleSettingsButton).gameObject.SetActive(false); __instance.DefaultButtonSelected = (UiElement)(object)gameSettingsButton; __instance.ControllerSelectable = new List(); __instance.ControllerSelectable.Add((UiElement)(object)gameSettingsButton); } [HarmonyPatch("ChangeTab")] [HarmonyPrefix] public static bool ChangeTabPrefix(GameSettingMenu __instance, ref int tabNum, [HarmonyArgument(1)] bool previewOnly) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) ModGameOptionsMenu.TabIndex = tabNum; GameOptionsMenu value; PassiveButton value2; if ((previewOnly && (int)Controller.currentTouchType == 0) || !previewOnly) { TabGroup[] allValues = EnumHelper.GetAllValues(); foreach (TabGroup key in allValues) { if (ModSettingsTabs.TryGetValue(key, out value) && (Object)(object)value != (Object)null) { ((Component)value).gameObject.SetActive(false); } } allValues = EnumHelper.GetAllValues(); foreach (TabGroup key2 in allValues) { if (ModSettingsButtons.TryGetValue(key2, out value2) && (Object)(object)value2 != (Object)null) { value2.SelectButton(false); } } } if (tabNum < 3) { return true; } TabGroup tabGroup = (TabGroup)(tabNum - 3); if ((previewOnly && (int)Controller.currentTouchType == 0) || !previewOnly) { ((Component)__instance.PresetsTab).gameObject.SetActive(false); ((Component)__instance.GameSettingsTab).gameObject.SetActive(false); ((Component)__instance.RoleSettingsTab).gameObject.SetActive(false); __instance.GamePresetsButton.SelectButton(false); __instance.GameSettingsButton.SelectButton(false); __instance.RoleSettingsButton.SelectButton(false); if (ModSettingsTabs.TryGetValue(tabGroup, out value) && (Object)(object)value != (Object)null) { ((Component)value).gameObject.SetActive(true); ((MonoBehaviour)(object)__instance.MenuDescriptionText).DestroyTranslator(); switch (tabGroup) { case TabGroup.SystemSettings: case TabGroup.ModSettings: case TabGroup.ModifierSettings: ((TMP_Text)__instance.MenuDescriptionText).text = Translator.GetString("TabMenuDescription_General"); break; case TabGroup.ImpostorRoles: case TabGroup.CrewmateRoles: case TabGroup.NeutralRoles: case TabGroup.Addons: ((TMP_Text)__instance.MenuDescriptionText).text = Translator.GetString("TabMenuDescription_Roles&AddOns"); break; } } } if (previewOnly) { __instance.ToggleLeftSideDarkener(false); __instance.ToggleRightSideDarkener(true); return false; } __instance.ToggleLeftSideDarkener(true); __instance.ToggleRightSideDarkener(false); if (ModSettingsButtons.TryGetValue(tabGroup, out value2) && (Object)(object)value2 != (Object)null) { value2.SelectButton(true); } return false; } [HarmonyPatch("OnEnable")] [HarmonyPrefix] private static bool OnEnablePrefix(GameSettingMenu __instance) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Invalid comparison between Unknown and I4 if ((Object)(object)TemplateGameOptionsMenu == (Object)null) { TemplateGameOptionsMenu = Object.Instantiate(__instance.GameSettingsTab, ((Component)__instance.GameSettingsTab).transform.parent); ((Component)TemplateGameOptionsMenu).gameObject.SetActive(false); } if ((Object)(object)TemplateGameSettingsButton == (Object)null) { TemplateGameSettingsButton = Object.Instantiate(__instance.GameSettingsButton, ((Component)__instance.GameSettingsButton).transform.parent); ((Component)TemplateGameSettingsButton).gameObject.SetActive(false); } SetDefaultButton(__instance); ControllerManager.Instance.OpenOverlayMenu(((Object)__instance).name, __instance.BackButton, __instance.DefaultButtonSelected, __instance.ControllerSelectable, false); DestroyableSingleton.Instance.menuNavigationPrompts.SetActive(false); if ((int)Controller.currentTouchType != 0) { __instance.ChangeTab(1, (int)Controller.currentTouchType == 0); } ((MonoBehaviour)__instance).StartCoroutine(__instance.CoSelectDefault()); return false; } [HarmonyPatch("Close")] [HarmonyPostfix] private static void ClosePostfix(GameSettingMenu __instance) { foreach (PassiveButton value in ModSettingsButtons.Values) { Object.Destroy((Object)(object)value); } foreach (GameOptionsMenu value2 in ModSettingsTabs.Values) { Object.Destroy((Object)(object)value2); } ModSettingsButtons = new Dictionary(); ModSettingsTabs = new Dictionary(); } } [HarmonyPatch(typeof(PlayerControl), "RpcSyncSettings")] public class RpcSyncSettingsPatch { public static void Postfix() { OptionItem.SyncAllOptions(); } } [HarmonyPatch(typeof(GameStartManager), "Update")] public static class GameStartManagerMinPlayersPatch { public static void Prefix(GameStartManager __instance) { __instance.MinPlayers = 1; } } public class GameStartManagerPatch { [HarmonyPatch(typeof(GameStartManager), "Start")] public class GameStartManagerStartPatch { public static TextMeshPro HideName; public static void Postfix(GameStartManager __instance) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Invalid comparison between Unknown and I4 //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Expected O, but got Unknown GameStartManagerUpdatePatch.AlredyBegin = false; ((TMP_Text)__instance.GameRoomNameCode).text = GameCode.IntToGameName(((InnerNetClient)AmongUsClient.Instance).GameId); timer = 600f; HideName = Object.Instantiate(__instance.GameRoomNameCode, __instance.GameRoomNameCode.transform); Color val = default(Color); ((TMP_Text)HideName).text = (ColorUtility.TryParseHtmlString(Main.HideColor.Value, ref val) ? $"{Main.HideName.Value}" : $"{Main.HideName.Value}"); warningText = Object.Instantiate(__instance.GameStartText, ((Component)__instance).transform.parent); ((Object)warningText).name = "WarningText"; warningText.transform.localPosition = new Vector3(0f, ((Component)__instance).transform.localPosition.y + 3f, -1f); ((Component)warningText).gameObject.SetActive(false); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { timerText = Object.Instantiate(__instance.PlayerCounter, ((Component)__instance.StartButton).transform.parent); } else { timerText = Object.Instantiate(__instance.PlayerCounter, ((Component)__instance.StartButtonClient).transform.parent); } ((TMP_Text)timerText).fontSize = 6.2f; ((TMP_Text)timerText).autoSizeTextContainer = true; ((Object)timerText).name = "Timer"; GameObjectExtensions.DestroyChildren((MonoBehaviour)(object)timerText); ((TMP_Text)timerText).DestroySubMeshObjects(); ((TMP_Text)timerText).alignment = (TextAlignmentOptions)514; ((TMP_Text)timerText).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)timerText).outlineWidth = 0.4f; ((Object)timerText).hideFlags = (HideFlags)0; Transform transform = timerText.transform; transform.localPosition += new Vector3(-0.55f, -0.25f, 0f); timerText.transform.localScale = new Vector3(0.7f, 0.7f, 1f); ((Component)timerText).gameObject.SetActive((int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 1 && GameStates.IsVanillaServer); GameStartManagerPatch.cancelButton = Object.Instantiate(__instance.StartButton, ((Component)__instance).transform); ((Object)GameStartManagerPatch.cancelButton).name = "CancelButton"; TextMeshPro buttonText = GameStartManagerPatch.cancelButton.buttonText; ((MonoBehaviour)(object)buttonText).DestroyTranslator(); ((TMP_Text)buttonText).text = Translator.GetString("Cancel"); GameStartManagerPatch.cancelButton.inactiveSprites.GetComponent().color = new Color(0.8f, 0f, 0f, 1f); GameStartManagerPatch.cancelButton.activeSprites.GetComponent().color = Color.red; Transform val2 = GameStartManagerPatch.cancelButton.inactiveSprites.transform.Find("Shine"); if (Object.op_Implicit((Object)(object)val2)) { ((Component)val2).gameObject.SetActive(false); } PassiveButton cancelButton = GameStartManagerPatch.cancelButton; val = (GameStartManagerPatch.cancelButton.inactiveTextColor = Color.white); cancelButton.activeTextColor = val; GameStartTextlocalPosition = __instance.GameStartText.transform.localPosition; GameStartManagerPatch.cancelButton.OnClick = new ButtonClickedEvent(); ((UnityEvent)GameStartManagerPatch.cancelButton.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { __instance.ResetStartState(); })); ((Component)GameStartManagerPatch.cancelButton).gameObject.SetActive(false); if (((InnerNetClient)AmongUsClient.Instance).AmHost && GameStates.IsNormalGame) { Main.NormalOptions.ConfirmImpostor = false; Main.NormalOptions.SetBool((BoolOptionNames)3, false); if (Main.NormalOptions.KillCooldown == 0f) { Main.NormalOptions.KillCooldown = Main.LastKillCooldown.Value; } AURoleOptions.SetOpt(((Il2CppObjectBase)Main.NormalOptions).Cast()); if (AURoleOptions.ShapeshifterCooldown == 0f) { AURoleOptions.ShapeshifterCooldown = Main.LastShapeshifterCooldown.Value; } if (AURoleOptions.GuardianAngelCooldown == 0f) { AURoleOptions.GuardianAngelCooldown = Options.DefaultAngelCooldown.GetFloat(); } } } } [HarmonyPatch(typeof(GameStartManager), "Update")] public static class GameStartManagerUpdatePatch { public static bool AlredyBegin = false; private static bool update = false; private static string currentText = ""; public static float exitTimer = -1f; private static float minWait; private static float maxWait; private static int minPlayer; public static void Prefix(GameStartManager __instance) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } minWait = Options.MinWaitAutoStart.GetFloat(); maxWait = Options.MaxWaitAutoStart.GetFloat(); minPlayer = Options.PlayerAutoStart.GetInt(); minWait = 600f - minWait * 60f; maxWait *= 60f; if (DataManager.Settings.Gameplay.StreamerMode) { ((Graphic)__instance.GameRoomNameCode).color = new Color(255f, 255f, 255f, 0f); ((Behaviour)GameStartManagerStartPatch.HideName).enabled = true; } else { ((Graphic)__instance.GameRoomNameCode).color = new Color(255f, 255f, 255f, 255f); ((Behaviour)GameStartManagerStartPatch.HideName).enabled = false; } GameData instance = GameData.Instance; update = ((instance != null) ? new int?(instance.PlayerCount) : null) != __instance.LastPlayerCount; if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !Object.op_Implicit((Object)(object)GameData.Instance) || (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 0 || !Main.AutoStart.Value) { return; } Main.updateTime++; if (Main.updateTime < 50) { return; } Main.updateTime = 0; if (!GameStates.IsCountDown) { if (Options.ImmediateAutoStart.GetBool() && ((GameData.Instance.PlayerCount >= Options.StartWhenPlayersReach.GetInt() && Options.StartWhenPlayersReach.GetInt() > 1) || (timer <= (float)Options.StartWhenTimerLowerThan.GetInt() && Options.StartWhenTimerLowerThan.GetInt() > 0))) { BeginAutoStart(Options.ImmediateStartTimer.GetInt()); } else if ((GameData.Instance.PlayerCount >= minPlayer && timer <= minWait) || timer <= maxWait) { BeginAutoStart(Options.AutoStartTimer.GetInt()); } } } public static void Postfix(GameStartManager __instance) { //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Invalid comparison between Unknown and I4 //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)AmongUsClient.Instance)) { return; } string text = ""; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { bool flag = true; List list = new List(); foreach (ClientData item in ((InnerNetClient)AmongUsClient.Instance).allClients.ToArray()) { if (!((Object)(object)item.Character == (Object)null)) { DummyBehaviour component = ((Component)item.Character).GetComponent(); if ((!((Object)(object)component != (Object)null) || !((Behaviour)component).enabled) && !MatchVersions(item.Id, acceptVanilla: true)) { flag = false; list.Add(Utils.ColorString(((Il2CppArrayBase)(object)Palette.PlayerColors)[item.ColorId], item.Character.Data.PlayerName)); } } } if (!flag) { ((Component)__instance.StartButton).gameObject.SetActive(false); text = Utils.ColorString(Color32.op_Implicit(Color.red), string.Format(Translator.GetString("Warning.MismatchedVersion"), string.Join(" ", list), $"{Main.ModName}")); } ((Component)cancelButton).gameObject.SetActive((int)__instance.startState == 1); } else if (MatchVersions(((InnerNetClient)AmongUsClient.Instance).HostId, acceptVanilla: true) || Main.VersionCheat.Value || Main.IsHostVersionCheating) { exitTimer = 0f; } else { exitTimer += Time.deltaTime; if (exitTimer >= 5f) { exitTimer = 0f; AmongUsClient.Instance.ExitGame((DisconnectReasons)0); SceneChanger.ChangeScene("MainMenu"); } if (exitTimer != 0f) { text = Utils.ColorString(Color32.op_Implicit(Color.red), string.Format(Translator.GetString("Warning.AutoExitAtMismatchedVersion"), $"{Main.ModName}", Math.Round(5f - exitTimer).ToString())); } } if (text == "") { ((Component)warningText).gameObject.SetActive(false); } else { ((TMP_Text)warningText).text = text; ((Component)warningText).gameObject.SetActive(true); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { __instance.GameStartText.transform.localPosition = new Vector3(__instance.GameStartText.transform.localPosition.x, 2f, __instance.GameStartText.transform.localPosition.z); } else { __instance.GameStartText.transform.localPosition = GameStartTextlocalPosition; } ((TMP_Text)__instance.RulesPresetText).text = Translator.GetString($"Preset_{OptionItem.CurrentPreset + 1}"); if (Object.op_Implicit((Object)(object)GameData.Instance) && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 0 && GameStates.IsVanillaServer) { if (update) { currentText = ((TMP_Text)__instance.PlayerCounter).text; } timer = Mathf.Max(0f, timer -= Time.deltaTime); int value = (int)timer / 60; int value2 = (int)timer % 60; string text2 = $"{value:00}:{value2:00}"; if (timer <= 60f) { text2 = Utils.ColorString(Color32.op_Implicit(Color.red), text2); } ((TMP_Text)timerText).text = text2; } } private static void BeginAutoStart(float countdown) { if (AlredyBegin) { return; } AlredyBegin = true; new LateTask(delegate { PlayerControl[] array = Main.AllPlayerControls.Where((PlayerControl p) => p.Data.DefaultOutfit.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= p.Data.DefaultOutfit.ColorId).ToArray(); if (array.Any()) { CollectionExtensions.Do((IEnumerable)array, (Action)delegate(PlayerControl p) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(p.GetClientId(), false); }); Logger.SendInGame(Translator.GetString("Error.InvalidColorPreventStart")); Utils.SendMessage(Translator.GetString("Error.InvalidColor") + "\n" + string.Join(",", array.Select((PlayerControl p) => p.GetRealName() ?? ""))); } if (Options.RandomMapsMode.GetBool()) { byte b = GameStartRandomMap.SelectRandomMap(); if (GameStates.IsNormalGame) { Main.NormalOptions.MapId = b; } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.MapId = b; } if (b == 3) { CreateOptionsPickerPatch.SetDleks = true; } else { CreateOptionsPickerPatch.SetDleks = false; } } else if (CreateOptionsPickerPatch.SetDleks) { if (GameStates.IsNormalGame) { Main.NormalOptions.MapId = 3; } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.MapId = 3; } } IGameOptions val = (GameStates.IsNormalGame ? ((Il2CppObjectBase)Main.NormalOptions).Cast() : ((Il2CppObjectBase)Main.HideNSeekOptions).Cast()); if (GameStates.IsNormalGame) { Options.DefaultKillCooldown = Main.NormalOptions.KillCooldown; Main.LastKillCooldown.Value = Main.NormalOptions.KillCooldown; Main.NormalOptions.KillCooldown = 0f; AURoleOptions.SetOpt(val); Main.LastShapeshifterCooldown.Value = AURoleOptions.ShapeshifterCooldown; AURoleOptions.ShapeshifterCooldown = 0f; AURoleOptions.ImpostorsCanSeeProtect = false; } PlayerControl.LocalPlayer.RpcSyncSettings(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(val, AprilFoolsMode.IsAprilFoolsModeToggledOn)); RPC.RpcVersionCheck(); DestroyableSingleton.Instance.startState = (StartingStates)1; DestroyableSingleton.Instance.countDownTimer = ((countdown == 0f) ? 0.2f : countdown); ((Component)DestroyableSingleton.Instance.StartButton).gameObject.SetActive(false); }, 0.8f, "Auto Start"); } private static bool MatchVersions(int clientId, bool acceptVanilla = false) { if (!Main.playerVersion.TryGetValue(clientId, out var value)) { return acceptVanilla; } if (Main.ForkId == value.forkId && Main.version.CompareTo(value.version) == 0) { return value.tag == "f6840257(main)"; } return false; } } [HarmonyPatch(typeof(TextBoxTMP), "SetText")] public static class HiddenTextPatch { private static void Postfix(TextBoxTMP __instance) { if (((Object)__instance).name == "GameIdText") { ((TMP_Text)__instance.outputText).text = new string('*', __instance.text.Length); } } } public static float timer = 600f; private static Vector3 GameStartTextlocalPosition; private static TextMeshPro warningText; private static TextMeshPro timerText; private static PassiveButton cancelButton; } [HarmonyPatch(typeof(GameStartManager), "BeginGame")] public class GameStartRandomMap { public static bool Prefix(GameStartManager __instance) { PlayerControl[] source = Main.AllPlayerControls.Where((PlayerControl p) => p.Data.DefaultOutfit.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= p.Data.DefaultOutfit.ColorId).ToArray(); if (source.Any()) { Logger.SendInGame(Translator.GetString("Error.InvalidColorPreventStart")); Utils.SendMessage(Translator.GetString("Error.InvalidColor") + "\n" + string.Join(",", source.Select((PlayerControl p) => p.GetRealName() ?? ""))); return false; } if (Options.RandomMapsMode.GetBool()) { byte b = SelectRandomMap(); if (GameStates.IsNormalGame) { Main.NormalOptions.MapId = b; } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.MapId = b; } if (b == 3) { CreateOptionsPickerPatch.SetDleks = true; } else { CreateOptionsPickerPatch.SetDleks = false; } } else if (CreateOptionsPickerPatch.SetDleks) { if (GameStates.IsNormalGame) { Main.NormalOptions.MapId = 3; } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.MapId = 3; } } IGameOptions val = (GameStates.IsNormalGame ? ((Il2CppObjectBase)Main.NormalOptions).Cast() : ((Il2CppObjectBase)Main.HideNSeekOptions).Cast()); if (GameStates.IsNormalGame) { Options.DefaultKillCooldown = Main.NormalOptions.KillCooldown; Main.LastKillCooldown.Value = Main.NormalOptions.KillCooldown; Main.NormalOptions.KillCooldown = 0f; AURoleOptions.SetOpt(val); Main.LastShapeshifterCooldown.Value = AURoleOptions.ShapeshifterCooldown; AURoleOptions.ShapeshifterCooldown = 0f; AURoleOptions.ImpostorsCanSeeProtect = false; } PlayerControl.LocalPlayer.RpcSyncSettings(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(val, AprilFoolsMode.IsAprilFoolsModeToggledOn)); RPC.RpcVersionCheck(); __instance.ReallyBegin(false); return false; } public static byte SelectRandomMap() { IRandom instance = IRandom.Instance; List list = new List(); if (Options.UseMoreRandomMapSelection.GetBool()) { if (instance.Next(1, 100) <= Options.SkeldChance.GetInt()) { list.Add(0); } if (instance.Next(1, 100) <= Options.MiraChance.GetInt()) { list.Add(1); } if (instance.Next(1, 100) <= Options.PolusChance.GetInt()) { list.Add(2); } if (instance.Next(1, 100) <= Options.DleksChance.GetInt()) { list.Add(3); } if (instance.Next(1, 100) <= Options.AirshipChance.GetInt()) { list.Add(4); } if (instance.Next(1, 100) <= Options.FungleChance.GetInt()) { list.Add(5); } } else { int num = instance.Next(1, 100); if (num <= Options.SkeldChance.GetInt()) { list.Add(0); } if (num <= Options.MiraChance.GetInt()) { list.Add(1); } if (num <= Options.PolusChance.GetInt()) { list.Add(2); } if (num <= Options.DleksChance.GetInt()) { list.Add(3); } if (num <= Options.AirshipChance.GetInt()) { list.Add(4); } if (num <= Options.FungleChance.GetInt()) { list.Add(5); } } if (list.Any()) { byte b = list.RandomElement(); Logger.Info($"{b}", "Chance Select MapId", escapeCRLF: true, 454, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\GameStartManagerPatch.cs"); return b; } if (Options.SkeldChance.GetInt() > 0) { list.Add(0); } if (Options.MiraChance.GetInt() > 0) { list.Add(1); } if (Options.PolusChance.GetInt() > 0) { list.Add(2); } if (Options.DleksChance.GetInt() > 0) { list.Add(3); } if (Options.AirshipChance.GetInt() > 0) { list.Add(4); } if (Options.FungleChance.GetInt() > 0) { list.Add(5); } byte b2 = list.RandomElement(); Logger.Info($"{b2}", "Random Select MapId", escapeCRLF: true, 468, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\GameStartManagerPatch.cs"); return b2; } } [HarmonyPatch(typeof(GameStartManager), "ResetStartState")] internal class ResetStartStatePatch { public static void Prefix(GameStartManager __instance) { if (GameStates.IsCountDown) { GameStartManagerPatch.GameStartManagerUpdatePatch.AlredyBegin = false; SoundManager.Instance.StopSound(__instance.gameStartSound); if (GameStates.IsNormalGame) { Main.NormalOptions.KillCooldown = Options.DefaultKillCooldown; } PlayerControl.LocalPlayer.RpcSyncSettings(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameOptionsManager.Instance.CurrentGameOptions, AprilFoolsMode.IsAprilFoolsModeToggledOn)); } } } [HarmonyPatch(typeof(IGameOptionsExtensions), "GetAdjustedNumImpostors")] internal class UnrestrictedNumImpostorsPatch { public static bool Prefix(ref int __result) { __result = GameOptionsManager.Instance.CurrentGameOptions.NumImpostors; return false; } } internal class GuardAngelPatch { [HarmonyPatch(typeof(MeetingIntroAnimation), "Start")] public static class ProtectedRecentlyPatch { public static bool Prefix(MeetingIntroAnimation __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown __instance.ProtectedRecently.active = false; __instance.ProtectedRecently.transform.localPosition = new Vector3(100f, 100f, 100f); __instance.ProtectedRecentlySound = new AudioClip(); return true; } } } [HarmonyPatch(typeof(HashRandom))] internal class HashRandomPatch { [HarmonyPatch("FastNext")] [HarmonyPrefix] private static bool FastNext_Prefix([HarmonyArgument(0)] int maxInt, ref int __result) { if (IRandom.Instance is HashRandomWrapper) { return true; } __result = IRandom.Instance.Next(maxInt); return false; } [HarmonyPatch("Next", new Type[] { typeof(int) })] [HarmonyPrefix] private static bool MaxNext_Prefix([HarmonyArgument(0)] int maxInt, ref int __result) { if (IRandom.Instance is HashRandomWrapper) { return true; } __result = IRandom.Instance.Next(maxInt); return false; } [HarmonyPatch("Next", new Type[] { typeof(int), typeof(int) })] [HarmonyPrefix] private static bool MinMaxNext_Prefix([HarmonyArgument(0)] int minInt, [HarmonyArgument(1)] int maxInt, ref int __result) { if (IRandom.Instance is HashRandomWrapper) { return true; } __result = IRandom.Instance.Next(minInt, maxInt); return false; } } [HarmonyPatch(typeof(ChatController), "Toggle")] internal class CancelBanMenuStuckPatch { public static void Prefix(ChatController __instance) { if (__instance.IsOpenOrOpening && !__instance.IsAnimating) { __instance.banButton.SetVisible(false); } } } [HarmonyPatch(typeof(HudManager), "Update")] internal class HudManagerPatch { public static bool ShowDebugText; public static int LastCallNotifyRolesPerSecond; public static int NowCallNotifyRolesCount; public static int LastSetNameDesyncCount; public static int LastFPS; public static int NowFrameCount; public static float FrameRateTimer; public static TextMeshPro LowerInfoText; public static GameObject TempLowerInfoText; public static void Postfix(HudManager __instance) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Invalid comparison between Unknown and I4 //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04ef: Invalid comparison between Unknown and I4 //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_050a: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Invalid comparison between Unknown and I4 //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Invalid comparison between Unknown and I4 //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Invalid comparison between Unknown and I4 //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsModHost || (Object)(object)__instance == (Object)null) { return; } PlayerControl localPlayer = PlayerControl.LocalPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (Input.GetKeyDown((KeyCode)306) && (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted || !GameStates.IsOnlineGame) && localPlayer.CanMove) { localPlayer.Collider.offset = new Vector2(0f, 127f); } if (localPlayer.Collider.offset.y == 127f && (!Input.GetKey((KeyCode)306) || (((InnerNetClient)AmongUsClient.Instance).IsGameStarted && GameStates.IsOnlineGame))) { localPlayer.Collider.offset = new Vector2(0f, -0.3636f); } if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted || GameStates.IsHideNSeek) { return; } Utils.CountAlivePlayers(); if (SetHudActivePatch.IsActive) { if (Options.CurrentGameMode == CustomGameMode.FFA) { if ((Object)(object)LowerInfoText == (Object)null) { TempLowerInfoText = new GameObject("CountdownText"); TempLowerInfoText.transform.position = new Vector3(0f, -2f, 1f); LowerInfoText = TempLowerInfoText.AddComponent(); ((TMP_Text)LowerInfoText).alignment = (TextAlignmentOptions)514; LowerInfoText.transform.parent = ((Component)__instance).transform; LowerInfoText.transform.localPosition = new Vector3(0f, -2f, 0f); ((TMP_Text)LowerInfoText).overflowMode = (TextOverflowModes)0; ((TMP_Text)LowerInfoText).enableWordWrapping = false; ((Graphic)LowerInfoText).color = Color.white; ((TMP_Text)LowerInfoText).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)LowerInfoText).outlineWidth = 20000000f; ((TMP_Text)LowerInfoText).fontSize = 2f; } ((TMP_Text)LowerInfoText).text = FFAManager.GetHudText(); } if (localPlayer.IsAlive()) { KillButton killButton = __instance.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("KillButtonText")); } ReportButton reportButton = __instance.ReportButton; if (reportButton != null) { ((ActionButton)reportButton).OverrideText(Translator.GetString("ReportButtonText")); } SabotageButton sabotageButton = __instance.SabotageButton; if (sabotageButton != null) { ((ActionButton)sabotageButton).OverrideText(Translator.GetString("SabotageButtonText")); } localPlayer.GetRoleClass()?.SetAbilityButtonText(__instance, localPlayer.PlayerId); if ((Object)(object)LowerInfoText == (Object)null) { LowerInfoText = Object.Instantiate(((ActionButton)__instance.KillButton).buttonLabelText); LowerInfoText.transform.parent = ((Component)__instance).transform; LowerInfoText.transform.localPosition = new Vector3(0f, -2f, 0f); ((TMP_Text)LowerInfoText).alignment = (TextAlignmentOptions)514; ((Graphic)LowerInfoText).color = Palette.EnabledColor; ((TMP_Text)LowerInfoText).overflowMode = (TextOverflowModes)0; ((TMP_Text)LowerInfoText).enableWordWrapping = false; ((TMP_Text)LowerInfoText).fontSizeMin = 2.8f; ((TMP_Text)LowerInfoText).fontSizeMax = 2.8f; } if (Options.CurrentGameMode == CustomGameMode.Standard) { RoleBase roleClass = localPlayer.GetRoleClass(); ((TMP_Text)LowerInfoText).text = roleClass?.GetLowerText(localPlayer, localPlayer, Main.MeetingIsStarted, isForHud: true) ?? string.Empty; if (roleClass != null) { Color32? FaceColor; float num = roleClass.SetModdedLowerText(out FaceColor); if (FaceColor.HasValue) { ((TMP_Text)LowerInfoText).SetFaceColor(FaceColor.Value); ((TMP_Text)LowerInfoText).SetOutlineColor(new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue)); } if (((TMP_Text)LowerInfoText).fontSizeMin != num) { ((TMP_Text)LowerInfoText).fontSizeMin = num; ((TMP_Text)LowerInfoText).fontSizeMax = num; } } } ((Behaviour)LowerInfoText).enabled = ((TMP_Text)LowerInfoText).text != "" && ((TMP_Text)LowerInfoText).text != string.Empty; if ((!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 2) || GameStates.IsMeeting) { ((Behaviour)LowerInfoText).enabled = false; } if (localPlayer.CanUseKillButton()) { ((ActionButton)__instance.KillButton).ToggleVisible(localPlayer.IsAlive() && GameStates.IsInTask); localPlayer.Data.Role.CanUseKillButton = true; } else { ((ActionButton)__instance.KillButton).SetDisabled(); ((ActionButton)__instance.KillButton).ToggleVisible(false); } bool flag = localPlayer.CanUseImpostorVentButton(); ((ActionButton)__instance.ImpostorVentButton).ToggleVisible(flag); localPlayer.Data.Role.CanVent = flag; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { ((ActionButton)__instance.SabotageButton).ToggleVisible(localPlayer.CanUseSabotage()); } } else { ((ActionButton)__instance.ReportButton).Hide(); ((ActionButton)__instance.ImpostorVentButton).Hide(); ((ActionButton)__instance.KillButton).Hide(); ((ActionButton)__instance.AbilityButton).Show(); ((ActionButton)__instance.AbilityButton).OverrideText(Translator.GetString((StringNames)1545)); } } if (Input.GetKeyDown((KeyCode)121) && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 2) { __instance.ToggleMapVisible(new MapOptions { Mode = (Modes)3, AllowMovementWhileMapOpen = true }); if (((InnerNetObject)localPlayer).AmOwner) { ((Behaviour)localPlayer.MyPhysics.inputHandler).enabled = true; ConsoleJoystick.SetMode_Task(); } } if ((int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 1) { RepairSender.enabled = false; } if (Input.GetKeyDown((KeyCode)303) && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 1) { RepairSender.enabled = !RepairSender.enabled; RepairSender.Reset(); } if (RepairSender.enabled && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 1) { if (Input.GetKeyDown((KeyCode)48)) { RepairSender.Input(0); } if (Input.GetKeyDown((KeyCode)49)) { RepairSender.Input(1); } if (Input.GetKeyDown((KeyCode)50)) { RepairSender.Input(2); } if (Input.GetKeyDown((KeyCode)51)) { RepairSender.Input(3); } if (Input.GetKeyDown((KeyCode)52)) { RepairSender.Input(4); } if (Input.GetKeyDown((KeyCode)53)) { RepairSender.Input(5); } if (Input.GetKeyDown((KeyCode)54)) { RepairSender.Input(6); } if (Input.GetKeyDown((KeyCode)55)) { RepairSender.Input(7); } if (Input.GetKeyDown((KeyCode)56)) { RepairSender.Input(8); } if (Input.GetKeyDown((KeyCode)57)) { RepairSender.Input(9); } if (Input.GetKeyDown((KeyCode)13)) { RepairSender.InputEnter(); } } } } [HarmonyPatch(typeof(PlayerControl), "ToggleHighlight")] internal class ToggleHighlightPatch { public static void Postfix(PlayerControl __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsHideNSeek) { PlayerControl localPlayer = PlayerControl.LocalPlayer; if (GameStates.IsInTask && localPlayer.CanUseKillButton()) { ((Renderer)__instance.cosmetics.currentBodySprite.BodySprite).material.SetColor("_OutlineColor", Utils.GetRoleColor(localPlayer.GetCustomRole())); } } } } [HarmonyPatch(typeof(Vent), "SetOutline")] internal class SetVentOutlinePatch { public static void Postfix(Vent __instance, [HarmonyArgument(1)] ref bool mainTarget) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsHideNSeek) { Color roleColor = PlayerControl.LocalPlayer.GetRoleColor(); ((Renderer)__instance.myRend).material.SetColor("_OutlineColor", roleColor); ((Renderer)__instance.myRend).material.SetColor("_AddColor", mainTarget ? roleColor : Color.clear); } } } [HarmonyPatch(typeof(HudManager), "SetHudActive")] [HarmonyPatch(new Type[] { typeof(PlayerControl), typeof(RoleBehaviour), typeof(bool) })] internal class SetHudActivePatch { public static bool IsActive; public static void Postfix(HudManager __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(2)] bool isActive) { ((ActionButton)__instance.ReportButton).ToggleVisible(!GameStates.IsLobby && isActive); if (!GameStates.IsModHost || GameStates.IsHideNSeek) { return; } IsActive = isActive; if (!GameStates.IsLobby && isActive && !((Object)(object)player == (Object)null)) { if (player.Is(CustomRoles.Oblivious) || player.Is(CustomRoles.KillingMachine)) { ((ActionButton)__instance.ReportButton).ToggleVisible(false); } if (player.Is(CustomRoles.Mare) && !Utils.IsActive((SystemTypes)7)) { ((ActionButton)__instance.KillButton).ToggleVisible(false); } ((ActionButton)__instance.KillButton).ToggleVisible(player.CanUseKillButton()); ((ActionButton)__instance.ImpostorVentButton).ToggleVisible(player.CanUseImpostorVentButton()); ((ActionButton)__instance.SabotageButton).ToggleVisible(player.CanUseSabotage()); } } } [HarmonyPatch(typeof(VentButton), "DoClick")] internal class VentButtonDoClickPatch { public static bool Prefix(VentButton __instance) { if (GameStates.IsHideNSeek) { return true; } PlayerControl localPlayer = PlayerControl.LocalPlayer; if (!localPlayer.Is(CustomRoles.Swooper) || !localPlayer.Is(CustomRoles.Wraith) || !localPlayer.Is(CustomRoles.Chameleon) || localPlayer.inVent || (Object)(object)__instance.currentTarget == (Object)null || !localPlayer.CanMove || !((Behaviour)__instance).isActiveAndEnabled) { return true; } if (localPlayer != null) { PlayerPhysics myPhysics = localPlayer.MyPhysics; if (myPhysics != null) { myPhysics.RpcEnterVent(__instance.currentTarget.Id); } } return false; } } [HarmonyPatch(typeof(MapBehaviour), "Show")] internal class MapBehaviourShowPatch { public static void Prefix(ref MapOptions opts) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 if (GameStates.IsMeeting || GameStates.IsHideNSeek) { return; } Modes mode = opts.Mode; if (((int)mode == 1 || (int)mode == 3) ? true : false) { if (PlayerControl.LocalPlayer.CanUseSabotage()) { opts.Mode = (Modes)3; } else { opts.Mode = (Modes)1; } } } } [HarmonyPatch(typeof(TaskPanelBehaviour), "SetTaskText")] internal class TaskPanelBehaviourPatch { public static void Postfix(TaskPanelBehaviour __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Invalid comparison between Unknown and I4 //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsModHost || GameStates.IsLobby) { return; } if (GameStates.IsHideNSeek) { __instance.open = false; return; } PlayerControl localPlayer = PlayerControl.LocalPlayer; string text = ((TMP_Text)__instance.taskText).text; if (text == "None" || (Object)(object)localPlayer == (Object)null) { return; } if (!localPlayer.GetCustomRole().IsVanilla()) { string text2 = localPlayer.GetDisplayRoleAndSubName(localPlayer) + ":\r\n"; text2 += localPlayer.GetRoleInfo(); string text3 = Utils.ColorString(Color32.op_Implicit(localPlayer.GetRoleColor()), text2); switch (Options.CurrentGameMode) { case CustomGameMode.Standard: { string[] array = text.Split("\r\n\n")[0].Split("\r\n\n")[0].Split("\r\n"); StringBuilder stringBuilder = new StringBuilder(); string[] array2 = array; for (int i = 0; i < array2.Length; i++) { string text4 = array2[i].Trim(); if ((!text4.StartsWith("") && !text4.StartsWith("")) || stringBuilder.Length >= 1 || text4.Contains('(')) { stringBuilder.Append(text4 + "\r\n"); } } if (stringBuilder.Length > 1) { string text5 = stringBuilder.ToString().TrimEnd('\n').TrimEnd('\r'); if (!Utils.HasTasks(localPlayer.Data, ForRecompute: false) && stringBuilder.ToString().Count((char s) => s == '\n') >= 2) { text5 = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(localPlayer.GetCustomRole()).ShadeColor(0.2f)), Translator.GetString("FakeTask")) + "\r\n" + text5; } text3 = text3 + "\r\n\r\n" + text5 + ""; } if (MeetingStates.FirstMeeting) { text3 = text3 + "\r\n\r\n" + Translator.GetString("PressF1ShowMainRoleDes"); if (Main.PlayerStates.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var value2) && value2.SubRoles.Count >= 1) { text3 = text3 + "\r\n" + Translator.GetString("PressF2ShowAddRoleDes"); } text3 = text3 + "\r\n" + Translator.GetString("PressF3ShowRoleSettings"); if (value2.SubRoles.Count >= 1) { text3 = text3 + "\r\n" + Translator.GetString("PressF4ShowAddOnsSettings"); } text3 += ""; } break; } case CustomGameMode.FFA: { Dictionary SummaryText2 = new Dictionary(); foreach (byte key in Main.PlayerStates.Keys) { string str = Main.AllPlayerNames[key].RemoveHtmlTags().Replace("\r\n", string.Empty); string value = Utils.GetProgressText(key) + " " + Utils.ColorString(Main.PlayerColors[key], str); if (!(Utils.GetProgressText(key).Trim() == string.Empty)) { SummaryText2[key] = value; } } List<(int, byte)> list = new List<(int, byte)>(); foreach (byte key2 in Main.PlayerStates.Keys) { list.Add((FFAManager.GetRankOfScore(key2), key2)); } list.Sort(); foreach (var item in list.Where(((int, byte) x) => SummaryText2.ContainsKey(x.Item2))) { text3 = text3 + "\r\n" + SummaryText2[item.Item2]; } text3 = "" + text3 + ""; break; } } ((TMP_Text)__instance.taskText).text = text3; } if (RepairSender.enabled && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 1) { ((TMP_Text)__instance.taskText).text = RepairSender.GetText(); } } } internal class RepairSender { public static bool enabled; public static bool TypingAmount; public static int SystemType; public static int amount; public static void Input(int num) { if (!TypingAmount) { SystemType *= 10; SystemType += num; } else { amount *= 10; amount += num; } } public static void InputEnter() { if (!TypingAmount) { TypingAmount = true; } else { Send(); } } public static void Send() { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)(byte)SystemType, (byte)amount); Reset(); } public static void Reset() { TypingAmount = false; SystemType = 0; amount = 0; } public static string GetText() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) string[] obj = new string[5] { SystemType.ToString(), "(", null, null, null }; SystemTypes val = (SystemTypes)(byte)SystemType; obj[2] = ((object)(SystemTypes)(ref val)).ToString(); obj[3] = ")\r\n"; obj[4] = amount.ToString(); return string.Concat(obj); } } public static class CustomButton { public static Sprite Get(string name) { return Utils.LoadSprite("TOHE.Resources.Images.Skills." + name + ".png", 115f); } } [HarmonyPriority(520)] [HarmonyPatch(typeof(HudManager), "Update")] public static class HudSpritePatch { private static Sprite Kill; private static Sprite Ability; private static Sprite Vent; private static Sprite Report; public static void Postfix(HudManager __instance) { if ((Object)(object)__instance == (Object)null) { return; } PlayerControl localPlayer = PlayerControl.LocalPlayer; if ((Object)(object)localPlayer == (Object)null || !Main.EnableCustomButton.Value || ((InnerNetClient)AmongUsClient.Instance).IsGameOver || GameStates.IsLobby || GameStates.IsHideNSeek || !GameStates.IsModHost || !SetHudActivePatch.IsActive || !localPlayer.IsAlive()) { return; } if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted || !Main.introDestroyed) { Kill = null; Ability = null; Vent = null; Report = null; return; } bool value; bool shapeshifting = Main.CheckShapeshift.TryGetValue(localPlayer.PlayerId, out value) && value; if (!Object.op_Implicit((Object)(object)Kill)) { Kill = ((ActionButton)__instance.KillButton).graphic.sprite; } if (!Object.op_Implicit((Object)(object)Ability)) { Ability = ((ActionButton)__instance.AbilityButton).graphic.sprite; } if (!Object.op_Implicit((Object)(object)Vent)) { Vent = ((ActionButton)__instance.ImpostorVentButton).graphic.sprite; } if (!Object.op_Implicit((Object)(object)Report)) { Report = ((ActionButton)__instance.ReportButton).graphic.sprite; } Sprite sprite = Kill; Sprite sprite2 = Ability; Sprite sprite3 = Vent; Sprite sprite4 = Report; RoleBase roleClass = localPlayer.GetRoleClass(); if (roleClass != null) { Sprite val = roleClass?.GetKillButtonSprite(localPlayer, shapeshifting); if (val != null) { sprite = val; } Sprite val2 = roleClass?.ImpostorVentButtonSprite(localPlayer); if (val2 != null) { sprite3 = val2; } Sprite val3 = roleClass?.GetAbilityButtonSprite(localPlayer, shapeshifting); if (val3 != null) { sprite2 = val3; } Sprite val4 = roleClass?.ReportButtonSprite; if (val4 != null) { sprite4 = val4; } } ((ActionButton)__instance.KillButton).graphic.sprite = sprite; ((ActionButton)__instance.ImpostorVentButton).graphic.sprite = sprite3; ((ActionButton)__instance.AbilityButton).graphic.sprite = sprite2; ((ActionButton)__instance.ReportButton).graphic.sprite = sprite4; CooldownHelpers.SetCooldownNormalizedUvs(((ActionButton)__instance.KillButton).graphic); CooldownHelpers.SetCooldownNormalizedUvs(((ActionButton)__instance.ImpostorVentButton).graphic); CooldownHelpers.SetCooldownNormalizedUvs(((ActionButton)__instance.AbilityButton).graphic); CooldownHelpers.SetCooldownNormalizedUvs(((ActionButton)__instance.ReportButton).graphic); } } [HarmonyPatch(typeof(HudManager), "CoShowIntro")] internal class CoShowIntroPatch { public static void Prefix() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !GameStates.IsModHost) { return; } new LateTask(delegate { try { Utils.DoNotifyRoles(null, null, isForMeeting: false, NoCache: true); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\IntroPatch.cs", 32, "Prefix"); } }, 0.35f, "Do Notify Roles In Show Intro"); } } [HarmonyPatch(typeof(IntroCutscene), "ShowRole")] internal class SetUpRoleTextPatch { public static bool IsInIntro; public static void Postfix(IntroCutscene __instance) { if (!GameStates.IsModHost) { return; } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { IsInIntro = false; Utils.DoNotifyRoles(null, null, isForMeeting: false, NoCache: true); } new LateTask(delegate { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) PlayerControl localPlayer = PlayerControl.LocalPlayer; CustomRoles customRole = localPlayer.GetCustomRole(); if (Options.CurrentGameMode == CustomGameMode.FFA) { Color val = default(Color); Color color = (Color)(ColorUtility.TryParseHtmlString("#00ffff", ref val) ? val : new Color(255f, 255f, 255f, 255f)); ((Component)__instance.YouAreText.transform).gameObject.SetActive(false); ((TMP_Text)__instance.RoleText).text = "FREE FOR ALL"; ((Graphic)__instance.RoleText).color = color; ((Graphic)__instance.RoleBlurbText).color = color; ((TMP_Text)__instance.RoleBlurbText).text = "KILL EVERYONE TO WIN"; } else { if (!customRole.IsVanilla()) { ((Graphic)__instance.YouAreText).color = Utils.GetRoleColor(customRole); ((TMP_Text)__instance.RoleText).text = Utils.GetRoleName(customRole); ((Graphic)__instance.RoleText).color = Utils.GetRoleColor(customRole); ((Graphic)__instance.RoleBlurbText).color = Utils.GetRoleColor(customRole); ((TMP_Text)__instance.RoleBlurbText).text = localPlayer.GetRoleInfo(); } CustomRoles[] array = Main.PlayerStates[localPlayer.PlayerId].SubRoles.ToArray(); foreach (CustomRoles customRoles in array) { TextMeshPro roleBlurbText = __instance.RoleBlurbText; ((TMP_Text)roleBlurbText).text = ((TMP_Text)roleBlurbText).text + "\n" + Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(customRoles)), Translator.GetString($"{customRoles}Info")); } TextMeshPro roleText = __instance.RoleText; ((TMP_Text)roleText).text = ((TMP_Text)roleText).text + Utils.GetSubRolesText(localPlayer.PlayerId, disableColor: false, intro: true); } }, 0.0001f, "Override Role Text"); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameOver && !GameStates.IsLobby && !((Object)(object)PlayerControl.LocalPlayer == (Object)null)) { string name = Main.AllPlayerNames[PlayerControl.LocalPlayer.PlayerId]; PlayerControl.LocalPlayer.SetName(name); } }, 1f, "Reset Name For Modded Client"); } } [HarmonyPatch(typeof(IntroCutscene), "CoBegin")] internal class CoBeginPatch { public static void Prefix() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) if (RoleBasisChanger.IsChangeInProgress) { return; } LogHandler logHandler = Logger.Handler("Info"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; logHandler.Info("------------Player Names------------"); PlayerControl[] array = allPlayerControls; foreach (PlayerControl val in array) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(4, 5); defaultInterpolatedStringHandler.AppendFormatted(((InnerNetObject)val).AmOwner ? "[*]" : "", -3); defaultInterpolatedStringHandler.AppendFormatted(val.PlayerId, -2); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(((Object)val).name.PadRightV2(20)); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(((TMP_Text)val.cosmetics.nameText).text); defaultInterpolatedStringHandler.AppendLiteral("("); StringNames val2 = ((Il2CppArrayBase)(object)Palette.ColorNames)[val.Data.DefaultOutfit.ColorId]; defaultInterpolatedStringHandler.AppendFormatted(((object)(StringNames)(ref val2)).ToString().Replace("Color", "")); defaultInterpolatedStringHandler.AppendLiteral(")"); logHandler.Info(defaultInterpolatedStringHandler.ToStringAndClear()); ((TMP_Text)val.cosmetics.nameText).text = ((Object)val).name; } logHandler.Info("------------Roles / Add-ons------------"); if (PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug || GameStates.IsLocalGame) { array = allPlayerControls; foreach (PlayerControl val3 in array) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 4); defaultInterpolatedStringHandler.AppendFormatted(((InnerNetObject)val3).AmOwner ? "[*]" : "", -3); defaultInterpolatedStringHandler.AppendFormatted(val3.PlayerId, -2); defaultInterpolatedStringHandler.AppendLiteral(":"); object value; if (val3 == null) { value = null; } else { NetworkedPlayerInfo data = val3.Data; value = ((data != null) ? data.PlayerName?.PadRightV2(20) : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(":"); defaultInterpolatedStringHandler.AppendFormatted(val3.GetAllRoleName().RemoveHtmlTags()); logHandler.Info(defaultInterpolatedStringHandler.ToStringAndClear()); } } else { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("------------Roles / Add-ons------------"); array = allPlayerControls; foreach (PlayerControl val4 in array) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 4, stringBuilder2); handler.AppendFormatted(((InnerNetObject)val4).AmOwner ? "[*]" : "", -3); handler.AppendFormatted(val4.PlayerId, -2); handler.AppendLiteral(":"); object value2; if (val4 == null) { value2 = null; } else { NetworkedPlayerInfo data2 = val4.Data; value2 = ((data2 != null) ? data2.PlayerName?.PadRight(20) : null); } handler.AppendFormatted((string?)value2); handler.AppendLiteral(":"); handler.AppendFormatted(val4.GetAllRoleName().RemoveHtmlTags()); stringBuilder2.AppendLine(ref handler); } try { string text = Convert.ToBase64String(EncryptDES(Encoding.UTF8.GetBytes(stringBuilder.ToString()), $"TOHE{PlayerControl.LocalPlayer.PlayerId}00000000".Substring(0, 8))); logHandler.Info(text); } catch (Exception ex) { logHandler.Error("Encryption error: " + ex.Message); } } logHandler.Info("------------Player Platforms------------"); array = allPlayerControls; foreach (PlayerControl val5 in array) { try { string text2 = (((InnerNetObject)val5).AmOwner ? "[*]" : " "); string text3 = text2; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 3); defaultInterpolatedStringHandler.AppendFormatted(val5.PlayerId, -2); defaultInterpolatedStringHandler.AppendLiteral(":"); NetworkedPlayerInfo data3 = val5.Data; defaultInterpolatedStringHandler.AppendFormatted((data3 == null) ? null : data3.PlayerName?.PadRightV2(20)); defaultInterpolatedStringHandler.AppendLiteral(":"); ClientData client = val5.GetClient(); object value3; if (client == null) { value3 = null; } else { PlatformSpecificData platformData = client.PlatformData; if (platformData == null) { value3 = null; } else { Platforms platform = platformData.Platform; value3 = ((object)(Platforms)(ref platform)).ToString()?.Replace("Standalone", ""); } } defaultInterpolatedStringHandler.AppendFormatted((string)value3, -11); text2 = text3 + defaultInterpolatedStringHandler.ToStringAndClear(); text2 = ((!Main.playerVersion.TryGetValue(val5.GetClientId(), out var value4)) ? (text2 + ":Vanilla, ClientId :" + val5.GetClientId()) : (text2 + $":Mod({value4.forkId}/{value4.version}:{value4.tag}), ClientId :{val5.GetClientId()}")); logHandler.Info(text2); } catch (Exception ex2) { Logger.Exception(ex2, "Platform", 171, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\IntroPatch.cs"); } } logHandler.Info("------------Vanilla Settings------------"); string[] array2 = IGameOptionsExtensions.ToHudString(GameOptionsManager.Instance.CurrentGameOptions, Object.op_Implicit((Object)(object)GameData.Instance) ? GameData.Instance.PlayerCount : 10).Split("\r\n").Skip(1) .ToArray(); foreach (string text4 in array2) { logHandler.Info(text4); } logHandler.Info("------------Mod Settings------------"); OptionItem[] array3 = OptionItem.AllOptions.ToArray(); foreach (OptionItem optionItem in array3) { if (!optionItem.IsHiddenOn(Options.CurrentGameMode) && ((optionItem.Parent == null) ? (!optionItem.GetString().Equals("0%")) : optionItem.Parent.GetBool())) { logHandler.Info(((optionItem.Parent == null) ? optionItem.GetName(disableColor: true, console: true).RemoveHtmlTags().PadRightV2(40) : ("┗ " + optionItem.GetName(disableColor: true, console: true).RemoveHtmlTags()).PadRightV2(41)) + ":" + optionItem.GetString().RemoveHtmlTags()); } } if (GameStates.IsNormalGame) { logHandler.Info("-------------Other Information-------------"); logHandler.Info($"Number players: {allPlayerControls.Length}"); array = allPlayerControls; foreach (PlayerControl val6 in array) { Main.PlayerStates[val6.PlayerId].InitTask(val6); } GameData.Instance.RecomputeTaskCounts(); TaskState.InitialTotalTasks = GameData.Instance.TotalTasks; } GameStates.InGame = true; RPC.RpcVersionCheck(); Utils.DoNotifyRoles(); if (((InnerNetClient)AmongUsClient.Instance).AmHost && GameStates.IsHideNSeek && RandomSpawn.IsRandomSpawn()) { RandomSpawn.SpawnMap spawnMap = Utils.GetActiveMapId() switch { 0 => new RandomSpawn.SkeldSpawnMap(), 1 => new RandomSpawn.MiraHQSpawnMap(), 2 => new RandomSpawn.PolusSpawnMap(), 3 => new RandomSpawn.DleksSpawnMap(), 5 => new RandomSpawn.FungleSpawnMap(), _ => null, }; if (spawnMap != null) { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)spawnMap.RandomTeleport); } } } public static byte[] EncryptDES(byte[] data, string key) { using SymmetricAlgorithm symmetricAlgorithm = DES.Create(); symmetricAlgorithm.Key = Encoding.UTF8.GetBytes(key); symmetricAlgorithm.IV = Encoding.UTF8.GetBytes(key); using MemoryStream memoryStream = new MemoryStream(); using (CryptoStream cryptoStream = new CryptoStream(memoryStream, symmetricAlgorithm.CreateEncryptor(), CryptoStreamMode.Write)) { cryptoStream.Write(data, 0, data.Length); } return memoryStream.ToArray(); } } [HarmonyPatch(typeof(IntroCutscene), "BeginCrewmate")] internal class BeginCrewmatePatch { public static bool Prefix(IntroCutscene __instance, ref List teamToDisplay) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); if (customRole.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) { teamToDisplay = new List(); teamToDisplay.Add(PlayerControl.LocalPlayer); __instance.BeginImpostor(teamToDisplay); __instance.overlayHandle.color = Palette.ImpostorRed; return false; } if (PlayerControl.LocalPlayer.Is(Custom_Team.Neutral) && !customRole.IsMadmate()) { teamToDisplay = new List(); teamToDisplay.Add(PlayerControl.LocalPlayer); } if (PlayerControl.LocalPlayer.Is(CustomRoles.Executioner)) { List val = new List(); val.Add(PlayerControl.LocalPlayer); foreach (byte value in Executioner.Target.Values) { PlayerControl playerById = Utils.GetPlayerById(value); val.Add(playerById); } teamToDisplay = val; } if (PlayerControl.LocalPlayer.Is(CustomRoles.Lawyer)) { List val2 = new List(); val2.Add(PlayerControl.LocalPlayer); foreach (byte value2 in Lawyer.Target.Values) { PlayerControl playerById2 = Utils.GetPlayerById(value2); val2.Add(playerById2); } teamToDisplay = val2; } return true; } public static void Postfix(IntroCutscene __instance) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_0675: Unknown result type (might be due to invalid IL or missing references) //IL_067a: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_071a: Unknown result type (might be due to invalid IL or missing references) //IL_0767: Unknown result type (might be due to invalid IL or missing references) //IL_0772: Unknown result type (might be due to invalid IL or missing references) //IL_0777: Unknown result type (might be due to invalid IL or missing references) CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); ((Component)__instance.ImpostorText).gameObject.SetActive(false); switch (customRole.GetCustomRoleTeam()) { case Custom_Team.Impostor: { ((TMP_Text)__instance.TeamTitle).text = Translator.GetString("TeamImpostor"); TextMeshPro teamTitle3 = __instance.TeamTitle; Color color = (((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); ((Graphic)teamTitle3).color = color; PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)1); ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = Translator.GetString("SubText.Impostor"); break; } case Custom_Team.Crewmate: { ((TMP_Text)__instance.TeamTitle).text = Translator.GetString("TeamCrewmate"); TextMeshPro teamTitle2 = __instance.TeamTitle; Color color = (((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue))); ((Graphic)teamTitle2).color = color; PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)0); ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = Translator.GetString("SubText.Crewmate"); break; } case Custom_Team.Neutral: { ((TMP_Text)__instance.TeamTitle).text = Translator.GetString("TeamNeutral"); TextMeshPro teamTitle = __instance.TeamTitle; Color color = (((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue))); ((Graphic)teamTitle).color = color; PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)5); ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = Translator.GetString("SubText.Neutral"); break; } } switch (customRole) { case CustomRoles.ShapeshifterTOHE: case CustomRoles.ShapeMaster: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)5); break; case CustomRoles.PhantomTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)9); break; case CustomRoles.TrackerTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)10); break; case CustomRoles.NoisemakerTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)8); break; case CustomRoles.EngineerTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)3); break; case CustomRoles.ScientistTOHE: case CustomRoles.Doctor: case CustomRoles.Medic: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)2); break; case CustomRoles.Bomber: case CustomRoles.Terrorist: { AudioClip openSound = ((PlayerTask)((IEnumerable)ShipStatus.Instance.CommonTasks).FirstOrDefault((Func)((NormalPlayerTask task) => (int)((PlayerTask)task).TaskType == 12))).MinigamePrefab.OpenSound; PlayerControl.LocalPlayer.Data.Role.IntroSound = openSound; break; } case CustomRoles.Snitch: case CustomRoles.TaskManager: case CustomRoles.Workaholic: PlayerControl.LocalPlayer.Data.Role.IntroSound = DestroyableSingleton.Instance.TaskCompleteSound; break; case CustomRoles.Hater: case CustomRoles.Opportunist: case CustomRoles.Revolutionist: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)0); break; case CustomRoles.Mechanic: case CustomRoles.Provocateur: PlayerControl.LocalPlayer.Data.Role.IntroSound = ShipStatus.Instance.SabotageSound; break; case CustomRoles.GM: ((TMP_Text)__instance.TeamTitle).text = Utils.GetRoleName(customRole); ((Graphic)__instance.TeamTitle).color = Utils.GetRoleColor(customRole); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(customRole); ((Component)__instance.ImpostorText).gameObject.SetActive(false); PlayerControl.LocalPlayer.Data.Role.IntroSound = DestroyableSingleton.Instance.TaskCompleteSound; break; case CustomRoles.KillingMachine: case CustomRoles.Knight: case CustomRoles.NiceGuesser: case CustomRoles.Reverie: case CustomRoles.Sheriff: case CustomRoles.Veteran: case CustomRoles.Vigilante: PlayerControl.LocalPlayer.Data.Role.IntroSound = PlayerControl.LocalPlayer.KillSfx; break; case CustomRoles.Swooper: case CustomRoles.Chameleon: case CustomRoles.Wraith: PlayerControl.LocalPlayer.Data.Role.IntroSound = PlayerControl.LocalPlayer.MyPhysics.ImpostorDiscoveredSound; break; } if (PlayerControl.LocalPlayer.Is(CustomRoles.Madmate) || customRole.IsMadmate()) { ((TMP_Text)__instance.TeamTitle).text = Translator.GetString("TeamMadmate"); TextMeshPro teamTitle4 = __instance.TeamTitle; Color color = (((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue))); ((Graphic)teamTitle4).color = color; PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)1); ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = Translator.GetString("SubText.Madmate"); } if (Options.CurrentGameMode == CustomGameMode.FFA) { ((TMP_Text)__instance.TeamTitle).text = "FREE FOR ALL"; TextMeshPro teamTitle5 = __instance.TeamTitle; Color color = (((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue))); ((Graphic)teamTitle5).color = color; PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound((RoleTypes)5); ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = "KILL EVERYONE TO WIN"; } if (Input.GetKey((KeyCode)303)) { ((TMP_Text)__instance.TeamTitle).text = "明天就跑路啦"; ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = "嘿嘿嘿嘿嘿嘿"; ((Graphic)__instance.TeamTitle).color = Color.cyan; StartFadeIntro(__instance, Color.cyan, Color.yellow); } if (Input.GetKey((KeyCode)305)) { ((TMP_Text)__instance.TeamTitle).text = "警告"; ((Component)__instance.ImpostorText).gameObject.SetActive(true); ((TMP_Text)__instance.ImpostorText).text = "请远离无知的玩家"; ((Graphic)__instance.TeamTitle).color = Color.magenta; StartFadeIntro(__instance, Color.magenta, Color.magenta); } } public static AudioClip GetIntroSound(RoleTypes roleType) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) RoleBehaviour? obj = ((IEnumerable)DestroyableSingleton.Instance.AllRoles).FirstOrDefault((Func)((RoleBehaviour role) => role.Role == roleType)); if (obj == null) { return null; } return obj.IntroSound; } private static async void StartFadeIntro(IntroCutscene __instance, Color start, Color end) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) await Task.Delay(1000); int milliseconds = 0; while (true) { await Task.Delay(20); milliseconds += 20; float num = (float)milliseconds / 500f; Color color = Color.Lerp(start, end, num); if ((Object)(object)__instance == (Object)null || milliseconds > 500) { break; } ((Renderer)__instance.BackgroundBar).material.color = color; } Logger.Info("ループを終了します", "StartFadeIntro", escapeCRLF: true, 442, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\IntroPatch.cs"); } } [HarmonyPatch(typeof(IntroCutscene), "BeginImpostor")] internal class BeginImpostorPatch { public static bool Prefix(IntroCutscene __instance, ref List yourTeam) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); if (customRole.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) { yourTeam = new List(); yourTeam.Add(PlayerControl.LocalPlayer); __instance.overlayHandle.color = Palette.ImpostorRed; return true; } if (customRole.IsCrewmate() && (int)customRole.GetDYRole() == 1) { yourTeam = new List(); yourTeam.Add(PlayerControl.LocalPlayer); foreach (PlayerControl item in Main.AllPlayerControls.Where((PlayerControl x) => !((InnerNetObject)x).AmOwner)) { yourTeam.Add(item); } __instance.BeginCrewmate(yourTeam); __instance.overlayHandle.color = Palette.CrewmateBlue; return false; } if (customRole.IsNeutral()) { yourTeam = new List(); yourTeam.Add(PlayerControl.LocalPlayer); foreach (PlayerControl item2 in Main.AllPlayerControls.Where((PlayerControl x) => !((InnerNetObject)x).AmOwner)) { yourTeam.Add(item2); } __instance.BeginCrewmate(yourTeam); __instance.overlayHandle.color = Color32.op_Implicit(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue)); return false; } BeginCrewmatePatch.Prefix(__instance, ref yourTeam); return true; } public static void Postfix(IntroCutscene __instance) { BeginCrewmatePatch.Postfix(__instance); } } [HarmonyPatch(typeof(IntroCutscene), "OnDestroy")] internal class IntroCutsceneDestroyPatch { public static void Postfix() { if (!GameStates.IsInGame || RoleBasisChanger.SkipTasksAfterAssignRole) { return; } Main.introDestroyed = true; if (!GameStates.AirshipIsActive) { foreach (PlayerState value in Main.PlayerStates.Values) { value.HasSpawned = true; } } CustomRoleManager.Add(); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (GameStates.IsNormalGame) { if (!GameStates.AirshipIsActive) { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl pc) { pc.RpcResetAbilityCooldown(); }); if (Options.FixFirstKillCooldown.GetBool() && Options.CurrentGameMode != CustomGameMode.FFA) { new LateTask(delegate { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl x) { x.ResetKillCooldown(); }); CollectionExtensions.Do(Main.AllPlayerControls.Where((PlayerControl x) => Main.AllPlayerKillCooldown[x.PlayerId] - 2f > 0f), (Action)delegate(PlayerControl pc) { pc.SetKillCooldown(Options.FixKillCooldownValue.GetFloat() - 2f); }); }, 2f, "Fix Kill Cooldown Task"); } } new LateTask(delegate { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl pc) { pc.RpcSetRoleDesync((RoleTypes)5, canOverride: false, -3); }); }, 2f, "Set Impostor For Server"); } if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) { PlayerControl.LocalPlayer.RpcExile(); Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); } else if (GhostRoleAssign.forceRole.Any()) { new LateTask(delegate { CollectionExtensions.Do>((IEnumerable>)GhostRoleAssign.forceRole, (Action>)delegate(KeyValuePair x) { Utils.GetPlayerById(x.Key).RpcExile(); Main.PlayerStates[x.Key].SetDead(); }); }, 3f, "Set Dev Ghost-Roles"); } if (GameStates.IsNormalGame && (RandomSpawn.IsRandomSpawn() || Options.CurrentGameMode == CustomGameMode.FFA)) { RandomSpawn.SpawnMap spawnMap = Utils.GetActiveMapId() switch { 0 => new RandomSpawn.SkeldSpawnMap(), 1 => new RandomSpawn.MiraHQSpawnMap(), 2 => new RandomSpawn.PolusSpawnMap(), 3 => new RandomSpawn.DleksSpawnMap(), 5 => new RandomSpawn.FungleSpawnMap(), _ => null, }; if (spawnMap != null) { CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)spawnMap.RandomTeleport); } } if (Main.ResetCamPlayerList.Contains(PlayerControl.LocalPlayer.PlayerId)) { PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; } } Logger.Info("OnDestroy", "IntroCutscene", escapeCRLF: true, 572, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\IntroPatch.cs"); } } [HarmonyPatch(typeof(JoinGameButton), "OnClick")] internal class JoinGameButtonPatch { public static void Prefix(JoinGameButton __instance) { if (!((Object)(object)__instance.GameIdText == (Object)null) && __instance.GameIdText.text == "" && Regex.IsMatch(GUIUtility.systemCopyBuffer.Trim('\r', '\n'), "^[A-Z]{6}$")) { Logger.Info(GUIUtility.systemCopyBuffer ?? "", "ClipBoard", escapeCRLF: true, 14, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\JoinGameButtonPatch.cs"); __instance.GameIdText.SetText(GUIUtility.systemCopyBuffer.Trim('\r', '\n'), ""); } } } public class FallFromLadder { public static Dictionary TargetLadderData; private static int Chance => (Options.LadderDeathChance as StringOptionItem).GetChance(); public static void Reset() { TargetLadderData = new Dictionary(); } public static void OnClimbLadder(PlayerPhysics player, Ladder source) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (Options.LadderDeath.GetBool() && !player.myPlayer.Is(CustomRoles.Solsticer)) { Vector3 position = ((Component)source).transform.position; Vector3 position2 = ((Component)source.Destination).transform.position; if (position.y > position2.y && IRandom.Instance.Next(1, 101) <= Chance) { TargetLadderData[player.myPlayer.PlayerId] = position2; } } } public static void FixedUpdate(PlayerControl player) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!player.Data.Disconnected && TargetLadderData.ContainsKey(player.PlayerId) && Vector2.Distance(Vector2.op_Implicit(TargetLadderData[player.PlayerId]), Vector2.op_Implicit(((Component)player).transform.position)) < 0.5f && !player.Data.IsDead) { player.Data.IsDead = true; new LateTask(delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Vector2.op_Implicit(TargetLadderData[player.PlayerId]) + new Vector2(0.1f, 0f); ushort val2 = (ushort)(NetHelpers.XRange.ReverseLerp(val.x) * 65535f); ushort val3 = (ushort)(NetHelpers.YRange.ReverseLerp(val.y) * 65535f); player.SetDeathReason(PlayerState.DeathReason.Fall); CustomRpcSender customRpcSender = CustomRpcSender.Create("LadderFallRpc", (SendOption)0); customRpcSender.AutoStartRpc(((InnerNetObject)player.NetTransform).NetId, 21).Write(val2).Write(val3) .EndRpc(); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 12).WriteNetObject((InnerNetObject)(object)player).Write(1) .EndRpc(); customRpcSender.SendMessage(); player.NetTransform.SnapTo(val); player.MurderPlayer(player, (MurderResultFlags)1); }, 0.05f, "Ladder Fall Task"); } } } [HarmonyPatch(typeof(PlayerPhysics), "ClimbLadder")] internal class LadderPatch { public static void Postfix(PlayerPhysics __instance, Ladder source) { FallFromLadder.OnClimbLadder(__instance, source); } } [HarmonyPatch(typeof(MainMenuManager), "Start")] [HarmonyPriority(800)] public class MainMenuManagerStartPatch { public static GameObject amongUsLogo; public static GameObject Ambience; public static SpriteRenderer ToheLogo { get; private set; } private static void Postfix(MainMenuManager __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) amongUsLogo = GameObject.Find("LOGO-AU"); Transform parent = __instance.gameModeButtons.transform.parent; GameObject val = new GameObject("titleLogo_TOHE"); Transform transform = val.transform; ToheLogo = val.AddComponent(); transform.parent = parent; transform.localPosition = new Vector3(-0.16f, 0f, 1f); transform.localScale *= 1.2f; if ((Object)(object)(Ambience = GameObject.Find("Ambience")) != (Object)null) { Ambience.SetActive(false); } } } [HarmonyPatch(typeof(MainMenuManager), "LateUpdate")] internal class MainMenuManagerLateUpdatePatch { private static int lateUpdate = 590; private static void Postfix(MainMenuManager __instance) { if ((Object)(object)__instance == (Object)null) { return; } if (lateUpdate <= 600) { lateUpdate++; return; } lateUpdate = 0; PassiveButton playOnlineButton = __instance.PlayOnlineButton; if ((Object)(object)playOnlineButton != (Object)null && RunLoginPatch.isAllowedOnline && !Main.hasAccess) { PassiveButton playLocalButton = __instance.playLocalButton; if ((Object)(object)playLocalButton != (Object)null) { ((Component)playLocalButton).gameObject.SetActive(false); } ((Component)playOnlineButton).gameObject.SetActive(false); DestroyableSingleton.Instance.ShowCustom(Translator.GetString("NoAccess")); } } } [HarmonyPatch(typeof(MainMenuManager))] public static class MainMenuManagerPatch { private static PassiveButton template; private static PassiveButton gitHubButton; private static PassiveButton donationButton; private static PassiveButton discordButton; private static PassiveButton websiteButton; [HarmonyPatch("Start")] [HarmonyPostfix] [HarmonyPriority(400)] public static void Start_Postfix(MainMenuManager __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template == (Object)null) { template = __instance.quitButton; } Application.targetFrameRate = (Main.UnlockFPS.Value ? 165 : 60); Transform transform = ((Component)__instance.screenTint).gameObject.transform; transform.localPosition += new Vector3(1000f, 0f); ((Renderer)__instance.screenTint).enabled = false; __instance.rightPanelMask.SetActive(true); ((Component)((Component)__instance.mainMenuUI.FindChild("BackgroundTexture")).transform).gameObject.SetActive(false); ((Component)((Component)__instance.mainMenuUI.FindChild("WindowShine")).transform).gameObject.SetActive(false); ((Component)__instance.mainMenuUI.FindChild("ScreenCover")).gameObject.SetActive(false); GameObject gameObject = ((Component)__instance.mainMenuUI.FindChild("LeftPanel")).gameObject; GameObject gameObject2 = ((Component)__instance.mainMenuUI.FindChild("RightPanel")).gameObject; ((Renderer)gameObject2.gameObject.GetComponent()).enabled = false; GameObject gameObject3 = ((Component)gameObject2.FindChild("MaskedBlackScreen")).gameObject; ((Renderer)gameObject3.GetComponent()).enabled = false; gameObject3.transform.localScale = new Vector3(7.35f, 4.5f, 4f); Transform transform2 = __instance.mainMenuUI.gameObject.transform; transform2.position += new Vector3(-0.2f, 0f); ((Renderer)gameObject.gameObject.GetComponent()).enabled = false; ((Renderer)gameObject.gameObject.FindChild("Divider")).enabled = false; ((IEnumerable)gameObject.GetComponentsInChildren(true)).Where((SpriteRenderer r) => ((Object)r).name == "Shine").ToList().ForEach(delegate(SpriteRenderer r) { ((Renderer)r).enabled = false; }); GameObject val = new GameObject("SplashArt"); val.transform.position = new Vector3(0f, 0f, 600f); SpriteRenderer obj = val.AddComponent(); string folder = "TOHE.Resources.Background."; IRandom instance = IRandom.Instance; if (instance.Next(0, 100) < 30) { folder += "PrevArtWinner"; } else { folder += "CurrentArtWinner"; } string[] array = (from resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames() where resourceName.StartsWith(folder) && resourceName.EndsWith(".png") select resourceName).ToArray(); int num = instance.Next(0, array.Length); obj.sprite = Utils.LoadSprite(array[num], 150f); if ((Object)(object)template == (Object)null) { return; } if ((Object)(object)donationButton == (Object)null) { donationButton = CreateButton("donationButton", new Vector3(-1.8f, -1.1f, 1f), new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue), new Color32((byte)75, byte.MaxValue, byte.MaxValue, byte.MaxValue), delegate { Application.OpenURL(Main.DonationInviteUrl); }, Translator.GetString("SupportUs")); } ((Component)donationButton).gameObject.SetActive(Main.ShowDonationButton); if ((Object)(object)gitHubButton == (Object)null) { gitHubButton = CreateButton("GitHubButton", new Vector3(-1.8f, -1.5f, 1f), new Color32((byte)153, (byte)153, (byte)153, byte.MaxValue), new Color32((byte)209, (byte)209, (byte)209, byte.MaxValue), delegate { Application.OpenURL(Main.GitHubInviteUrl); }, Translator.GetString("GitHub")); } ((Component)gitHubButton).gameObject.SetActive(Main.ShowGitHubButton); if ((Object)(object)discordButton == (Object)null) { discordButton = CreateButton("DiscordButton", new Vector3(-1.8f, -1.9f, 1f), new Color32((byte)88, (byte)101, (byte)242, byte.MaxValue), new Color32((byte)148, (byte)161, byte.MaxValue, byte.MaxValue), delegate { Application.OpenURL(Main.DiscordInviteUrl); }, Translator.GetString("Discord")); } ((Component)discordButton).gameObject.SetActive(Main.ShowDiscordButton); if ((Object)(object)websiteButton == (Object)null) { websiteButton = CreateButton("WebsiteButton", new Vector3(-1.8f, -2.3f, 1f), new Color32((byte)251, (byte)81, (byte)44, byte.MaxValue), new Color32((byte)211, (byte)77, (byte)48, byte.MaxValue), delegate { Application.OpenURL(Main.WebsiteInviteUrl); }, Translator.GetString("Website")); } ((Component)websiteButton).gameObject.SetActive(Main.ShowWebsiteButton); PassiveButton howToPlayButton = __instance.howToPlayButton; Transform val2 = ((Component)howToPlayButton).transform.parent.Find("FreePlayButton"); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } GameObjectExtensions.SetLocalX(((Component)howToPlayButton).transform, 0f); } public static PassiveButton CreateButton(string name, Vector3 localPosition, Color32 normalColor, Color32 hoverColor, Action action, string label, Vector2? scale = null) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) PassiveButton val = Object.Instantiate(template, ((Component)MainMenuManagerStartPatch.ToheLogo).transform); ((Object)val).name = name; Object.Destroy((Object)(object)((Component)val).GetComponent()); ((Component)val).transform.localPosition = localPosition; val.OnClick = new ButtonClickedEvent(); ((UnityEvent)val.OnClick).AddListener(UnityAction.op_Implicit(action)); TMP_Text component = ((Component)((Component)val).transform.Find("FontPlacer/Text_TMP")).GetComponent(); ((MonoBehaviour)(object)component).DestroyTranslator(); float num2 = (component.fontSizeMin = 3.5f); float fontSize = (component.fontSizeMax = num2); component.fontSize = fontSize; component.enableWordWrapping = false; component.text = label; SpriteRenderer component2 = val.inactiveSprites.GetComponent(); SpriteRenderer component3 = val.activeSprites.GetComponent(); component2.color = Color32.op_Implicit(normalColor); component3.color = Color32.op_Implicit(hoverColor); Transform parent = component.transform.parent; Object.Destroy((Object)(object)((Component)parent).GetComponent()); Object.Destroy((Object)(object)((Component)component).GetComponent()); GameObjectExtensions.SetLocalX(parent, 0f); GameObjectExtensions.SetLocalX(component.transform, 0f); component.horizontalAlignment = (HorizontalAlignmentOptions)2; BoxCollider2D component4 = ((Component)val).GetComponent(); if (scale.HasValue) { Vector2 val2 = (component4.size = scale.Value); Vector2 size = (component3.size = val2); component2.size = size; } ((Collider2D)component4).offset = new Vector2(0f, 0f); return val; } public static void Modify(this PassiveButton passiveButton, Action action) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown if (!((Object)(object)passiveButton == (Object)null)) { passiveButton.OnClick = new ButtonClickedEvent(); ((UnityEvent)passiveButton.OnClick).AddListener(UnityAction.op_Implicit(action)); } } public static T FindChild(this MonoBehaviour obj, string name) where T : Object { return ((IEnumerable)((Component)obj).GetComponentsInChildren()).First((T c) => ((Object)c).name == name); } public static T FindChild(this GameObject obj, string name) where T : Object { return ((IEnumerable)obj.GetComponentsInChildren()).First((T c) => ((Object)c).name == name); } public static void ForEach(this IEnumerable source, Action action) { if (source == null) { throw new ArgumentNullException("source"); } IEnumerator enumerator = source.GetEnumerator(); while (enumerator.MoveNext()) { action(enumerator.Current); } enumerator.Dispose(); } [HarmonyPatch("OpenGameModeMenu")] [HarmonyPatch("OpenAccountMenu")] [HarmonyPatch("OpenCredits")] [HarmonyPostfix] public static void OpenMenu_Postfix() { if ((Object)(object)MainMenuManagerStartPatch.ToheLogo != (Object)null) { ((Component)MainMenuManagerStartPatch.ToheLogo).gameObject.SetActive(false); } } [HarmonyPatch("ResetScreen")] [HarmonyPostfix] public static void ResetScreen_Postfix() { if ((Object)(object)MainMenuManagerStartPatch.ToheLogo != (Object)null) { ((Component)MainMenuManagerStartPatch.ToheLogo).gameObject.SetActive(true); } } } [HarmonyPatch(typeof(MeetingHud), "CheckForEndVoting")] internal class CheckForEndVotingPatch { public static string TempExileMsg; public static bool Prefix(MeetingHud __instance) { //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_08d7: Unknown result type (might be due to invalid IL or missing references) //IL_08dc: Unknown result type (might be due to invalid IL or missing references) //IL_08de: Unknown result type (might be due to invalid IL or missing references) //IL_08ff: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_07b2: Unknown result type (might be due to invalid IL or missing references) //IL_097e: Unknown result type (might be due to invalid IL or missing references) //IL_0983: Unknown result type (might be due to invalid IL or missing references) //IL_0989: Unknown result type (might be due to invalid IL or missing references) //IL_098b: Unknown result type (might be due to invalid IL or missing references) //IL_0948: Unknown result type (might be due to invalid IL or missing references) //IL_084d: Unknown result type (might be due to invalid IL or missing references) //IL_086f: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } bool flag = false; if (Input.GetKeyDown((KeyCode)287)) { flag = true; } LogHandler logHandler = Logger.Handler("Vote"); try { List statesList = new List(); VoterState[] array; VoterState[] array2; int num; foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)__instance.playerStates) { if ((Object)(object)item == (Object)null) { continue; } PlayerControl playerById = Utils.GetPlayerById(item.TargetPlayerId); if ((Object)(object)playerById == (Object)null) { continue; } if (item.DidVote && playerById.PlayerId == item.VotedFor && item.VotedFor < 253 && !playerById.Data.IsDead && Madmate.MadmateSpawnMode.GetInt() == 2 && Main.MadmateNum < CustomRoles.Madmate.GetCount() && playerById.CanBeMadmate()) { Main.MadmateNum++; playerById.RpcSetCustomRole(CustomRoles.Madmate); ExtendedPlayerControl.RpcSetCustomRole(playerById.PlayerId, CustomRoles.Madmate); Utils.NotifyRoles(playerById, null, isForMeeting: true, NoCache: true); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(38, 3); defaultInterpolatedStringHandler.AppendLiteral("Assign in meeting by self vote: "); object value; if (playerById == null) { value = null; } else { NetworkedPlayerInfo data = playerById.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" = "); defaultInterpolatedStringHandler.AppendFormatted(playerById.GetCustomRole()); defaultInterpolatedStringHandler.AppendLiteral(" + "); defaultInterpolatedStringHandler.AppendFormatted(CustomRoles.Madmate); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Madmate", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } if (Dictator.CheckVotingForTarget(playerById, item)) { PlayerControl playerById2 = Utils.GetPlayerById(item.VotedFor); TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, playerById.PlayerId); statesList.Add(new VoterState { VoterId = item.TargetPlayerId, VotedForId = item.VotedFor }); List list = statesList; num = 0; array = (VoterState[])(object)new VoterState[list.Count]; foreach (VoterState item2 in list) { array[num] = item2; num++; } array2 = array; NetworkedPlayerInfo val = (Main.LastVotedPlayerInfo = (ExileControllerWrapUpPatch.AntiBlackout_LastExiled = playerById2.Data)); if (AntiBlackout.BlackOutIsActive) { bool blackOutIsActive = AntiBlackout.BlackOutIsActive; if (blackOutIsActive) { __instance.AntiBlackRpcVotingComplete(array2, val, tie: false); } else { __instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(array2), val, false); } if ((Object)(object)val != (Object)null) { AntiBlackout.ShowExiledInfo = blackOutIsActive; ConfirmEjections(val, blackOutIsActive); } } else { __instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(array2), val, false); if ((Object)(object)val != (Object)null) { ConfirmEjections(val); } } Logger.Info(playerById2.GetNameWithRole() + " expelled by Dictator", "Dictator", escapeCRLF: true, 101, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); CheckForDeathOnExile(PlayerState.DeathReason.Vote, item.VotedFor); Logger.Info("Dictatorial vote, forced closure of the meeting", "Special Phase", escapeCRLF: true, 105, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); playerById2.SetRealKiller(playerById); return true; } if (!item.DidVote || item.VotedFor >= 253 || !playerById.IsAlive()) { continue; } PlayerControl playerById3 = Utils.GetPlayerById(item.VotedFor); if ((Object)(object)playerById3 == (Object)null || !playerById3.IsAlive() || playerById3.Data.Disconnected) { Utils.SendMessage(Translator.GetString("VoteDead"), playerById.PlayerId); __instance.UpdateButtons(); __instance.RpcClearVote(playerById.GetClientId()); Swapper.CheckSwapperTarget(item.VotedFor); } else if ((Object)(object)playerById3 != (Object)null) { playerById.GetRoleClass()?.OnVote(playerById, playerById3); playerById3.GetRoleClass()?.OnVoted(playerById3, playerById); if (playerById3.Is(CustomRoles.Aware)) { Aware.OnVoted(playerById, item); } } } if (!flag) { foreach (PlayerVoteArea item3 in (Il2CppArrayBase)(object)__instance.playerStates) { if (!item3.DidVote) { PlayerControl playerById4 = Utils.GetPlayerById(item3.TargetPlayerId); if (playerById4 != null && playerById4.IsAlive()) { return false; } } } } NetworkedPlayerInfo val2 = PlayerControl.LocalPlayer.Data; bool tie = false; foreach (PlayerVoteArea item4 in (Il2CppArrayBase)(object)__instance.playerStates) { if ((Object)(object)item4 == (Object)null) { continue; } logHandler.Info(string.Format("{0,-2}{1}:{2,-3}{3}", item4.TargetPlayerId, ("(" + Utils.GetVoteName(item4.TargetPlayerId) + ")").PadRightV2(40), item4.VotedFor, "(" + Utils.GetVoteName(item4.VotedFor) + ")")); PlayerControl playerById5 = Utils.GetPlayerById(item4.TargetPlayerId); if ((Object)(object)playerById5 == (Object)null || (Object)(object)playerById5.Data == (Object)null || playerById5.Data.Disconnected) { continue; } if (Options.VoteMode.GetBool()) { if (item4.VotedFor == 253 && !playerById5.Data.IsDead && (!Options.WhenSkipVoteIgnoreFirstMeeting.GetBool() || !MeetingStates.FirstMeeting) && (!Options.WhenSkipVoteIgnoreNoDeadBody.GetBool() || MeetingStates.IsExistDeadBody) && (!Options.WhenSkipVoteIgnoreEmergency.GetBool() || !MeetingStates.IsEmergencyMeeting)) { switch (Options.GetWhenSkipVote()) { case VoteMode.Suicide: TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, item4.TargetPlayerId); logHandler.Info(playerById5.GetNameWithRole() + " voted to skip, so the player will suicide"); break; case VoteMode.SelfVote: item4.VotedFor = item4.TargetPlayerId; logHandler.Info(playerById5.GetNameWithRole() + " voted to skip, so the player voted self"); break; } } if (item4.VotedFor == 254 && !playerById5.Data.IsDead) { switch (Options.GetWhenNonVote()) { case VoteMode.Suicide: TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, item4.TargetPlayerId); logHandler.Info(playerById5.GetNameWithRole() + " did not vote, so the player will suicide"); break; case VoteMode.SelfVote: item4.VotedFor = item4.TargetPlayerId; logHandler.Info(playerById5.GetNameWithRole() + " did not vote, so the player voted self"); break; case VoteMode.Skip: item4.VotedFor = 253; logHandler.Info(playerById5.GetNameWithRole() + " did not vote, so the player voted skip"); break; } } } RoleBase roleClass = Utils.GetPlayerById(item4.TargetPlayerId).GetRoleClass(); if (!roleClass.HideVote(item4) && (item4.TargetPlayerId != item4.VotedFor || Madmate.MadmateSpawnMode.GetInt() != 2)) { statesList.Add(new VoterState { VoterId = item4.TargetPlayerId, VotedForId = item4.VotedFor }); if (playerById5.GetRoleClass() is Swapper swapper) { swapper.SwapVotes(__instance); } roleClass?.AddVisualVotes(item4, ref statesList); if (CheckRole(item4.TargetPlayerId, CustomRoles.TicketsStealer)) { Stealer.AddVisualVotes(item4, ref statesList); } if (CheckRole(item4.TargetPlayerId, CustomRoles.Paranoia) && Paranoia.DualVotes.GetBool()) { Paranoia.AddVisualVotes(item4, ref statesList); } if (CheckRole(item4.TargetPlayerId, CustomRoles.Knighted) && !Monarch.HideAdditionalVotesForKnighted.GetBool()) { statesList.Add(new VoterState { VoterId = item4.TargetPlayerId, VotedForId = item4.VotedFor }); } } } Dictionary VotingData = __instance.CustomCalculateVotes(); if (CustomRoles.Influenced.RoleExist()) { Influenced.ChangeVotingData(VotingData); VotingData = __instance.CustomCalculateVotes(CountInfluenced: true); } for (int i = 0; i < statesList.Count; i++) { VoterState val3 = statesList[i]; PlayerControl playerById6 = Utils.GetPlayerById(val3.VoterId); if (!((Object)(object)playerById6 == (Object)null) && playerById6.IsAlive()) { PlayerVoteArea playerVoteArea = GetPlayerVoteArea(val3.VoterId); if (playerVoteArea.VotedFor != val3.VotedForId) { val3.VotedForId = playerVoteArea.VotedFor; } if (playerById6.Is(CustomRoles.Silent)) { val3.VotedForId = 254; } statesList[i] = val3; } } List list2 = statesList; num = 0; array = (VoterState[])(object)new VoterState[list2.Count]; foreach (VoterState item5 in list2) { array[num] = item5; num++; } array2 = array; byte exileId = byte.MaxValue; int max = 0; logHandler.Info("=========Vote Result========="); foreach (KeyValuePair item6 in VotingData) { logHandler.Info($"{Utils.GetVoteName(item6.Key)}({item6.Key}): {item6.Value} votes"); if (item6.Value > max) { logHandler.Info($"{Utils.GetVoteName(item6.Key)}({item6.Key}) have a higher number of votes ({item6.Value})"); exileId = item6.Key; max = item6.Value; tie = false; } else if (item6.Value == max) { logHandler.Info($"{Utils.GetVoteName(item6.Key)}({item6.Key}) has the same number of votes as {Utils.GetVoteName(exileId)}({exileId}) - Count: {item6.Value}"); exileId = byte.MaxValue; tie = true; } logHandler.Info($"Exiled ID: {exileId} ({Utils.GetVoteName(exileId)}), max: {max} votes"); } logHandler.Info($"Decision to exiled a player: {exileId} ({Utils.GetVoteName(exileId)})"); bool flag2 = false; if (tie) { byte b = byte.MaxValue; KeyValuePair[] array3 = VotingData.Where((KeyValuePair x) => x.Key < 15 && x.Value == max).ToArray(); for (num = 0; num < array3.Length; num++) { KeyValuePair keyValuePair = array3[num]; if (Tiebreaker.VoteFor.Contains(keyValuePair.Key)) { if (b != byte.MaxValue) { b = byte.MaxValue; break; } b = keyValuePair.Key; } } if (b != byte.MaxValue) { Logger.Info("Flat breakers cover expulsion of players", "Tiebreaker Vote", escapeCRLF: true, 315, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); val2 = Utils.GetPlayerInfoById(b); tie = false; flag2 = true; } } List list3 = Utils.GetRoleBasesByType()?.ToList(); if (Collector.HasEnabled && list3 != null) { CollectionExtensions.Do((IEnumerable)list3, (Action)delegate(Collector x) { x.CollectAmount(VotingData, __instance); }); } if (Options.VoteMode.GetBool() && Options.WhenTie.GetBool() && tie) { switch ((TieMode)Options.WhenTie.GetValue()) { case TieMode.Default: val2 = ((IEnumerable)GameData.Instance.AllPlayers.ToArray()).FirstOrDefault((Func)((NetworkedPlayerInfo info) => info.PlayerId == exileId)); break; case TieMode.All: { byte[] array4 = (from x in VotingData where x.Key < 15 && x.Value == max select x into kvp select kvp.Key).ToArray(); byte[] array5 = array4; for (num = 0; num < array5.Length; num++) { Utils.GetPlayerById(array5[num]).SetRealKiller(null); } TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Vote, array4); val2 = null; break; } case TieMode.Random: { val2 = ((IEnumerable)((IEnumerable)GameData.Instance.AllPlayers.ToArray()).OrderBy((NetworkedPlayerInfo _) => Guid.NewGuid())).FirstOrDefault((Func)((NetworkedPlayerInfo x) => VotingData.TryGetValue(x.PlayerId, out var value2) && value2 == max)); tie = false; break; } } } else if (!flag2) { val2 = ((IEnumerable)GameData.Instance.AllPlayers.ToArray()).FirstOrDefault((Func)((NetworkedPlayerInfo info) => !tie && info.PlayerId == exileId)); } if (Keeper.IsTargetExiled(exileId)) { exileId = byte.MaxValue; val2 = Utils.GetPlayerInfoById(exileId); } if (val2 != null) { val2.Object.SetRealKiller(null); } ExileControllerWrapUpPatch.AntiBlackout_LastExiled = val2; Main.LastVotedPlayerInfo = val2; if (AntiBlackout.BlackOutIsActive) { bool blackOutIsActive2 = AntiBlackout.BlackOutIsActive; if (blackOutIsActive2) { __instance.AntiBlackRpcVotingComplete(array2, val2, tie); } else { __instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(array2), val2, tie); } if ((Object)(object)val2 != (Object)null) { AntiBlackout.ShowExiledInfo = blackOutIsActive2; ConfirmEjections(val2, blackOutIsActive2); } } else { __instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(array2), val2, tie); if ((Object)(object)val2 != (Object)null) { ConfirmEjections(val2); } } CheckForDeathOnExile(PlayerState.DeathReason.Vote, exileId); return false; } catch (Exception ex) { Logger.SendInGame(string.Format(Translator.GetString("Error.MeetingException"), ex.Message)); throw; } } private static void ConfirmEjections(NetworkedPlayerInfo exiledPlayer, bool AntiBlackoutStore = false) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (Object)(object)exiledPlayer == (Object)null) { return; } byte playerId = exiledPlayer.PlayerId; if (playerId > 254) { return; } string realName = exiledPlayer.Object.GetRealName(isMeeting: true); Main.LastVotedPlayer = realName; PlayerControl player = Utils.GetPlayerById(exiledPlayer.PlayerId); Translator.GetString(exiledPlayer.GetCustomRole().ToString()); exiledPlayer.GetCustomRole(); string text = Utils.GetDisplayRoleAndSubName(playerId, playerId, notShowAddOns: true); if (Options.ConfirmEgoistOnEject.GetBool() && player.Is(CustomRoles.Egoist)) { text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Egoist)), text.RemoveHtmlTags()); } if (Options.ConfirmLoversOnEject.GetBool() && player.Is(CustomRoles.Lovers)) { text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lovers)), text.RemoveHtmlTags()); } if (Rascal.AppearAsMadmate(player)) { text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetRoleString("Mad-") + text.RemoveHtmlTags()); } string name = ""; int num = 0; int num2 = 0; if (CustomRoles.Bard.RoleExist()) { Main.BardCreations++; try { name = ModUpdater.Get("https://v1.hitokoto.cn/?encode=text"); } catch { name = Translator.GetString("ByBardGetFailed"); } name = name + "\n\t\t——" + Translator.GetString("ByBard"); } else { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { CustomRoles customRole = val.GetCustomRole(); if (customRole.IsImpostor() && (Object)(object)val != (Object)(object)exiledPlayer.Object) { num++; } else if (customRole.IsNK() && (Object)(object)val != (Object)(object)exiledPlayer.Object) { num2++; } } switch (Options.CEMode.GetInt()) { case 0: name = string.Format(Translator.GetString("PlayerExiled"), realName); break; case 1: if (player.GetCustomRole().IsImpostor() || player.Is(CustomRoles.Parasite) || player.Is(CustomRoles.Crewpostor) || player.Is(CustomRoles.Refugee)) { name = string.Format(Translator.GetString("BelongTo"), realName, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), Translator.GetString("TeamImpostor"))); } else if (player.GetCustomRole().IsCrewmate()) { name = string.Format(Translator.GetString("IsGood"), realName); } else if (player.GetCustomRole().IsNeutral() && !player.Is(CustomRoles.Parasite) && !player.Is(CustomRoles.Refugee) && !player.Is(CustomRoles.Crewpostor)) { name = string.Format(Translator.GetString("BelongTo"), realName, Utils.ColorString(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue), Translator.GetString("TeamNeutral"))); } break; case 2: name = string.Format(Translator.GetString("PlayerIsRole"), realName, text); if (Options.ShowTeamNextToRoleNameOnEject.GetBool()) { name += " ("; if (player.GetCustomRole().IsImpostor() || player.Is(CustomRoles.Madmate)) { name += Utils.ColorString(new Color32(byte.MaxValue, (byte)25, (byte)25, byte.MaxValue), Translator.GetString("TeamImpostor")); } else if (player.GetCustomRole().IsNeutral() || player.Is(CustomRoles.Charmed)) { name += Utils.ColorString(new Color32((byte)127, (byte)140, (byte)141, byte.MaxValue), Translator.GetString("TeamNeutral")); } else if (player.GetCustomRole().IsCrewmate()) { name += Utils.ColorString(new Color32((byte)140, byte.MaxValue, byte.MaxValue, byte.MaxValue), Translator.GetString("TeamCrewmate")); } name += ")"; } break; } bool DecidedWinner = false; player.GetRoleClass()?.CheckExile(exiledPlayer, ref DecidedWinner, isMeetingHud: true, ref name); CollectionExtensions.Do((IEnumerable)CustomRoleManager.AllEnabledRoles, (Action)delegate(RoleBase roleClass) { roleClass.CheckExileTarget(exiledPlayer, ref DecidedWinner, isMeetingHud: true, ref name); }); if (DecidedWinner) { name += ""; } if (Options.ShowImpRemainOnEject.GetBool() && !DecidedWinner) { name += "\n"; string text2 = ((num2 > 0) ? "" : ""); if (num == 0) { name = name + Translator.GetString("NoImpRemain") + text2; } if (num == 1) { name = name + Translator.GetString("OneImpRemain") + text2; } if (num == 2) { name = name + Translator.GetString("TwoImpRemain") + text2; } if (num == 3) { name = name + Translator.GetString("ThreeImpRemain") + text2; } if (Options.ShowNKRemainOnEject.GetBool() && num2 > 0) { if (num2 == 1) { name = name + string.Format(Translator.GetString("OneNeutralRemain"), num2) + text2; } else { name = name + string.Format(Translator.GetString("NeutralRemain"), num2) + text2; } } } } name += ""; TempExileMsg = name; new LateTask(delegate { try { if (GameStates.IsInGame) { exiledPlayer.UpdateName(name, Utils.GetClientById(exiledPlayer.ClientId)); PlayerControl obj3 = player; if (obj3 != null) { obj3.RpcSetName(name); } } } catch (Exception value2) { Logger.Error($"Error after change exiled player name: {value2}", "ConfirmEjections", escapeCRLF: true, 513, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } }, 4f, "Change Exiled Player Name"); new LateTask(delegate { try { if (GameStates.IsInGame && !player.Data.Disconnected) { PlayerControl obj2 = player; if (obj2 != null) { obj2.RpcSetName(realName); } } if (GameStates.IsInGame && player.Data.Disconnected) { player.Data.PlayerName = realName; exiledPlayer.UpdateName(realName, Utils.GetClientById(exiledPlayer.ClientId)); } } catch (Exception value) { Logger.Error($"Error after change exiled player name back: {value}", "ConfirmEjections", escapeCRLF: true, 535, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } }, 7f, "Change Exiled Player Name Back"); if (AntiBlackoutStore) { AntiBlackout.StoreExiledMessage = name; Logger.Info(AntiBlackout.StoreExiledMessage, "AntiBlackoutStore", escapeCRLF: true, 542, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } } public static bool CheckRole(byte id, CustomRoles role) { PlayerControl val = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl pc) => pc.PlayerId == id)); if ((Object)(object)val != (Object)null) { return val.Is(role); } return false; } public static PlayerVoteArea GetPlayerVoteArea(byte playerId) { if ((Object)(object)MeetingHud.Instance == (Object)null || !((IEnumerable)MeetingHud.Instance.playerStates).Any()) { return null; } foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)MeetingHud.Instance.playerStates) { if (item.TargetPlayerId == playerId) { return item; } } return null; } public static void ReturnChangedPva(PlayerVoteArea pva) { Il2CppReferenceArray playerStates = MeetingHud.Instance.playerStates; int num = ((Il2CppArrayBase)(object)playerStates).IndexOf(((IEnumerable)playerStates).FirstOrDefault((Func)((PlayerVoteArea ipva) => ipva.TargetPlayerId == pva.TargetPlayerId))); if (num != -1) { ((Il2CppArrayBase)(object)MeetingHud.Instance.playerStates)[num] = pva; } } public static void TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason deathReason, params byte[] playerIds) { List list = new List(); byte[] array = playerIds; foreach (byte b in array) { PlayerControl playerById = Utils.GetPlayerById(b); if ((Object)(object)playerById == (Object)null) { return; } if (playerById.Is(CustomRoles.Susceptible)) { Susceptible.CallEnabledAndChange(playerById); deathReason = Susceptible.randomReason; } if (Main.AfterMeetingDeathPlayers.TryAdd(b, deathReason)) { list.Add(b); } } PlayerState.DeathReason deathReason2 = deathReason; int i = 0; array = new byte[list.Count]; foreach (byte item in list) { array[i] = item; i++; } CheckForDeathOnExile(deathReason2, array); } private static void CheckForDeathOnExile(PlayerState.DeathReason deathReason, params byte[] playerIds) { Witch.OnCheckForEndVoting(deathReason, playerIds); HexMaster.OnCheckForEndVoting(deathReason, playerIds); Virus.OnCheckForEndVoting(deathReason, playerIds); foreach (byte playerId in playerIds) { if (CustomRoles.Lovers.IsEnable() && !Main.isLoversDead && Main.LoversPlayers.Any((PlayerControl lp) => lp.PlayerId == playerId)) { FixedUpdateInNormalGamePatch.LoversSuicide(playerId, isExiled: true); } RevengeOnExile(playerId); } } private static void RevengeOnExile(byte playerId) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null)) { PlayerControl val = PickRevengeTarget(playerById); if (!((Object)(object)val == (Object)null)) { TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Revenge, val.PlayerId); val.SetRealKiller(playerById); Logger.Info(playerById.GetNameWithRole() + " revenge:" + val.GetNameWithRole(), "RevengeOnExile", escapeCRLF: true, 617, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } } } private static PlayerControl PickRevengeTarget(PlayerControl exiledplayer) { List list = new List(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!((Object)(object)val == (Object)(object)exiledplayer)) { Main.AfterMeetingDeathPlayers.ContainsKey(val.PlayerId); } } if (list == null || list.Count == 0) { return null; } _ = IRandom.Instance; return list.RandomElement(); } } [HarmonyPatch(typeof(MeetingHud), "CastVote")] internal class CastVotePatch { public static bool Prefix(MeetingHud __instance, [HarmonyArgument(0)] byte srcPlayerId, [HarmonyArgument(1)] byte suspectPlayerId) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } PlayerControl playerById = Utils.GetPlayerById(srcPlayerId); if ((Object)(object)playerById == (Object)null || !playerById.IsAlive()) { return false; } PlayerControl playerById2 = Utils.GetPlayerById(suspectPlayerId); if ((Object)(object)playerById2 == (Object)null && suspectPlayerId < 253) { Utils.SendMessage(Translator.GetString("VoteDead"), srcPlayerId); __instance.RpcClearVote(playerById.GetClientId()); return false; } if ((Object)(object)playerById2 != (Object)null && suspectPlayerId < 253) { if (!playerById2.IsAlive() || playerById2.Data.Disconnected) { Utils.SendMessage(Translator.GetString("VoteDead"), srcPlayerId); __instance.RpcClearVote(playerById.GetClientId()); Swapper.CheckSwapperTarget(suspectPlayerId); return false; } switch (playerById.GetCustomRole()) { case CustomRoles.Dictator: if (playerById2.Is(CustomRoles.Solsticer)) { Utils.SendMessage(Translator.GetString("VoteSolsticer"), srcPlayerId); __instance.RpcClearVote(playerById.GetClientId()); return false; } if (!playerById2.IsAlive()) { Utils.SendMessage(Translator.GetString("VoteDead"), srcPlayerId); __instance.RpcClearVote(playerById.GetClientId()); return false; } break; case CustomRoles.Keeper: if (!Keeper.OnVotes(playerById, playerById2)) { __instance.RpcClearVote(playerById.GetClientId()); return false; } break; } } return true; } public static void Postfix(MeetingHud __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 bool flag = GameStates.IsMeeting; if (flag) { VoteStates state = MeetingHud.Instance.state; bool flag2 = state - 1 <= 2; flag = flag2; } if (flag) { __instance.CheckForEndVoting(); } } } internal static class ExtendedMeetingHud { public static Dictionary CustomCalculateVotes(this MeetingHud __instance, bool CountInfluenced = false) { Logger.Info("===Start of vote counting processing===", "Vote", escapeCRLF: true, 703, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); Dictionary dictionary = new Dictionary(); Collector.Clear(); Tiebreaker.Clear(); foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)__instance.playerStates) { if ((Object)(object)item == (Object)null) { continue; } byte votedFor = item.VotedFor; if (votedFor == 252 || votedFor == byte.MaxValue || votedFor == 254) { continue; } int VoteNum = 1; PlayerControl playerById = Utils.GetPlayerById(item.VotedFor); if ((Object)(object)playerById != (Object)null) { Zombie.CheckRealVotes(playerById, ref VoteNum); if (playerById.Is(CustomRoles.Solsticer)) { VoteNum = 0; } Tiebreaker.CheckVote(playerById, item); Collector.CollectorVotes(playerById, item); } PlayerControl playerById2 = Utils.GetPlayerById(item.TargetPlayerId); if (CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, playerById2.GetCustomRole()) && item.TargetPlayerId != item.VotedFor && (Object)(object)item != (Object)null) { VoteNum += item.TargetPlayerId.GetRoleClassById().AddRealVotesNum(item); } if (CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, CustomRoles.Knighted) && item.TargetPlayerId != item.VotedFor) { VoteNum++; } if (Paranoia.DualVotes.GetBool() && CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, CustomRoles.Paranoia) && item.TargetPlayerId != item.VotedFor) { VoteNum += VoteNum; } if (CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, CustomRoles.TicketsStealer)) { VoteNum += Stealer.AddRealVotesNum(item); } if (item.TargetPlayerId == item.VotedFor && Madmate.MadmateSpawnMode.GetInt() == 2) { VoteNum = 0; } if (CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, CustomRoles.VoidBallot)) { VoteNum = 0; } if (Jailer.IsTarget(item.VotedFor) || Jailer.IsTarget(item.TargetPlayerId)) { VoteNum = 0; } if (!CountInfluenced && CheckForEndVotingPatch.CheckRole(item.TargetPlayerId, CustomRoles.Influenced)) { VoteNum = 0; } dictionary[item.VotedFor] = ((!dictionary.TryGetValue(item.VotedFor, out var value)) ? VoteNum : (value + VoteNum)); } return dictionary; } } [HarmonyPatch(typeof(MeetingHud), "Start")] internal class MeetingHudStartPatch { public static List<(string, byte, string)> msgToSend = new List<(string, byte, string)>(); public static void AddMsg(string text, byte sendTo = byte.MaxValue, string title = "") { msgToSend.Add((text, sendTo, title)); } public static void NotifyRoleSkillOnMeetingStart() { //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Invalid comparison between Unknown and I4 //IL_062a: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } Main.MeetingIsStarted = true; msgToSend = new List<(string, byte, string)>(); PlayerControl[] array; if (Options.SendRoleDescriptionFirstMeeting.GetBool() && MeetingStates.FirstMeeting) { array = Main.AllAlivePlayerControls.Where((PlayerControl x) => !x.IsModClient()).ToArray(); foreach (PlayerControl val in array) { CustomRoles customRole = val.GetCustomRole(); string roleInfo = val.GetRoleInfo(InfoLong: true); string title = "" + customRole.GetRoleTitle() + "\n"; StringBuilder sb = new StringBuilder(); StringBuilder stringBuilder = new StringBuilder(); string roleColorCode = Utils.GetRoleColorCode(customRole); string title2 = "" + Translator.GetString("YourAddon") + "\n"; if (Options.CustomRoleSpawnChances.TryGetValue(customRole, out var _)) { Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[customRole], ref sb); } string text = sb.ToString(); string text2 = $"{Translator.GetString(customRole.ToString())} {Translator.GetString("Settings:")}\n"; sb.Clear().Append("" + text2 + text + ""); CustomRoles[] array2 = Main.PlayerStates[val.PlayerId].SubRoles.ToArray(); foreach (CustomRoles role in array2) { stringBuilder.Append("\n\n" + role.GetRoleTitle() + role.GetInfoLong() + ""); } if (stringBuilder.ToString() != string.Empty) { string text3 = stringBuilder.ToString().Remove(0, 2); text3 = ((text3.Length > 1200) ? ("" + text3.RemoveHtmlTags() + "") : text3); stringBuilder.Clear().Append(text3); } AddMsg(roleInfo, val.PlayerId, title); AddMsg("", val.PlayerId, sb.ToString()); if (stringBuilder.ToString() != string.Empty) { AddMsg(stringBuilder.ToString(), val.PlayerId, title2); } } } if (msgToSend.Count >= 1) { List<(string, byte, string)> msgTemp = msgToSend.ToList(); new LateTask(delegate { CollectionExtensions.Do<(string, byte, string)>((IEnumerable<(string, byte, string)>)msgTemp, (Action<(string, byte, string)>)delegate((string, byte, string) x) { Utils.SendMessage(x.Item1, x.Item2, x.Item3); }); }, 3f, "Skill Description First Meeting"); } msgToSend = new List<(string, byte, string)>(); if (Madmate.MadmateSpawnMode.GetInt() == 2 && CustomRoles.Madmate.GetCount() > 0) { AddMsg(string.Format(Translator.GetString("Message.MadmateSelfVoteModeNotify"), Translator.GetString("MadmateSpawnMode.SelfVote"))); } if (MeetingStates.FirstMeeting && CustomRoles.Bait.RoleExist() && Bait.BaitNotification.GetBool()) { array = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Bait)).ToArray(); foreach (PlayerControl val2 in array) { Bait.BaitAlive.Add(val2.PlayerId); } List list = new List(); byte[] array3 = Bait.BaitAlive.ToArray(); for (int i = 0; i < array3.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array3[i]); if (!((Object)(object)playerById == (Object)null)) { list.Add(playerById.GetRealName()); } } SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; bool flag = (((int)languageID == 0 || (int)languageID == 5) ? true : false); string separator = (flag ? "], [" : "】, 【"); AddMsg(string.Format(Translator.GetString("BaitAdviceAlive"), string.Join(separator, list)), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Bait)), Translator.GetString("BaitAliveTitle"))); } string MimicMsg = ""; array = Main.AllPlayerControls; foreach (PlayerControl pc in array) { pc?.GetRoleClass()?.OnMeetingHudStart(pc); CollectionExtensions.Do>((IEnumerable>)Main.PlayerStates, (Action>)delegate(KeyValuePair plr) { plr.Value.RoleClass.OnOthersMeetingHudStart(pc); }); foreach (byte item in Cyber.CyberDead) { if ((Cyber.ImpKnowCyberDead.GetBool() || !pc.GetCustomRole().IsImpostor()) && (Cyber.NeutralKnowCyberDead.GetBool() || !pc.GetCustomRole().IsNeutral()) && (Cyber.CrewKnowCyberDead.GetBool() || !pc.GetCustomRole().IsCrewmate())) { AddMsg(string.Format(Translator.GetString("CyberDead"), Main.AllPlayerNames[item]), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cyber)), Translator.GetString("CyberNewsTitle"))); } } if (Sleuth.SleuthNotify.ContainsKey(pc.PlayerId)) { AddMsg(Sleuth.SleuthNotify[pc.PlayerId], pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Sleuth)), Translator.GetString("SleuthNoticeTitle"))); } if (pc.Is(CustomRoles.Mimic) && !pc.IsAlive()) { CollectionExtensions.Do(Main.AllAlivePlayerControls.Where(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == pc.PlayerId; }), (Action)delegate(PlayerControl x) { MimicMsg = MimicMsg + "\n" + x.GetNameWithRole(forUser: true); }); } } if (MimicMsg != "") { MimicMsg = Translator.GetString("MimicDeadMsg") + "\n" + MimicMsg; array = Main.AllPlayerControls.Where((PlayerControl x) => x.GetCustomRole().IsImpostorTeam()).ToArray(); foreach (PlayerControl val3 in array) { AddMsg(MimicMsg, val3.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Mimic)), Translator.GetString("MimicMsgTitle"))); } } CollectionExtensions.Do<(string, byte, string)>((IEnumerable<(string, byte, string)>)msgToSend, (Action<(string, byte, string)>)delegate((string, byte, string) x) { Logger.Info($"To:{x.Item2} {x.Item3} => {x.Item1}", "Skill Notice OnMeeting Start", escapeCRLF: true, 900, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); }); new LateTask(delegate { CollectionExtensions.Do<(string, byte, string)>((IEnumerable<(string, byte, string)>)msgToSend, (Action<(string, byte, string)>)delegate((string, byte, string) x) { Utils.SendMessage(x.Item1, x.Item2, x.Item3); }); }, 3f, "Skill Notice On Meeting Start"); CollectionExtensions.Do>((IEnumerable>)Main.PlayerStates, (Action>)delegate(KeyValuePair x) { x.Value.RoleClass.MeetingHudClear(); }); Cyber.Clear(); Sleuth.Clear(); } public static void Prefix() { Logger.Info("------------Opening of the session------------", "Phase", escapeCRLF: true, 916, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); ChatUpdatePatch.DoBlockChat = true; GameStates.AlreadyDied |= !Utils.IsAllAlive; CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl x) { ReportDeadBodyPatch.WaitReport[x.PlayerId].Clear(); }); MeetingStates.MeetingCalled = true; } public static void Postfix(MeetingHud __instance) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_06d7: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e7: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Unknown result type (might be due to invalid IL or missing references) //IL_0569: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_0779: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_0924: Unknown result type (might be due to invalid IL or missing references) //IL_0938: Unknown result type (might be due to invalid IL or missing references) //IL_093d: Unknown result type (might be due to invalid IL or missing references) //IL_0805: Unknown result type (might be due to invalid IL or missing references) //IL_080a: Unknown result type (might be due to invalid IL or missing references) //IL_08ce: Unknown result type (might be due to invalid IL or missing references) //IL_08d3: Unknown result type (might be due to invalid IL or missing references) //IL_089f: Unknown result type (might be due to invalid IL or missing references) //IL_08a4: Unknown result type (might be due to invalid IL or missing references) SoundManager.Instance.ChangeAmbienceVolume(0f); if (!GameStates.IsModHost) { return; } GuessManager.textTemplate = Object.Instantiate(((Il2CppArrayBase)(object)__instance.playerStates)[0].NameText); ((Behaviour)GuessManager.textTemplate).enabled = false; foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)__instance.playerStates) { PlayerControl playerById = Utils.GetPlayerById(item.TargetPlayerId); if (!((Object)(object)playerById == (Object)null)) { (string, Color) roleAndSubText = Utils.GetRoleAndSubText(PlayerControl.LocalPlayer.PlayerId, playerById.PlayerId); TextMeshPro val = Object.Instantiate(item.NameText); val.transform.SetParent(item.NameText.transform); val.transform.localPosition = new Vector3(0f, -0.18f, 0f); ((TMP_Text)val).fontSize = 1.6f; ((TMP_Text)val).text = roleAndSubText.Item1; if (Main.VisibleTasksCount) { ((TMP_Text)val).text = ((TMP_Text)val).text + Utils.GetProgressText(playerById); } ((Graphic)val).color = roleAndSubText.Item2; ((Object)((Component)val).gameObject).name = "RoleTextMeeting"; ((TMP_Text)val).enableWordWrapping = false; ((Behaviour)val).enabled = ((InnerNetObject)playerById).AmOwner || ExtendedPlayerControl.KnowRoleTarget(PlayerControl.LocalPlayer, playerById); RoleBase roleClass = PlayerControl.LocalPlayer.GetRoleClass(); bool enabled = true; if (!PlayerControl.LocalPlayer.Data.IsDead && Overseer.IsRevealedPlayer(PlayerControl.LocalPlayer, playerById) && playerById.Is(CustomRoles.Trickster)) { ((TMP_Text)val).text = Overseer.GetRandomRole(PlayerControl.LocalPlayer.PlayerId); ((TMP_Text)val).text = ((TMP_Text)val).text + TaskState.GetTaskState(); } StringBuilder stringBuilder = new StringBuilder(32); if (roleClass != null) { stringBuilder.Append(roleClass.GetSuffix(PlayerControl.LocalPlayer, playerById, isForMeeting: true)); } stringBuilder.Append(CustomRoleManager.GetSuffixOthers(PlayerControl.LocalPlayer, playerById, isForMeeting: true)); _ = PlayerControl.LocalPlayer; Utils.GetPlayerById(item.TargetPlayerId); if (stringBuilder.Length > 0) { ((TMP_Text)val).text = stringBuilder.ToString(); ((Behaviour)val).enabled = enabled; } } } if (Options.SyncButtonMode.GetBool()) { Utils.SendMessage(string.Format(Translator.GetString("Message.SyncButtonLeft"), Options.SyncedButtonCount.GetFloat() - (float)Options.UsedButtonCount)); Logger.Info("紧急会议剩余 " + (Options.SyncedButtonCount.GetFloat() - (float)Options.UsedButtonCount) + " 次使用次数", "SyncButtonMode", escapeCRLF: true, 978, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); } if (AntiBlackout.BlackOutIsActive) { new LateTask(delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(Translator.GetString("Warning.AntiBlackoutProtectionMsg"), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Color.blue), Translator.GetString("AntiBlackoutProtectionTitle")), logforChatManager: false, noReplay: true); }, 5f, "Warning BlackOut Is Active"); } if (AntiBlackout.ShowExiledInfo) { AntiBlackout.ShowExiledInfo = false; if (AntiBlackout.StoreExiledMessage != "") { AntiBlackout.StoreExiledMessage = Translator.GetString("Warning.ShowAntiBlackExiledPlayer") + AntiBlackout.StoreExiledMessage; new LateTask(delegate { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(AntiBlackout.StoreExiledMessage, byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Color.red), Translator.GetString("DefaultSystemMessageTitle")), logforChatManager: false, noReplay: true); AntiBlackout.StoreExiledMessage = ""; }, 5.5f, "AntiBlackout.StoreExiledMessage"); } } if (MeetingStates.FirstMeeting) { TemplateManager.SendTemplate("OnFirstMeeting", byte.MaxValue, noErr: true); } TemplateManager.SendTemplate("OnMeeting", byte.MaxValue, noErr: true); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { NotifyRoleSkillOnMeetingStart(); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { new LateTask(delegate { PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl player in allPlayerControls) { player.RpcSetNameEx(player.GetRealName(isMeeting: true)); } ChatUpdatePatch.DoBlockChat = false; }, 3f, "SetName To Chat"); } foreach (PlayerVoteArea item2 in (Il2CppArrayBase)(object)__instance.playerStates) { if ((Object)(object)item2 == (Object)null) { continue; } PlayerControl localPlayer = PlayerControl.LocalPlayer; RoleBase roleClass2 = localPlayer.GetRoleClass(); PlayerControl playerById2 = Utils.GetPlayerById(item2.TargetPlayerId); if ((Object)(object)playerById2 == (Object)null) { continue; } StringBuilder stringBuilder2 = new StringBuilder(); ((TMP_Text)item2.NameText).text = ((TMP_Text)item2.NameText).text.ApplyNameColorData(localPlayer, playerById2, isMeeting: true); if (Options.GuesserMode.GetBool()) { if (Options.CrewmatesCanGuess.GetBool() && localPlayer.GetCustomRole().IsCrewmate() && !localPlayer.Is(CustomRoles.Judge) && !localPlayer.Is(CustomRoles.Lookout) && !localPlayer.Is(CustomRoles.Swapper) && !localPlayer.Is(CustomRoles.Inspector) && !localPlayer.Data.IsDead && !playerById2.Data.IsDead) { ((TMP_Text)item2.NameText).text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(localPlayer.GetCustomRole())), playerById2.PlayerId.ToString()) + " " + ((TMP_Text)item2.NameText).text; } if (Options.ImpostorsCanGuess.GetBool() && (localPlayer.GetCustomRole().IsImpostor() || localPlayer.GetCustomRole().IsMadmate()) && !localPlayer.Is(CustomRoles.Councillor) && !localPlayer.Data.IsDead && !playerById2.Data.IsDead) { ((TMP_Text)item2.NameText).text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(localPlayer.GetCustomRole())), playerById2.PlayerId.ToString()) + " " + ((TMP_Text)item2.NameText).text; } if (Options.NeutralKillersCanGuess.GetBool() && localPlayer.GetCustomRole().IsNK() && !localPlayer.Data.IsDead && !playerById2.Data.IsDead) { ((TMP_Text)item2.NameText).text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(localPlayer.GetCustomRole())), playerById2.PlayerId.ToString()) + " " + ((TMP_Text)item2.NameText).text; } if (Options.PassiveNeutralsCanGuess.GetBool() && localPlayer.GetCustomRole().IsNonNK() && !localPlayer.Is(CustomRoles.Doomsayer) && !localPlayer.Data.IsDead && !playerById2.Data.IsDead) { ((TMP_Text)item2.NameText).text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(localPlayer.GetCustomRole())), playerById2.PlayerId.ToString()) + " " + ((TMP_Text)item2.NameText).text; } } if (localPlayer.KnowDeathReason(playerById2)) { StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder3); handler.AppendLiteral(" ("); handler.AppendFormatted(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doctor)), Utils.GetVitalText(playerById2.PlayerId))); handler.AppendLiteral(")"); stringBuilder3.Append(ref handler); } stringBuilder2.Append(roleClass2?.GetMark(localPlayer, playerById2, isForMeeting: true)); stringBuilder2.Append(CustomRoleManager.GetMarkOthers(localPlayer, playerById2, isForMeeting: true)); if (localPlayer.GetCustomRole().IsImpostor() && playerById2.GetPlayerTaskState().IsTaskFinished && playerById2.Is(CustomRoles.Snitch) && playerById2.Is(CustomRoles.Madmate)) { stringBuilder2.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), "★")); } string text = localPlayer.GetRoleClass().PVANameText(item2, localPlayer, playerById2); if (text != string.Empty) { ((TMP_Text)item2.NameText).text = text; } CustomRoles[] array = localPlayer.GetCustomSubRoles().ToArray(); for (int i = 0; i < array.Length; i++) { if (array[i] == CustomRoles.Guesser && !localPlayer.Data.IsDead && !playerById2.Data.IsDead) { ((TMP_Text)item2.NameText).text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Guesser)), playerById2.PlayerId.ToString()) + " " + ((TMP_Text)item2.NameText).text; } } array = playerById2.GetCustomSubRoles().ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.Lovers: if (localPlayer.Is(CustomRoles.Lovers) || localPlayer.Data.IsDead) { stringBuilder2.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lovers)), "♥")); } break; case CustomRoles.Cyber: if (Cyber.CyberKnown.GetBool()) { stringBuilder2.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cyber)), "★")); } break; } } TextMeshPro nameText = item2.NameText; ((TMP_Text)nameText).text = ((TMP_Text)nameText).text + stringBuilder2.ToString(); Transform transform = item2.ColorBlindName.transform; transform.localPosition -= new Vector3(1.35f, 0f, 0f); } } } [HarmonyPatch(typeof(MeetingHud), "Update")] internal class MeetingHudUpdatePatch { private static int bufferTime = 10; private static void ClearShootButton(MeetingHud __instance, bool forceAll = false) { ((IEnumerable)__instance.playerStates).ToList().ForEach(delegate(PlayerVoteArea x) { if ((forceAll || !Main.PlayerStates.TryGetValue(x.TargetPlayerId, out var value) || value.IsDead) && (Object)(object)((Component)x).transform.FindChild("ShootButton") != (Object)null) { Object.Destroy((Object)(object)((Component)((Component)x).transform.FindChild("ShootButton")).gameObject); } }); } public static void Postfix(MeetingHud __instance) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && Input.GetKeyDown((KeyCode)287)) { __instance.CheckForEndVoting(); } if (((InnerNetClient)AmongUsClient.Instance).AmHost && Input.GetMouseButtonUp(1) && Input.GetKey((KeyCode)306)) { CollectionExtensions.DoIf((IEnumerable)__instance.playerStates, (Func)((PlayerVoteArea x) => ((Renderer)x.HighlightedFX).enabled), (Action)delegate(PlayerVoteArea x) { PlayerControl playerById = Utils.GetPlayerById(x.TargetPlayerId); if ((Object)(object)playerById != (Object)null && !playerById.Data.IsDead) { playerById.SetDeathReason(PlayerState.DeathReason.Execution); playerById.SetRealKiller(PlayerControl.LocalPlayer); playerById.RpcExileV2(); Main.PlayerStates[playerById.PlayerId].SetDead(); MurderPlayerPatch.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, playerById, GameStates.IsMeeting); Utils.SendMessage(string.Format(Translator.GetString("Message.Executed"), playerById.Data.PlayerName)); Logger.Info(playerById.GetNameWithRole() + " was executed", "Execution", escapeCRLF: true, 1146, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); __instance.CheckForEndVoting(); } }); } if (!GameStates.IsVoting && __instance.lastSecond < 1) { if ((Object)(object)GameObject.Find("ShootButton") != (Object)null) { ClearShootButton(__instance, forceAll: true); } return; } bufferTime--; if (bufferTime < 0 && __instance.discussionTimer > 0f) { bufferTime = 10; CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); CollectionExtensions.Do(((IEnumerable)__instance.playerStates).Where((PlayerVoteArea x) => (!Main.PlayerStates.TryGetValue(x.TargetPlayerId, out var value) || value.IsDead) && !x.AmDead), (Action)delegate(PlayerVoteArea x) { x.SetDead(x.DidReport, true, false); }); bool flag; switch (customRole) { case CustomRoles.Councillor: case CustomRoles.EvilGuesser: case CustomRoles.Judge: case CustomRoles.NiceGuesser: case CustomRoles.Swapper: case CustomRoles.Doomsayer: case CustomRoles.Guesser: flag = true; break; default: flag = false; break; } if (flag && !PlayerControl.LocalPlayer.IsAlive()) { ClearShootButton(__instance, forceAll: true); } if (customRole == CustomRoles.Nemesis && !PlayerControl.LocalPlayer.IsAlive() && (Object)(object)GameObject.Find("ShootButton") == (Object)null) { Nemesis.CreateJudgeButton(__instance); } if (customRole == CustomRoles.Retributionist && !PlayerControl.LocalPlayer.IsAlive() && (Object)(object)GameObject.Find("ShootButton") == (Object)null) { Retributionist.CreateJudgeButton(__instance); } ClearShootButton(__instance); } } } [HarmonyPatch(typeof(PlayerVoteArea), "SetHighlighted")] internal class SetHighlightedPatch { public static bool Prefix(PlayerVoteArea __instance, bool value) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (!Object.op_Implicit((Object)(object)__instance.HighlightedFX)) { return false; } ((Renderer)__instance.HighlightedFX).enabled = value; return false; } } [HarmonyPatch(typeof(MeetingHud), "OnDestroy")] internal class MeetingHudOnDestroyPatch { public static void Postfix() { MeetingStates.FirstMeeting = false; Logger.Info("------------End Meeting------------", "Phase", escapeCRLF: true, 1202, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\MeetingHudPatch.cs"); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { AntiBlackout.SetIsDead(doSend: true, "Postfix"); Main.LastVotedPlayerInfo = null; EAC.ReportTimes = new Dictionary(); } } } [HarmonyPatch(typeof(MovingPlatformBehaviour))] public static class MovingPlatformBehaviourPatch { private static bool isDisabled; [HarmonyPatch("Start")] [HarmonyPrefix] public static void Start_Prefix(MovingPlatformBehaviour __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) isDisabled = Options.DisableAirshipMovingPlatform.GetBool(); if (isDisabled) { ((Component)__instance).transform.localPosition = __instance.DisabledPosition; ((Il2CppObjectBase)ShipStatus.Instance).Cast().outOfOrderPlat.SetActive(true); } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] public static bool GetIsDirty_Prefix(ref bool __result) { if (isDisabled) { __result = false; return false; } return true; } [HarmonyPatch("Use", new Type[] { typeof(PlayerControl) })] [HarmonyPrefix] public static bool Use_Prefix() { return !isDisabled; } [HarmonyPatch("SetSide")] [HarmonyPrefix] public static bool SetSide_Prefix() { return !isDisabled; } } [HarmonyPatch(typeof(LogicGameFlowNormal), "IsGameOverDueToDeath")] internal class DontBlackoutPatch { public static void Postfix(ref bool __result) { __result = false; } } [HarmonyPatch(typeof(OneWayShadows), "IsIgnored")] public static class OneWayShadowsIsIgnoredPatch { public static bool Prefix(OneWayShadows __instance, ref bool __result) { bool flag = Main.ResetCamPlayerList.Contains(PlayerControl.LocalPlayer.PlayerId); if (__instance.IgnoreImpostor && flag) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(AmongUsClient), "CoStartGame")] internal class ChangeRoleSettings { public static void Postfix(AmongUsClient __instance) { //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Expected O, but got Unknown //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Expected O, but got Unknown if (((InnerNetClient)AmongUsClient.Instance).AmHost) { SetUpRoleTextPatch.IsInIntro = true; } Main.OverrideWelcomeMsg = ""; Logger.Msg("Is Started", "Initialization", escapeCRLF: true, 25, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); try { if (GameStates.IsNormalGame) { Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)4, 0, 0); if (Options.DisableVanillaRoles.GetBool()) { Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)2, 0, 0); Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)3, 0, 0); Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)5, 0, 0); Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)8, 0, 0); Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)9, 0, 0); Main.NormalOptions.roleOptions.SetRoleRate((RoleTypes)10, 0, 0); } } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.NumImpostors = Options.NumImpostorsHnS.GetInt(); Main.AliveImpostorCount = Main.HideNSeekOptions.NumImpostors; } Main.PlayerStates = new Dictionary(); KillTimerManager.Initializate(); Main.AllPlayerKillCooldown.Clear(); Main.AllPlayerSpeed.Clear(); Main.AllPlayerCustomRoles.Clear(); Main.TasklessCrewmate.Clear(); Main.UnreportableBodies.Clear(); Main.LastEnteredVent.Clear(); Main.LastEnteredVentLocation.Clear(); Main.PlayersDiedInMeeting.Clear(); GuessManager.GuesserGuessed.Clear(); Main.AfterMeetingDeathPlayers.Clear(); Main.ResetCamPlayerList.Clear(); Main.clientIdList.Clear(); PlayerControlSetRolePatch.DidSetGhost.Clear(); Main.CheckShapeshift.Clear(); Main.ShapeshiftTarget.Clear(); Main.AllKillers.Clear(); Main.OverDeadPlayerList.Clear(); Utils.LateExileTask.Clear(); Main.LastNotifyNames.Clear(); Main.PlayerColors.Clear(); Main.ShieldPlayer = (Options.ShieldPersonDiedFirst.GetBool() ? Main.FirstDied : ""); Main.FirstDied = ""; Main.MadmateNum = 0; Main.BardCreations = 0; Main.MeetingsPassed = 0; Main.MeetingIsStarted = false; Main.introDestroyed = false; GameEndCheckerForNormal.ShouldNotCheck = false; GameEndCheckerForNormal.ForEndGame = false; GameEndCheckerForNormal.ShowAllRolesWhenGameEnd = false; GameStartManagerPatch.GameStartManagerUpdatePatch.AlredyBegin = false; ChatManager.ResetHistory(); ReportDeadBodyPatch.CanReport = new Dictionary(); Options.UsedButtonCount = 0; Main.RealOptionsData = new OptionBackupData(GameOptionsManager.Instance.CurrentGameOptions); if (GameStates.IsNormalGame) { GameOptionsManager.Instance.currentNormalGameOptions.ConfirmImpostor = false; GameOptionsManager.Instance.currentNormalGameOptions.SetBool((BoolOptionNames)3, false); MeetingTimeManager.Init(); Main.DefaultCrewmateVision = Main.RealOptionsData.GetFloat((FloatOptionNames)4); Main.DefaultImpostorVision = Main.RealOptionsData.GetFloat((FloatOptionNames)3); } ExileControllerWrapUpPatch.AntiBlackout_LastExiled = null; IRandom.SetInstanceById(Options.RoleAssigningAlgorithm.GetValue()); Main.DoBlockNameChange = true; RPC.SyncAllPlayerNames(); GhostRoleAssign.Init(); Camouflage.Init(); IEnumerable source = Main.AllPlayerControls.Where((PlayerControl p) => p.Data.DefaultOutfit.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= p.Data.DefaultOutfit.ColorId); if (source.Any()) { string @string = Translator.GetString("Error.InvalidColor"); Logger.SendInGame(@string); string text = @string + " " + string.Join(", ", source.Select((PlayerControl p) => p.Data.PlayerName ?? "")); Utils.SendMessage(text); Logger.Error(text, "CoStartGame", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { PlayerControl[] allPlayerControls2 = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls2) { (byte, byte) key = (val.PlayerId, val2.PlayerId); Main.LastNotifyNames[key] = ((Object)val).name; } } allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val3 in allPlayerControls) { PlayerOutfit defaultOutfit = val3.Data.DefaultOutfit; int colorId = val3.Data.DefaultOutfit.ColorId; string playerName = ""; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (Options.FormatNameMode.GetInt() == 1) { string colorName = Palette.GetColorName(colorId); playerName = colorName; val3.RpcSetName(colorName); } else { string value; string text2 = (Main.AllPlayerNames.TryGetValue(val3.PlayerId, out value) ? value : ""); if (text2 == "") { continue; } playerName = text2; val3.RpcSetName(text2); } } Main.PlayerStates[val3.PlayerId] = new PlayerState(val3.PlayerId) { NormalOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), playerName, val3.CurrentOutfit.ColorId, val3.CurrentOutfit.HatId, val3.CurrentOutfit.SkinId, val3.CurrentOutfit.VisorId, val3.CurrentOutfit.PetId, val3.CurrentOutfit.NamePlateId) }; Main.PlayerColors[val3.PlayerId] = ((Il2CppArrayBase)(object)Palette.PlayerColors)[colorId]; if (GameStates.IsNormalGame) { Main.AllPlayerSpeed[val3.PlayerId] = Main.RealOptionsData.GetFloat((FloatOptionNames)2); } ReportDeadBodyPatch.CanReport[val3.PlayerId] = true; ReportDeadBodyPatch.WaitReport[val3.PlayerId] = new List(); ((TMP_Text)val3.cosmetics.nameText).text = ((Object)val3).name; Camouflage.PlayerSkins[val3.PlayerId] = PlayerOutfitExtension.Set(new PlayerOutfit(), playerName, defaultOutfit.ColorId, defaultOutfit.HatId, defaultOutfit.SkinId, defaultOutfit.VisorId, defaultOutfit.PetId, defaultOutfit.NamePlateId); Main.clientIdList.Add(val3.GetClientId()); } Main.VisibleTasksCount = true; if (((InnerNetClient)__instance).AmHost) { RPC.SyncCustomSettingsRPC(); Main.RefixCooldownDelay = 0f; } CustomRoles[] array = (from role in EnumHelper.GetAllValues() where role < CustomRoles.NotAssigned select role).ToArray(); for (int i = 0; i < array.Length; i++) { array[i].GetStaticRoleClass()?.OnInit(); } LastImpostor.Init(); TargetArrow.Init(); LocateArrow.Init(); DoubleTrigger.Init(); Workhorse.Init(); Diseased.Init(); Clumsy.Init(); Aware.Init(); Radar.Init(); Glow.Init(); Sleuth.Init(); Bait.Init(); Antidote.Init(); Fool.Init(); Burst.Init(); DoubleShot.Init(); Lucky.Init(); Bewilder.Init(); Cyber.Init(); Oiiai.Init(); Tired.Init(); Statue.Init(); Ghoul.Init(); Rainbow.Init(); FFAManager.Init(); FallFromLadder.Reset(); CustomRoleManager.Initialize(); CustomWinnerHolder.Reset(); AntiBlackout.Reset(); NameNotifyManager.Reset(); SabotageSystemPatch.SabotageSystemTypeRepairDamagePatch.Initialize(); DoorsReset.Initialize(); MeetingStates.MeetingCalled = false; MeetingStates.FirstMeeting = true; GameStates.AlreadyDied = false; EAC.ReportTimes = new Dictionary(); SetEverythingUpPatch.LastWinsText = ""; SetEverythingUpPatch.LastWinsReason = ""; Logger.Msg("End", "Initialization", escapeCRLF: true, 242, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } catch (Exception ex) { Utils.ErrorEnd("Change Role Setting Postfix"); Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs", 247, "Postfix"); } } } [HarmonyPatch(typeof(RoleManager), "SelectRoles")] internal class SelectRolesPatch { [HarmonyPatch(typeof(PlayerControl), "RpcSetRole")] public static class RpcSetRoleReplacer { public static bool doReplace = false; public static Dictionary senders; public static Dictionary StoragedData = new Dictionary(); public static List OverriddenSenderList; public static bool Prefix() { return !doReplace; } public static void Release() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected I4, but got Unknown foreach (KeyValuePair sender in senders) { if (OverriddenSenderList.Contains(sender.Value)) { continue; } if (sender.Value.CurrentState != CustomRpcSender.State.InRootMessage) { throw new InvalidOperationException("A CustomRpcSender had Invalid State."); } foreach (var (val3, val4) in StoragedData) { try { val3.SetRole(val4); sender.Value.AutoStartRpc(((InnerNetObject)val3).NetId, 44, Utils.GetPlayerById(sender.Key).GetClientId()).Write((ushort)(int)val4).Write(val: false) .EndRpc(); } catch { } } sender.Value.EndMessage(); } doReplace = false; } public static void Initialize() { StoragedData = new Dictionary(); OverriddenSenderList = new List(); doReplace = true; } public static void StartReplace(Dictionary senders) { RpcSetRoleReplacer.senders = senders; doReplace = true; } } private static Dictionary RoleTypeNums = new Dictionary(); private static RoleOptionsCollectionV08 RoleOpt => Main.NormalOptions.roleOptions; public static void UpdateRoleTypeNums() { RoleTypeNums = new Dictionary { { (RoleTypes)2, RoleAssign.AddScientistNum }, { (RoleTypes)3, RoleAssign.AddEngineerNum }, { (RoleTypes)5, RoleAssign.AddShapeshifterNum }, { (RoleTypes)8, RoleAssign.AddNoisemakerNum }, { (RoleTypes)9, RoleAssign.AddPhantomNum }, { (RoleTypes)10, RoleAssign.AddTrackerNum } }; } public static void Prefix() { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if (GameStates.IsHideNSeek) { if (Main.EnableGM.Value) { PlayerControl.LocalPlayer.RpcSetCustomRole(CustomRoles.GM); PlayerControl.LocalPlayer.RpcSetRole((RoleTypes)0, false); PlayerControl.LocalPlayer.Data.IsDead = true; Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); } EAC.OriginalRoles = new Dictionary(); return; } try { RpcSetRoleReplacer.Initialize(); if (Main.EnableGM.Value && Options.CurrentGameMode == CustomGameMode.Standard) { PlayerControl.LocalPlayer.RpcSetCustomRole(CustomRoles.GM); PlayerControl.LocalPlayer.RpcSetRole((RoleTypes)0, false); PlayerControl.LocalPlayer.Data.IsDead = true; Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); } EAC.OriginalRoles = new Dictionary(); RoleAssign.StartSelect(); AddonAssign.StartSelect(); RoleAssign.CalculateVanillaRoleCount(); UpdateRoleTypeNums(); foreach (KeyValuePair roleTypeNum in RoleTypeNums) { int num = ((!Options.DisableVanillaRoles.GetBool()) ? RoleOpt.GetNumPerGame(roleTypeNum.Key) : 0); num += roleTypeNum.Value; RoleOpt.SetRoleRate(roleTypeNum.Key, num, (roleTypeNum.Value > 0) ? 100 : RoleOpt.GetChancePerGame(roleTypeNum.Key)); } } catch (Exception ex) { Utils.ErrorEnd("Select Role Prefix"); Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs", 320, "Prefix"); } } public static void Postfix() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } new LateTask(delegate { try { SetRolesAfterSelect(); ShipStatus.Instance.Begin(); } catch (Exception ex) { Utils.ErrorEnd("Set Roles After Select In LateTask"); Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs", 341, "Postfix"); } }, 1f, "Set Role Types After Select"); } private static void SetRolesAfterSelect() { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0764: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Invalid comparison between Unknown and I4 //IL_0786: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Expected I4, but got Unknown try { PlayerControl[] allPlayerControls; if (GameStates.IsHideNSeek) { GameOptionsSender.AllSenders.Clear(); allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl player in allPlayerControls) { GameOptionsSender.AllSenders.Add(new PlayerGameOptionsSender(player)); } EAC.LogAllRoles(); Utils.SyncAllSettings(); return; } Logger.Msg("Is Started", "AssignRoles", escapeCRLF: true, 367, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); Dictionary dictionary = new Dictionary(); allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { dictionary[val.PlayerId] = new CustomRpcSender(((Object)val).name + "'s SetRole Sender", (SendOption)1, isUnsafe: false).StartMessage(val.GetClientId()); } RpcSetRoleReplacer.StartReplace(dictionary); Dictionary<(byte, byte), RoleTypes> rolesMap = new Dictionary<(byte, byte), RoleTypes>(); PlayerControl key; CustomRoles value; foreach (KeyValuePair item in RoleAssign.RoleResult.Where((KeyValuePair x) => x.Value.IsDesyncRole())) { item.Deconstruct(out key, out value); PlayerControl player2 = key; CustomRoles role = value; AssignDesyncRole(role, player2, dictionary, rolesMap, role.GetDYRole(), (RoleTypes)0); } MakeDesyncSender(dictionary, rolesMap); foreach (KeyValuePair item2 in RoleAssign.RoleResult) { item2.Deconstruct(out key, out value); PlayerControl val2 = key; CustomRoles customRoles = value; if (!((Object)(object)val2 == (Object)null) && !customRoles.IsDesyncRole()) { RpcSetRoleReplacer.StoragedData.Add(val2, customRoles.GetRoleTypes()); Logger.Warn($"Set original role type => {val2.GetRealName()}: {customRoles} => {customRoles.GetRoleTypes()}", "Override Role Select", escapeCRLF: true, 394, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } } RpcSetRoleReplacer.Release(); CollectionExtensions.Do>((IEnumerable>)RpcSetRoleReplacer.senders, (Action>)delegate(KeyValuePair kvp) { kvp.Value.SendMessage(); }); RpcSetRoleReplacer.senders = null; RpcSetRoleReplacer.OverriddenSenderList = null; RpcSetRoleReplacer.StoragedData = null; allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val3 in allPlayerControls) { val3.Data.IsDead = false; if (Main.PlayerStates[val3.PlayerId].MainRole != CustomRoles.NotAssigned) { continue; } CustomRoles mainRole = CustomRoles.NotAssigned; RoleTypes role2 = val3.Data.Role.Role; switch ((int)role2) { case 0: mainRole = CustomRoles.Crewmate; break; case 1: mainRole = CustomRoles.Impostor; break; case 2: mainRole = CustomRoles.Scientist; break; case 3: mainRole = CustomRoles.Engineer; break; case 4: mainRole = CustomRoles.GuardianAngel; break; case 5: mainRole = CustomRoles.Shapeshifter; break; case 8: mainRole = CustomRoles.Noisemaker; break; case 9: mainRole = CustomRoles.Phantom; break; case 10: mainRole = CustomRoles.Tracker; break; default: { string @string = Translator.GetString("Error.InvalidRoleAssignment"); object arg; if (val3 == null) { arg = null; } else { NetworkedPlayerInfo data = val3.Data; arg = ((data != null) ? data.PlayerName : null); } Logger.SendInGame(string.Format(@string, arg)); break; } } Main.PlayerStates[val3.PlayerId].SetMainRole(mainRole); } if (Options.CurrentGameMode == CustomGameMode.FFA) { foreach (KeyValuePair playerState in Main.PlayerStates) { ExtendedPlayerControl.RpcSetCustomRole(playerState.Key, playerState.Value.MainRole); } } else { _ = IRandom.Instance; foreach (KeyValuePair item3 in RoleAssign.RoleResult) { if (!item3.Value.IsDesyncRole()) { AssignCustomRole(item3.Value, item3.Key); } } try { AddonAssign.InitAndStartAssignLovers(); AddonAssign.StartSortAndAssign(); } catch (Exception value2) { Logger.Warn($"Error after addons assign - error: {value2}", "AddonAssign", escapeCRLF: true, 475, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } foreach (KeyValuePair playerState2 in Main.PlayerStates) { ExtendedPlayerControl.RpcSetCustomRole(playerState2.Key, playerState2.Value.MainRole); CustomRoles[] array = playerState2.Value.SubRoles.ToArray(); foreach (CustomRoles role3 in array) { ExtendedPlayerControl.RpcSetCustomRole(playerState2.Key, role3); } } GhostRoleAssign.Add(); allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val4 in allPlayerControls) { RoleBase roleClass = val4.GetRoleClass(); if (roleClass != null && (int)roleClass.ThisRoleBase.GetRoleTypes() == 5) { Main.CheckShapeshift.Add(val4.PlayerId, value: false); } val4.GetRoleClass()?.OnAdd(val4.PlayerId); CustomRoles[] array = val4.GetCustomSubRoles().ToArray(); for (int j = 0; j < array.Length; j++) { switch (array[j]) { case CustomRoles.Aware: Aware.Add(val4.PlayerId); break; case CustomRoles.Radar: Radar.Add(val4.PlayerId); break; case CustomRoles.Glow: Glow.Add(val4.PlayerId); break; case CustomRoles.Oiiai: Oiiai.Add(val4.PlayerId); break; case CustomRoles.Tired: Tired.Add(val4.PlayerId); break; case CustomRoles.Rainbow: Rainbow.Add(); break; case CustomRoles.Statue: Statue.Add(val4.PlayerId); break; case CustomRoles.Ghoul: Ghoul.Add(); break; case CustomRoles.Diseased: Diseased.Add(); break; case CustomRoles.Antidote: Antidote.Add(); break; case CustomRoles.Burst: Burst.Add(); break; case CustomRoles.Bewilder: Bewilder.Add(); break; case CustomRoles.Lucky: Lucky.Add(val4.PlayerId); break; case CustomRoles.Clumsy: Clumsy.Add(val4.PlayerId); break; case CustomRoles.Fool: Fool.Add(); break; case CustomRoles.Bloodthirst: Bloodthirst.Add(); break; } } } } try { if (!((InnerNetClient)AmongUsClient.Instance).IsGameOver) { DestroyableSingleton.Instance.SetHudActive(true); } } catch { } allPlayerControls = Main.AllPlayerControls; for (int i = 0; i < allPlayerControls.Length; i++) { allPlayerControls[i].ResetKillCooldown(); } foreach (KeyValuePair roleTypeNum in RoleTypeNums) { int num = ((!Options.DisableVanillaRoles.GetBool()) ? RoleOpt.GetNumPerGame(roleTypeNum.Key) : 0); num -= roleTypeNum.Value; RoleOpt.SetRoleRate(roleTypeNum.Key, num, RoleOpt.GetChancePerGame(roleTypeNum.Key)); } switch (Options.CurrentGameMode) { case CustomGameMode.Standard: GameEndCheckerForNormal.SetPredicateToNormal(); break; case CustomGameMode.FFA: GameEndCheckerForNormal.SetPredicateToFFA(); Main.ResetCamPlayerList.UnionWith(from pc in Main.AllPlayerControls where pc.GetCustomRole() == CustomRoles.Killer select pc.PlayerId); break; } GameOptionsSender.AllSenders.Clear(); allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl player3 in allPlayerControls) { GameOptionsSender.AllSenders.Add(new PlayerGameOptionsSender(player3)); } EAC.LogAllRoles(); Utils.CountAlivePlayers(sendLog: true); Utils.SyncAllSettings(); Logger.Msg("Ended", "AssignRoles", escapeCRLF: true, 605, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } catch (Exception ex) { Utils.ErrorEnd("Set Roles After Select"); Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs", 610, "SetRolesAfterSelect"); } } private static void AssignDesyncRole(CustomRoles role, PlayerControl player, Dictionary senders, Dictionary<(byte, byte), RoleTypes> rolesMap, RoleTypes BaseRole, RoleTypes hostBaseRole = 0) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { byte playerId = PlayerControl.LocalPlayer.PlayerId; bool num = player.PlayerId == playerId; Main.PlayerStates[player.PlayerId].SetMainRole(role); RoleTypes val = (num ? hostBaseRole : BaseRole); RoleTypes val2 = (RoleTypes)((!num) ? 2 : 0); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val3 in allPlayerControls) { rolesMap[(player.PlayerId, val3.PlayerId)] = ((player.PlayerId != val3.PlayerId) ? val2 : val); } allPlayerControls = Main.AllPlayerControls.Where((PlayerControl x) => player.PlayerId != x.PlayerId).ToArray(); foreach (PlayerControl val4 in allPlayerControls) { rolesMap[(val4.PlayerId, player.PlayerId)] = val2; } RpcSetRoleReplacer.OverriddenSenderList.Add(senders[player.PlayerId]); player.SetRole(val2); player.Data.IsDead = true; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(61, 4); defaultInterpolatedStringHandler.AppendLiteral("Registered Role: "); PlayerControl obj = player; object value; if (obj == null) { value = null; } else { NetworkedPlayerInfo data = obj.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" => "); defaultInterpolatedStringHandler.AppendFormatted(role); defaultInterpolatedStringHandler.AppendLiteral(" : RoleType for self => "); defaultInterpolatedStringHandler.AppendFormatted(val); defaultInterpolatedStringHandler.AppendLiteral(", for others => "); defaultInterpolatedStringHandler.AppendFormatted(val2); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "AssignDesyncRoles", escapeCRLF: true, 638, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } } private static void MakeDesyncSender(Dictionary senders, Dictionary<(byte, byte), RoleTypes> rolesMap) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl seer in allPlayerControls) { PlayerControl[] allPlayerControls2 = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls2) { if (!rolesMap.TryGetValue((seer.PlayerId, val.PlayerId), out var value)) { continue; } try { if ((int)value == 2 && RoleAssign.RoleResult.Any(delegate(KeyValuePair x) { bool flag = x.Key.PlayerId == seer.PlayerId; if (flag) { CustomRoles value2 = x.Value; bool flag2 = ((value2 == CustomRoles.Noisemaker || value2 == CustomRoles.NoisemakerTOHE) ? true : false); flag = flag2; } return flag; })) { Logger.Info($"seer: {seer.PlayerId}, target: {val.PlayerId}, {value} => {8}", "OverrideRoleForDesync", escapeCRLF: true, 653, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); value = (RoleTypes)8; } senders[seer.PlayerId].RpcSetRole(seer, value, val.GetClientId()); } catch { } } } } private static void AssignCustomRole(CustomRoles role, PlayerControl player) { if (!((Object)(object)player == (Object)null)) { Main.PlayerStates[player.PlayerId].SetMainRole(role); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(21, 2); defaultInterpolatedStringHandler.AppendLiteral("Registered Role: "); object value; if (player == null) { value = null; } else { NetworkedPlayerInfo data = player.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" => "); defaultInterpolatedStringHandler.AppendFormatted(role); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "AssignRoles", escapeCRLF: true, 672, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\onGameStartedPatch.cs"); } } } [HarmonyPatch(typeof(AmongUsClient), "OnGameEnd")] internal class EndGamePatch { public static Dictionary SummaryText = new Dictionary(); public static string KillLog = ""; public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref EndGameResult endGameResult) { //IL_0807: Unknown result type (might be due to invalid IL or missing references) //IL_0811: Expected O, but got Unknown GameStates.InGame = false; if (!GameStates.IsModHost || GameStates.IsHideNSeek) { return; } Logger.Info("-----------Game over-----------", "Phase", escapeCRLF: true, 29, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); try { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { foreach (byte key3 in GhostRoleAssign.GhostGetPreviousRole.Keys) { if (Main.PlayerStates.TryGetValue(key3, out var value) && value.MainRole.IsGhostRole() && GhostRoleAssign.GhostGetPreviousRole.TryGetValue(key3, out var value2)) { Main.PlayerStates[key3].MainRole = value2; MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)125, (SendOption)1, -1); val.Write(key3); val.WritePacked((int)value2); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } if (GhostRoleAssign.GhostGetPreviousRole.Any()) { Logger.Info(string.Join(", ", GhostRoleAssign.GhostGetPreviousRole.Select((KeyValuePair x) => $"{Utils.GetPlayerById(x.Key).GetRealName()}/{x.Value}")), "OutroPatch.GhostGetPreviousRole", escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); } } } catch (Exception value3) { Logger.Error($"{value3} at EndGamePatch", "GhostGetPreviousRole", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); } SummaryText = new Dictionary(); GhostRoleAssign.GhostGetPreviousRole = new Dictionary(); byte[] array = Main.PlayerStates.Keys.ToArray(); foreach (byte b in array) { if (Doppelganger.HasEnabled && Doppelganger.DoppelVictim.TryGetValue(b, out var value4)) { PlayerControl playerById = Utils.GetPlayerById(b); if ((Object)(object)playerById != (Object)null) { playerById.RpcSetName(value4); Main.AllPlayerNames[b] = value4; } } SummaryText[b] = Utils.SummaryTexts(b, disableColor: false); } CollectionExtensions.Do(CustomRoleManager.RoleClass.Values.Where((RoleBase x) => x.IsEnable), (Action)delegate(RoleBase x) { x.IsEnable = false; }); StringBuilder stringBuilder = new StringBuilder(Translator.GetString("KillLog") + ":"); if (Options.OldKillLog.GetBool()) { foreach (KeyValuePair item3 in Main.PlayerStates.OrderBy((KeyValuePair x) => x.Value.RealKiller.Item1.Ticks)) { DateTime item = item3.Value.RealKiller.Item1; if (!(item == DateTime.MinValue)) { byte realKiller = item3.Value.GetRealKiller(); byte key = item3.Key; StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 5, stringBuilder2); handler.AppendLiteral("\n"); handler.AppendFormatted(item, "T"); handler.AppendLiteral(" "); handler.AppendFormatted(Main.AllPlayerNames[key]); handler.AppendLiteral("("); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetDisplayRoleAndSubName(key, key, notShowAddOns: true)); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetSubRolesText(key, disableColor: false, intro: false, summary: true)); handler.AppendLiteral(") ["); handler.AppendFormatted(Utils.GetVitalText(item3.Key)); handler.AppendLiteral("]"); stringBuilder3.Append(ref handler); if (realKiller != byte.MaxValue && realKiller != key) { stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(6, 3, stringBuilder2); handler.AppendLiteral("\n\t⇐ "); handler.AppendFormatted(Main.AllPlayerNames[realKiller]); handler.AppendLiteral("("); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetDisplayRoleAndSubName(realKiller, realKiller, notShowAddOns: true)); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetSubRolesText(realKiller, disableColor: false, intro: false, summary: true)); handler.AppendLiteral(")"); stringBuilder4.Append(ref handler); } } } } else { stringBuilder.Clear(); foreach (KeyValuePair item4 in Main.PlayerStates.OrderBy((KeyValuePair x) => x.Value.RealKiller.Item1.Ticks)) { DateTime item2 = item4.Value.RealKiller.Item1; if (!(item2 == DateTime.MinValue)) { byte realKiller2 = item4.Value.GetRealKiller(); byte key2 = item4.Key; StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(102, 5, stringBuilder2); handler.AppendLiteral("\n"); handler.AppendFormatted(item2, "T"); handler.AppendLiteral(" "); handler.AppendFormatted(Main.AllPlayerNames[key2]); handler.AppendLiteral("("); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetDisplayRoleAndSubName(key2, key2, notShowAddOns: true)); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetSubRolesText(key2, disableColor: false, intro: false, summary: true)); handler.AppendLiteral(") 『"); handler.AppendFormatted(Utils.GetVitalText(item4.Key, RealKillerColor: true)); handler.AppendLiteral("』"); stringBuilder5.Append(ref handler); if (realKiller2 != byte.MaxValue && realKiller2 != key2) { stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(9, 3, stringBuilder2); handler.AppendLiteral("
\t⇐ "); handler.AppendFormatted(Main.AllPlayerNames[realKiller2]); handler.AppendLiteral("("); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetDisplayRoleAndSubName(realKiller2, realKiller2, notShowAddOns: true)); handler.AppendFormatted((Options.CurrentGameMode == CustomGameMode.FFA) ? string.Empty : Utils.GetSubRolesText(realKiller2, disableColor: false, intro: false, summary: true)); handler.AppendLiteral(")"); stringBuilder6.Append(ref handler); } } } } KillLog = stringBuilder.ToString(); if (!KillLog.Contains('\n')) { KillLog = ""; } if (GameStates.IsNormalGame) { Main.NormalOptions.KillCooldown = Options.DefaultKillCooldown; } EndGameResult.CachedWinners = new List(); List winner = new List(); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls) { if (CustomWinnerHolder.WinnerIds.Contains(val2.PlayerId)) { winner.Add(val2); } } CustomRoles[] array2 = CustomWinnerHolder.WinnerRoles.ToArray(); foreach (CustomRoles team in array2) { winner.AddRange(Main.AllPlayerControls.Where((PlayerControl p) => p.Is(team) && !winner.Contains(p))); } Main.winnerNameList.Clear(); Main.winnerList.Clear(); winner = winner.Distinct().ToList(); allPlayerControls = winner.ToArray(); foreach (PlayerControl val3 in allPlayerControls) { if ((CustomWinnerHolder.WinnerTeam == CustomWinner.Draw || !val3.Is(CustomRoles.GM)) && !Main.winnerList.Contains(val3.PlayerId)) { EndGameResult.CachedWinners.Add(new CachedPlayerData(val3.Data)); Main.winnerList.Add(val3.PlayerId); Main.winnerNameList.Add(val3.GetRealName()); } } BountyHunter.ChangeTimer.Clear(); Revolutionist.IsDraw.Clear(); Overseer.IsRevealed.Clear(); Main.PlayerQuitTimes.Clear(); ChatManager.ChatSentBySystem = new List(); Main.VisibleTasksCount = false; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Main.RealOptionsData.Restore(GameOptionsManager.Instance.CurrentGameOptions); GameOptionsSender.AllSenders.Clear(); GameOptionsSender.AllSenders.Add(new NormalGameOptionsSender()); } } } [HarmonyPatch(typeof(EndGameManager), "SetEverythingUp")] internal class SetEverythingUpPatch { public static string LastWinsText = ""; public static string LastWinsReason = ""; public static void Postfix(EndGameManager __instance) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_0640: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0883: Unknown result type (might be due to invalid IL or missing references) //IL_08c6: Unknown result type (might be due to invalid IL or missing references) //IL_08d3: Unknown result type (might be due to invalid IL or missing references) //IL_08e0: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek || !Main.playerVersion.ContainsKey(((InnerNetClient)AmongUsClient.Instance).HostId)) { return; } ((TMP_Text)__instance.WinText).alignment = (TextAlignmentOptions)516; GameObject obj = Object.Instantiate(((Component)__instance.WinText).gameObject); obj.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f); obj.transform.position = new Vector3(__instance.WinText.transform.position.x + 2.4f, __instance.WinText.transform.position.y - 0.5f, __instance.WinText.transform.position.z); TextMeshPro component = obj.GetComponent(); ((TMP_Text)component).fontSizeMin = 3f; ((TMP_Text)component).text = ""; string value = ""; string text = ""; string roleColorCode = Utils.GetRoleColorCode(CustomRoles.Crewmate); if (Options.CurrentGameMode == CustomGameMode.FFA) { byte key = CustomWinnerHolder.WinnerIds.FirstOrDefault(); ((Renderer)__instance.BackgroundBar).material.color = Color32.op_Implicit(new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue)); ((TMP_Text)component).text = Main.AllPlayerNames[key] + " wins!"; ((Graphic)component).color = Color32.op_Implicit(Main.PlayerColors[key]); } else { CustomRoles winnerTeam = (CustomRoles)CustomWinnerHolder.WinnerTeam; if (winnerTeam >= CustomRoles.Crewmate) { value = GetWinnerRoleName(winnerTeam); roleColorCode = Utils.GetRoleColorCode(winnerTeam); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(winnerTeam); if (winnerTeam.IsNeutral()) { ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(winnerTeam); } } if (((InnerNetClient)AmongUsClient.Instance).AmHost && Main.PlayerStates[0].MainRole == CustomRoles.GM) { ((TMP_Text)__instance.WinText).text = Translator.GetString("GameOver"); ((Graphic)__instance.WinText).color = Utils.GetRoleColor(CustomRoles.GM); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(winnerTeam); } switch (CustomWinnerHolder.WinnerTeam) { case CustomWinner.Crewmate: roleColorCode = Utils.GetRoleColorCode(CustomRoles.Engineer); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Engineer); break; case CustomWinner.Impostor: roleColorCode = Utils.GetRoleColorCode(CustomRoles.Impostor); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Impostor); break; case CustomWinner.Egoist: roleColorCode = Utils.GetRoleColorCode(CustomRoles.Egoist); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Egoist); break; case CustomWinner.Terrorist: ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Terrorist); break; case CustomWinner.Lovers: ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Lovers); break; case CustomWinner.Draw: ((TMP_Text)__instance.WinText).text = Translator.GetString("ForceEnd"); ((Graphic)__instance.WinText).color = Color.white; ((Renderer)__instance.BackgroundBar).material.color = Color.gray; ((TMP_Text)component).text = Translator.GetString("ForceEndText"); ((Graphic)component).color = Color.gray; break; case CustomWinner.NiceMini: ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Mini); ((Graphic)component).color = Utils.GetRoleColor(CustomRoles.Mini); break; case CustomWinner.Neutrals: ((TMP_Text)__instance.WinText).text = Translator.GetString("DefeatText"); ((Graphic)__instance.WinText).color = Utils.GetRoleColor(CustomRoles.Impostor); ((Renderer)__instance.BackgroundBar).material.color = Utils.GetRoleColor(CustomRoles.Executioner); ((TMP_Text)component).text = Translator.GetString("NeutralsLeftText"); ((Graphic)component).color = Utils.GetRoleColor(CustomRoles.Executioner); break; case CustomWinner.None: ((TMP_Text)__instance.WinText).text = ""; ((Graphic)__instance.WinText).color = Color.black; ((Renderer)__instance.BackgroundBar).material.color = Color.gray; ((TMP_Text)component).text = Translator.GetString("EveryoneDied"); ((Graphic)component).color = Color.gray; break; case CustomWinner.Error: ((TMP_Text)__instance.WinText).text = Translator.GetString("ErrorEndText"); ((Graphic)__instance.WinText).color = Color.red; ((Renderer)__instance.BackgroundBar).material.color = Color.red; ((TMP_Text)component).text = Translator.GetString("ErrorEndTextDescription"); ((Graphic)component).color = Color.white; break; } foreach (AdditionalWinners additionalWinnerTeam in CustomWinnerHolder.AdditionalWinnerTeams) { text = text + "+" + Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor((CustomRoles)additionalWinnerTeam)), GetAdditionalWinnerRoleName((CustomRoles)additionalWinnerTeam)); } CustomWinner winnerTeam2 = CustomWinnerHolder.WinnerTeam; if (winnerTeam2 != CustomWinner.Draw && winnerTeam2 != CustomWinner.None && winnerTeam2 != CustomWinner.Error) { if (text == "") { ((TMP_Text)component).text = $"{value}"; } else { ((TMP_Text)component).text = $"{value}\n{text}"; } } } LastWinsText = ((TMP_Text)component).text; Vector3 val = Camera.main.ViewportToWorldPoint(new Vector3(0f, 1f, Camera.main.nearClipPlane)); GameObject val2 = Object.Instantiate(((Component)__instance.WinText).gameObject); val2.transform.position = new Vector3(((Component)__instance.Navigation.ExitButton).transform.position.x + 0.1f, val.y - 0.1f, -15f); val2.transform.localScale = new Vector3(1f, 1f, 1f); StringBuilder stringBuilder = new StringBuilder(Translator.GetString("RoleSummaryText") + "\n"); List list = new List(Main.PlayerStates.Keys); byte[] array = Main.winnerList.ToArray(); foreach (byte b in array) { if (!EndGamePatch.SummaryText[b].Contains("")) { stringBuilder.Append('\n').Append(EndGamePatch.SummaryText[b]); list.Remove(b); } } if (Options.CurrentGameMode == CustomGameMode.FFA) { List<(int, byte)> list2 = new List<(int, byte)>(); array = list.ToArray(); foreach (byte b2 in array) { list2.Add((FFAManager.GetRankOfScore(b2), b2)); } list2.Sort(); foreach (var item in list2.Where(((int, byte) x) => EndGamePatch.SummaryText.ContainsKey(x.Item2))) { stringBuilder.Append("\n\u3000 ").Append(EndGamePatch.SummaryText[item.Item2]); } } else { stringBuilder.Append("\n"); array = list.ToArray(); foreach (byte key2 in array) { if (!EndGamePatch.SummaryText[key2].Contains("")) { stringBuilder.Append('\n').Append(EndGamePatch.SummaryText[key2]); } } } TextMeshPro component2 = val2.GetComponent(); ((TMP_Text)component2).alignment = (TextAlignmentOptions)257; ((Graphic)component2).color = Color.white; ((TMP_Text)component2).outlineWidth = ((TMP_Text)component2).outlineWidth * 1.2f; float num2 = (((TMP_Text)component2).fontSize = 1.25f); float fontSizeMin = (((TMP_Text)component2).fontSizeMax = num2); ((TMP_Text)component2).fontSizeMin = fontSizeMin; ((Component)component2).GetComponent().anchoredPosition = new Vector2(val.x + 3.5f, val.y - 0.1f); ((TMP_Text)component2).text = stringBuilder.ToString(); Logger.Info($"{CustomWinnerHolder.WinnerTeam}", "Winner Team", escapeCRLF: true, 356, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); Logger.Info(LastWinsReason ?? "", "Wins Reason", escapeCRLF: true, 357, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); Logger.Info(((TMP_Text)component2).text.RemoveHtmlTags() ?? "", "Role Summary", escapeCRLF: true, 358, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\OutroPatch.cs"); static string GetAdditionalWinnerRoleName(CustomRoles role) { string text2 = Translator.GetString("AdditionalWinnerRoleText." + Enum.GetName(typeof(CustomRoles), role)); if (text2 == "" || text2.StartsWith("*") || text2.StartsWith("" + target.GetNameWithRole(), "CheckProtect", escapeCRLF: true, 29, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (!__instance.GetRoleClass().OnCheckProtect(__instance, target)) { return false; } if (__instance.Is(CustomRoles.EvilSpirit)) { if (target.GetRoleClass() is Spiritcaller spiritcaller) { spiritcaller.ProtectSpiritcaller(); } else { Spiritcaller.HauntPlayer(target); } __instance.RpcResetAbilityCooldown(); return false; } if (__instance.Is(CustomRoles.Sheriff) && __instance.Data.IsDead) { Logger.Info("Blocked protection", "CheckProtect", escapeCRLF: true, 51, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } return true; } public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target) { Utils.NotifyRoles(__instance); Utils.NotifyRoles(target); } } [HarmonyPatch(typeof(PlayerControl), "CheckMurder")] internal class CheckMurderPatch { public static Dictionary TimeSinceLastKill = new Dictionary(); public static void Update() { for (byte b = 0; b < 15; b++) { if (TimeSinceLastKill.ContainsKey(b)) { TimeSinceLastKill[b] += Time.deltaTime; if (15f < TimeSinceLastKill[b]) { TimeSinceLastKill.Remove(b); } } } } public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, bool __state = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (GameStates.IsHideNSeek) { return true; } PlayerControl sniper = __instance; Logger.Info(sniper.GetNameWithRole().RemoveHtmlTags() + " => " + target.GetNameWithRole().RemoveHtmlTags(), "CheckMurder", escapeCRLF: true, 87, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (!CheckForInvalidMurdering(sniper, target, checkCanUseKillButton: true)) { return false; } sniper.ResetKillCooldown(); Logger.Info("Kill Cooldown Resets", "CheckMurder", escapeCRLF: true, 95, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (Sniper.SnipeIsActive(__instance.PlayerId)) { Logger.Info("Killer is Sniper", "CheckMurder", escapeCRLF: true, 100, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); Sniper.TryGetSniper(target.PlayerId, ref sniper); Logger.Info("After Try Get Sniper", "CheckMurder", escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (sniper.PlayerId != __instance.PlayerId) { Logger.Info("Real Killer = " + sniper.GetNameWithRole().RemoveHtmlTags(), "Sniper.CheckMurder", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } Logger.Info("Start: CustomRoleManager.OnCheckMurder", "CheckMurder", escapeCRLF: true, 112, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (!CustomRoleManager.OnCheckMurder(ref sniper, ref target, ref __state)) { Logger.Info("Canceled from CustomRoleManager.OnCheckMurder", "CheckMurder", escapeCRLF: true, 116, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } Logger.Info("End: CustomRoleManager.OnCheckMurder", "CheckMurder", escapeCRLF: true, 120, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); __instance.RpcMurderPlayer(target); return false; } public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, bool __state) { if (__state) { Utils.NotifyRoles(__instance); Utils.NotifyRoles(target); } } public static bool CheckForInvalidMurdering(PlayerControl killer, PlayerControl target, bool checkCanUseKillButton = false) { if (!killer.IsAlive()) { Logger.Info(killer.GetNameWithRole().RemoveHtmlTags() + " was cancelled because it is dead", "CheckMurder", escapeCRLF: true, 141, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if ((Object)(object)target.Data == (Object)null || target.inVent || target.inMovingPlat || target.MyPhysics.Animations.IsPlayingEnterVentAnimation() || target.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { Logger.Info("The target is in an unkillable state and the kill is canceled", "CheckMurder", escapeCRLF: true, 154, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (!target.IsAlive()) { Logger.Info("The target is in a dead state and the kill is canceled", "CheckMurder", escapeCRLF: true, 160, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if ((Object)(object)MeetingHud.Instance != (Object)null) { Logger.Info("In the meeting, the kill was canceled", "CheckMurder", escapeCRLF: true, 166, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } float num = ((Options.CurrentGameMode == CustomGameMode.FFA) ? 3000f : 2000f); float num2 = Mathf.Max(0.02f, (float)((InnerNetClient)AmongUsClient.Instance).Ping / num * 6f); if (TimeSinceLastKill.TryGetValue(killer.PlayerId, out var value) && value < num2) { Logger.Info($"Last kill was too shortly before, canceled - time: {value}, minTime: {num2}", "CheckMurder", escapeCRLF: true, 177, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } TimeSinceLastKill[killer.PlayerId] = 0f; if (killer.PlayerId != target.PlayerId && !killer.CanUseKillButton() && checkCanUseKillButton) { Logger.Info(killer.GetNameWithRole().RemoveHtmlTags() + " The hitter is not allowed to use the kill button and the kill is canceled", "CheckMurder", escapeCRLF: true, 185, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (Options.CurrentGameMode == CustomGameMode.FFA) { FFAManager.OnPlayerAttack(killer, target); return false; } if (Glitch.HasEnabled && !Glitch.OnCheckMurderOthers(killer, target)) { Logger.Info("Is hacked by Glitch, it cannot kill ", "Glitch.CheckMurder", escapeCRLF: true, 199, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (Pelican.IsEaten(target.PlayerId)) { Logger.Info("Is eaten player can't be killed", "Pelican.CheckMurder", escapeCRLF: true, 206, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } List list = Utils.GetRoleBasesByType()?.ToList(); if (Penguin.HasEnabled && list != null && list.Any(delegate(Penguin x) { byte playerId = killer.PlayerId; byte? obj; if (x == null) { obj = null; } else { PlayerControl abductVictim = x.AbductVictim; obj = ((abductVictim != null) ? new byte?(abductVictim.PlayerId) : null); } return playerId == obj; })) { killer.Notify(Translator.GetString("PenguinTargetOnCheckMurder")); killer.SetKillCooldown(5f); return false; } return true; } public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target, bool check = false) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } Logger.Info($"check: {check}", "RpcCheckAndMurder", escapeCRLF: true, 229, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if ((Object)(object)target == (Object)null) { target = killer; } CustomRoles customRole = killer.GetCustomRole(); RoleBase roleClass = target.GetRoleClass(); List customSubRoles = target.GetCustomSubRoles(); if (Main.ShieldPlayer != "" && Main.ShieldPlayer == target.GetClient().GetHashedPuid() && Utils.IsAllAlive) { Main.ShieldPlayer = ""; killer.RpcGuardAndKill(target); killer.SetKillCooldown(-1f, null, forceAnime: true); return false; } if (Madmate.MadmateSpawnMode.GetInt() == 1 && Main.MadmateNum < CustomRoles.Madmate.GetCount() && target.CanBeMadmate()) { Main.MadmateNum++; target.RpcSetCustomRole(CustomRoles.Madmate); ExtendedPlayerControl.RpcSetCustomRole(target.PlayerId, CustomRoles.Madmate); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("BecomeMadmateCuzMadmateMode"))); killer.SetKillCooldown(); killer.RpcGuardAndKill(target); target.RpcGuardAndKill(killer); target.RpcGuardAndKill(target); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(32, 3); defaultInterpolatedStringHandler.AppendLiteral("Assign by first try kill: "); PlayerControl obj = target; object value; if (obj == null) { value = null; } else { NetworkedPlayerInfo data = obj.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" = "); defaultInterpolatedStringHandler.AppendFormatted(target.GetCustomRole()); defaultInterpolatedStringHandler.AppendLiteral(" + "); defaultInterpolatedStringHandler.AppendFormatted(CustomRoles.Madmate); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Madmate", escapeCRLF: true, 258, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (killer.Is(Custom_Team.Impostor) && !Madmate.ImpCanKillMadmate.GetBool() && target.Is(CustomRoles.Madmate)) { return false; } Logger.Info("Start", "OnCheckMurderAsTargetOnOthers", escapeCRLF: true, 266, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (!CustomRoleManager.OnCheckMurderAsTargetOnOthers(killer, target)) { Logger.Info("Cancels because for others target need cancel kill", "OnCheckMurderAsTargetOnOthers", escapeCRLF: true, 271, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } Logger.Info("Start", "TargetSubRoles", escapeCRLF: true, 275, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (customSubRoles.Any()) { CustomRoles[] array = customSubRoles.ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.Diseased: Diseased.CheckMurder(killer); break; case CustomRoles.Antidote: Antidote.CheckMurder(killer); break; case CustomRoles.Susceptible: Susceptible.CallEnabledAndChange(target); break; case CustomRoles.Aware: Aware.OnCheckMurder(customRole, target); break; case CustomRoles.Lucky: if (!Lucky.OnCheckMurder(killer, target)) { return false; } break; case CustomRoles.Cyber: { if (killer.PlayerId == target.PlayerId) { break; } PlayerControl[] array2 = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != target.PlayerId).ToArray(); for (int j = 0; j < array2.Length; j++) { _ = array2[j]; if (target.Is(CustomRoles.Cyber) && Main.AllAlivePlayerControls.Any((PlayerControl x) => x.PlayerId != killer.PlayerId && x.PlayerId != target.PlayerId && Vector2.Distance(Vector2.op_Implicit(((Component)x).transform.position), Vector2.op_Implicit(((Component)target).transform.position)) < 2f)) { return false; } } break; } } } } Logger.Info("Start", "OnCheckMurderAsTarget", escapeCRLF: true, 324, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (!roleClass.OnCheckMurderAsTarget(killer, target)) { Logger.Info("Cancels because for target need cancel kill", "OnCheckMurderAsTarget", escapeCRLF: true, 329, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (!check) { killer.RpcMurderPlayer(target); } return true; } } [HarmonyPatch(typeof(PlayerControl), "MurderPlayer")] internal class MurderPlayerPatch { public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, [HarmonyArgument(1)] MurderResultFlags resultFlags, ref bool __state) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) Logger.Info($"{__instance.GetNameWithRole().RemoveHtmlTags()} => {target.GetNameWithRole().RemoveHtmlTags()}{(target.IsProtected() ? "(Protected)" : "")}, flags : {resultFlags}", "MurderPlayer Prefix", escapeCRLF: true, 343, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); bool flag = ((Enum)resultFlags).HasFlag((Enum)(object)(MurderResultFlags)8) && target.IsProtected(); bool flag2 = ((Enum)resultFlags).HasFlag((Enum)(object)(MurderResultFlags)4); bool flag3 = ((Enum)resultFlags).HasFlag((Enum)(object)(MurderResultFlags)2); bool num = (__state = !flag && !flag2 && !flag3); if (flag) { Logger.Info("The kill will fail because it has DecisonByHost and target is protected", "MurderPlayer Prefix", escapeCRLF: true, 352, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } if (flag2) { if (GameStates.IsModHost) { Logger.Info("Host sent FailedProtected due to role skill / reset kill timer", "MurderPlayer Prefix", escapeCRLF: true, 357, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } else { Logger.Info("Vanilla server canceled murder due to protection", "MurderPlayer Prefix", escapeCRLF: true, 359, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } if (flag3) { if (GameStates.IsModHost) { Logger.Info("The kill was cancelled by the host", "MurderPlayer Prefix", escapeCRLF: true, 364, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } else { Logger.Info("The kill was cancelled by the server", "MurderPlayer Prefix", escapeCRLF: true, 366, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } if (num && ((InnerNetClient)AmongUsClient.Instance).AmHost && GameStates.IsNormalGame) { bool value; if (target.shapeshifting) { new LateTask(delegate { if (GameStates.IsInTask) { target.RpcShapeshift(target, false); } }, 1.5f, "Revert Shapeshift Before Murder"); } else if (Main.CheckShapeshift.TryGetValue(target.PlayerId, out value) && value) { target.RpcShapeshift(target, false); } if (!target.IsProtected() && !Doppelganger.CheckDoppelVictim(target.PlayerId) && !Camouflage.ResetSkinAfterDeathPlayers.Contains(target.PlayerId)) { Camouflage.ResetSkinAfterDeathPlayers.Add(target.PlayerId); Camouflage.RpcSetSkin(target, ForceRevert: true, RevertToDefault: true); } } return true; } public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, bool __state) { if (!__state || GameStates.IsHideNSeek) { return; } if (((InnerNetObject)target).AmOwner) { RemoveDisableDevicesPatch.UpdateDisableDevices(); } if (!target.Data.IsDead || !((InnerNetClient)AmongUsClient.Instance).AmHost || Main.OverDeadPlayerList.Contains(target.PlayerId)) { return; } if ((Object)(object)__instance != (Object)(object)__instance) { Logger.Info("Real Killer => " + __instance.GetNameWithRole().RemoveHtmlTags(), "MurderPlayer", escapeCRLF: true, 420, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.etc) { target.SetDeathReason(PlayerState.DeathReason.Kill); } if (Main.FirstDied == "" && target.Is(CustomRoles.Youtuber) && !__instance.Is(CustomRoles.KillingMachine)) { Youtuber.OnMurderPlayer(__instance, target); return; } if (Main.FirstDied == "") { Main.FirstDied = target.GetClient().GetHashedPuid(); } if (Main.AllKillers.ContainsKey(__instance.PlayerId)) { Main.AllKillers.Remove(__instance.PlayerId); } __instance.SetKillTimer(); if (!__instance.Is(CustomRoles.Trickster)) { Main.AllKillers.Add(__instance.PlayerId, Utils.GetTimeStamp()); } Main.PlayerStates[target.PlayerId].SetDead(); target.SetRealKiller(__instance, NotOverRide: true); Utils.CountAlivePlayers(sendLog: true); AfterPlayerDeathTasks(__instance, target, inMeeting: false); Utils.TargetDies(__instance, target); Utils.CountAlivePlayers(sendLog: false, checkGameEnd: true); if (Options.LowLoadMode.GetBool()) { __instance.MarkDirtySettings(); target.MarkDirtySettings(); } else { Utils.SyncAllSettings(); } Utils.NotifyRoles(__instance); Utils.NotifyRoles(target); } public static void AfterPlayerDeathTasks(PlayerControl killer, PlayerControl target, bool inMeeting) { CustomRoleManager.OnMurderPlayer(killer, target, inMeeting); } } [HarmonyPatch(typeof(PlayerControl), "RpcMurderPlayer")] internal class RpcMurderPlayerPatch { public static bool Prefix(PlayerControl __instance, PlayerControl target, bool didSucceed) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { Logger.Error("Client is calling RpcMurderPlayer, are you Hacking?", "RpcMurderPlayerPatch.Prefix", escapeCRLF: true, 483, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } MurderResultFlags val = (MurderResultFlags)(didSucceed ? 1 : 2); if (((InnerNetClient)AmongUsClient.Instance).AmClient) { __instance.MurderPlayer(target, val); } MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)__instance).NetId, (byte)12, (SendOption)1, -1); MessageExtensions.WriteNetObject(val2, (InnerNetObject)(object)target); val2.Write((int)val); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); return false; } } [HarmonyPatch(typeof(PlayerControl), "CheckShapeshift")] public static class CheckShapeshiftPatch { private static readonly LogHandler logger = Logger.Handler("CheckShapeshift"); public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, [HarmonyArgument(1)] bool shouldAnimate) { if (((InnerNetClient)AmongUsClient.Instance).IsGameOver || !((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!CheckInvalidShapeshifting(__instance, target, shouldAnimate)) { __instance.RpcRejectShapeshift(); return false; } bool resetCooldown = true; logger.Info($"Self:{__instance.PlayerId == target.PlayerId} - Is animate:{shouldAnimate} - In Meeting:{GameStates.IsMeeting}"); RoleBase roleClass = __instance.GetRoleClass(); if (roleClass != null && !roleClass.OnCheckShapeshift(__instance, target, ref resetCooldown, ref shouldAnimate)) { if (roleClass.CanDesyncShapeshift) { __instance.RpcSpecificRejectShapeshift(target, shouldAnimate); if (resetCooldown) { __instance.RpcResetAbilityCooldown(); } } else { __instance.RejectShapeshiftAndReset(resetCooldown); } return false; } __instance.RpcShapeshift(target, shouldAnimate); return false; } private static bool CheckInvalidShapeshifting(PlayerControl instance, PlayerControl target, bool animate) { logger.Info("Checking shapeshift " + instance.GetNameWithRole() + " -> " + (((Object)(object)target == (Object)null || (Object)(object)target.Data == (Object)null) ? "(null)" : target.GetNameWithRole().RemoveHtmlTags())); if (!Object.op_Implicit((Object)(object)target) || (Object)(object)target.Data == (Object)null) { logger.Info("Cancel shapeshifting because target is null"); return false; } if (!instance.IsAlive()) { logger.Info("Shapeshifting canceled because shapeshifter is dead"); return false; } if (instance.Data.Disconnected) { logger.Info("Shapeshifting canceled because shapeshifter is disconnected"); return false; } if (target.IsMushroomMixupActive() && animate) { logger.Info("Shapeshifting canceled because mushroom mixup is active"); return false; } if (Object.op_Implicit((Object)(object)MeetingHud.Instance) && animate) { logger.Info("Cancel shapeshifting in meeting"); return false; } if (Pelican.IsEaten(instance.PlayerId)) { logger.Info("Cancel shapeshifting because " + instance.GetRealName() + " is eaten by Pelican"); return false; } return true; } public static void RejectShapeshiftAndReset(this PlayerControl player, bool reset = true) { player.RpcRejectShapeshift(); if (reset) { player.RpcResetAbilityCooldown(); } Logger.Info("Rejected " + player.GetRealName() + " shapeshift & " + (reset ? "Reset cooldown" : "Not Reset cooldown"), "RejectShapeshiftAndReset", escapeCRLF: true, 591, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } [HarmonyPatch(typeof(PlayerControl), "Shapeshift")] internal class ShapeshiftPatch { public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target, [HarmonyArgument(1)] bool animate) { Logger.Info(__instance?.GetNameWithRole().RemoveHtmlTags() + " => " + target?.GetNameWithRole().RemoveHtmlTags(), "ShapeshiftPatch", escapeCRLF: true, 599, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); PlayerControl shapeshifter = __instance; bool flag = shapeshifter.PlayerId != target.PlayerId; if (Main.CheckShapeshift.TryGetValue(shapeshifter.PlayerId, out var value) && value == flag) { Logger.Info(__instance?.GetNameWithRole().RemoveHtmlTags() + " : Cancel Shapeshift.Prefix", "ShapeshiftPatch", escapeCRLF: true, 606, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return; } Main.CheckShapeshift[shapeshifter.PlayerId] = flag; Main.ShapeshiftTarget[shapeshifter.PlayerId] = target.PlayerId; if (!((InnerNetClient)AmongUsClient.Instance).AmHost || GameStates.IsHideNSeek) { return; } if (!flag) { Camouflage.RpcSetSkin(__instance); } shapeshifter.GetRoleClass()?.OnShapeshift(shapeshifter, target, animate, flag); if (shapeshifter.Is(CustomRoles.Glitch) || Main.MeetingIsStarted) { return; } float time = (animate ? 1.2f : 0.5f); if (flag) { new LateTask(delegate { Utils.NotifyRoles(null, shapeshifter, isForMeeting: false, NoCache: true); }, time, "ShapeShiftNotify"); } else if (!flag) { new LateTask(delegate { Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); }, time, "UnShiftNotify"); } } } [HarmonyPatch(typeof(PlayerControl), "CmdCheckVanish")] internal class CmdCheckVanishPatch { public static bool Prefix(PlayerControl __instance, float maxDuration) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { __instance.CheckVanish(); return false; } __instance.SetRoleInvisibility(true, true, false); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)__instance).NetId, (byte)62, (SendOption)1, ((InnerNetClient)AmongUsClient.Instance).HostId); val.Write(maxDuration); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); return false; } } [HarmonyPatch(typeof(PlayerControl), "CmdCheckAppear")] internal class CmdCheckAppearPatch { public static bool Prefix(PlayerControl __instance, bool shouldAnimate) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { __instance.CheckAppear(shouldAnimate); return false; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)__instance).NetId, (byte)64, (SendOption)1, ((InnerNetClient)AmongUsClient.Instance).HostId); val.Write(shouldAnimate); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); return false; } } [HarmonyPatch(typeof(PlayerControl), "CheckVanish")] internal class CheckVanishPatch { public static bool Prefix(PlayerControl __instance) { return true; } } [HarmonyPatch(typeof(PlayerControl), "CheckAppear")] internal class CheckAppearPatch { public static bool Prefix(PlayerControl __instance, bool shouldAnimate) { return true; } } [HarmonyPatch(typeof(PlayerControl), "SetRoleInvisibility")] internal class SetRoleInvisibilityPatch { public static readonly Dictionary PhantomIsInvisibility = new Dictionary(); public static void Prefix(PlayerControl __instance, bool isActive, bool shouldAnimate, bool playFullAnimation) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } Logger.Info($"Player: {__instance.GetRealName()} => Is Active {isActive}, Animate:{shouldAnimate}, Full Animation:{playFullAnimation}", "SetRoleInvisibility", escapeCRLF: true, 716, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (GameStates.IsMeeting) { return; } Vent val = ((IList)ShipStatus.Instance.AllVents).RandomElement(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (!((Object)(object)__instance == (Object)(object)val2) && !((InnerNetObject)val2).AmOwner && val2.GetCustomRole().IsDesyncRole()) { if (isActive) { int id = val.Id; Vector3 position = ((Component)val).transform.position; __instance.RpcDesyncTeleport(Vector2.op_Implicit(position), val2); __instance.MyPhysics.RpcEnterVentDesync(id, val2); } else if (!isActive && shouldAnimate) { PhantomIsInvisibility.TryGetValue(__instance.PlayerId, out var value); __instance.MyPhysics.RpcExitVentDesync(value.Id, val2); __instance.RpcDesyncTeleport(__instance.GetCustomPosition(), val2); } } } if (isActive) { PhantomIsInvisibility.Add(__instance.PlayerId, val); } else { PhantomIsInvisibility.Remove(__instance.PlayerId); } } } [HarmonyPatch(typeof(PlayerControl), "ReportDeadBody")] internal class ReportDeadBodyPatch { public static Dictionary CanReport; public static Dictionary> WaitReport = new Dictionary>(); public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo target) { //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsMeeting || GameStates.IsHideNSeek) { return false; } if (EAC.RpcReportDeadBodyCheck(__instance, target)) { Logger.Fatal("Eac patched the report body rpc", "ReportDeadBodyPatch", escapeCRLF: true, 759, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } if (Options.DisableMeeting.GetBool()) { return false; } if (Options.CurrentGameMode == CustomGameMode.FFA) { return false; } if (!CanReport[__instance.PlayerId]) { WaitReport[__instance.PlayerId].Add(target); Logger.Warn(__instance.GetNameWithRole().RemoveHtmlTags() + " : Reporting is prohibited and will wait until it becomes possible", "ReportDeadBody", escapeCRLF: true, 768, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + " => " + (((target != null) ? target.PlayerName : null) ?? "null (Button Pressed)"), "ReportDeadBody", escapeCRLF: true, 772, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); foreach (KeyValuePair playerState in Main.PlayerStates) { PlayerControl playerById = Utils.GetPlayerById(playerState.Key); playerState.Value.LastRoom = playerById.GetPlainShipRoom(); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } try { if (__instance.Data.IsDead) { return false; } PlayerControl val = ((target == null) ? null : target.Object?.GetRealKiller()); val?.GetCustomRole(); if ((Object)(object)target == (Object)null) { RoleBase roleClass = __instance.GetRoleClass(); if (!roleClass.OnCheckStartMeeting(__instance)) { Logger.Info($"Player has role class: {roleClass} - the start of the meeting has been cancelled", "ReportDeadBody", escapeCRLF: true, 800, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } } if ((Object)(object)target != (Object)null) { if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Gambled) { return false; } PlayerState[] array = Main.PlayerStates.Values.ToArray(); foreach (PlayerState obj in array) { RoleBase roleClass2 = obj.RoleClass; if (obj != null && roleClass2 != null && !roleClass2.OnCheckReportDeadBody(__instance, target, val)) { Logger.Info($"Player has role class: {roleClass2} - is canceled the report", "ReportDeadBody", escapeCRLF: true, 817, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } } if ((!target.Object.Is(CustomRoles.Bait) || !Bait.BaitCanBeReportedUnderAllConditions.GetBool()) && Options.DisableReportWhenCC.GetBool() && Utils.IsActive((SystemTypes)14) && Camouflage.IsActive) { return false; } if (Main.UnreportableBodies.Contains(target.PlayerId)) { __instance.Notify(Utils.ColorString(Color32.op_Implicit(__instance.GetRoleColor()), Translator.GetString("BodyCannotBeReported"))); return false; } if (target.Object.Is(CustomRoles.Unreportable)) { return false; } PlayerControl playerById2 = Utils.GetPlayerById(target.PlayerId); if (__instance.Is(CustomRoles.Oblivious) && (!playerById2.Is(CustomRoles.Bait) || (playerById2.Is(CustomRoles.Bait) && Oblivious.ObliviousBaitImmune.GetBool()))) { return false; } Utils.GetPlayerById(target.PlayerId); if (__instance.Is(CustomRoles.Unlucky) && ((Object)(object)((target != null) ? target.Object : null) == (Object)null || !target.Object.Is(CustomRoles.Bait)) && Unlucky.SuicideRand(__instance, Unlucky.StateSuicide.ReportDeadBody)) { return false; } } if (Options.SyncButtonMode.GetBool() && (Object)(object)target == (Object)null) { Logger.Info($"Option: {Options.SyncedButtonCount.GetInt()}, has button count: {Options.UsedButtonCount}", "ReportDeadBody", escapeCRLF: true, 861, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (Options.SyncedButtonCount.GetFloat() <= (float)Options.UsedButtonCount) { Logger.Info("The button has been canceled because the maximum number of available buttons has been exceeded", "ReportDeadBody", escapeCRLF: true, 864, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); return false; } Options.UsedButtonCount++; if (Options.SyncedButtonCount.GetFloat() == (float)Options.UsedButtonCount) { Logger.Info("The maximum number of meeting buttons has been reached", "ReportDeadBody", escapeCRLF: true, 871, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs", 877, "Prefix"); } AfterReportTasks(__instance, target); return true; } public static void AfterReportTasks(PlayerControl player, NetworkedPlayerInfo target) { try { Main.MeetingIsStarted = true; Main.LastVotedPlayerInfo = null; Main.AllKillers.Clear(); GuessManager.GuesserGuessed.Clear(); Logger.Info($"target is null? - {(Object)(object)target == (Object)null}", "AfterReportTasks", escapeCRLF: true, 899, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); Logger.Info($"target.Object is null? - {(Object)(object)((target != null) ? target.Object : null) == (Object)null}", "AfterReportTasks", escapeCRLF: true, 900, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); Logger.Info($"target.PlayerId is - {((target != null) ? new byte?(target.PlayerId) : null)}", "AfterReportTasks", escapeCRLF: true, 901, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); PlayerState[] array = Main.PlayerStates.Values.ToArray(); foreach (PlayerState playerState in array) { try { playerState.RoleClass?.OnReportDeadBody(player, target); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs", 911, "AfterReportTasks"); Logger.Error($"Role Class Error: {ex}", "RoleClass_OnReportDeadBody", escapeCRLF: true, 912, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); Logger.SendInGame($"Error: {ex}"); } } Alchemist.OnReportDeadBodyGlobal(); if (Aware.IsEnable) { Aware.OnReportDeadBody(); } Sleuth.OnReportDeadBody(player, target); } catch (Exception ex2) { Utils.ThrowException(ex2, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs", 927, "AfterReportTasks"); Logger.Error($"Error: {ex2}", "AfterReportTasks", escapeCRLF: true, 928, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); Logger.SendInGame($"Error: {ex2}"); } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!Doppelganger.CheckDoppelVictim(val.PlayerId)) { bool flag = Camouflage.IsCamouflage; if (flag) { int value = Options.KPDCamouflageMode.GetValue(); bool flag2 = (uint)(value - 2) <= 1u; flag = flag2; } if (flag) { Camouflage.RpcSetSkin(val); } if (Main.CheckShapeshift.ContainsKey(val.PlayerId)) { Camouflage.RpcSetSkin(val, ForceRevert: false, RevertToDefault: true); } } if (GameStates.FungleIsActive && (val.IsMushroomMixupActive() || Utils.IsActive((SystemTypes)57))) { val.FixMixedUpOutfit(); } DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 3); defaultInterpolatedStringHandler.AppendLiteral("Player "); object value2; if (val == null) { value2 = null; } else { NetworkedPlayerInfo data = val.Data; value2 = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral(": Id "); defaultInterpolatedStringHandler.AppendFormatted(val.PlayerId); defaultInterpolatedStringHandler.AppendLiteral(" - is alive: "); defaultInterpolatedStringHandler.AppendFormatted(val.IsAlive()); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "CheckIsAlive", escapeCRLF: true, 955, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } MeetingTimeManager.OnReportDeadBody(); NameNotifyManager.Reset(); Utils.DoNotifyRoles(null, null, isForMeeting: true, NoCache: true, ForceLoop: true, CamouflageIsForMeeting: true); new LateTask(Utils.SyncAllSettings, 3f, "Sync all settings after report"); } } [HarmonyPatch(typeof(PlayerControl), "FixedUpdate")] internal class FixedUpdateInNormalGamePatch { private static readonly StringBuilder Mark = new StringBuilder(20); private static readonly StringBuilder Suffix = new StringBuilder(120); private static readonly Dictionary BufferTime = new Dictionary(); private static int LevelKickBufferTime = 20; public static async void Postfix(PlayerControl __instance) { if (GameStates.IsHideNSeek || !GameStates.IsModHost || (Object)(object)__instance == (Object)null) { return; } byte playerId = __instance.PlayerId; if (((InnerNetClient)AmongUsClient.Instance).AmHost && GameStates.IsInTask && ReportDeadBodyPatch.CanReport[playerId] && ReportDeadBodyPatch.WaitReport[playerId].Any() && (!Glitch.HasEnabled || Glitch.OnCheckFixedUpdateReport(__instance, playerId))) { NetworkedPlayerInfo val = ReportDeadBodyPatch.WaitReport[playerId][0]; ReportDeadBodyPatch.WaitReport[playerId].Clear(); Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + ": The report will be processed now that it is available for reporting", "ReportDeadbody", escapeCRLF: true, 994, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); __instance.ReportDeadBody(val); } try { await DoPostfix(__instance); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs", 1005, "Postfix"); Logger.Error($"Error for {__instance.GetNameWithRole().RemoveHtmlTags()}: Error: {ex}", "FixedUpdateInNormalGamePatch", escapeCRLF: true, 1006, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } public static Task DoPostfix(PlayerControl __instance) { //IL_0764: Unknown result type (might be due to invalid IL or missing references) //IL_081c: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Invalid comparison between Unknown and I4 //IL_0903: Unknown result type (might be due to invalid IL or missing references) //IL_0908: Unknown result type (might be due to invalid IL or missing references) //IL_0a69: Unknown result type (might be due to invalid IL or missing references) //IL_0a6e: Unknown result type (might be due to invalid IL or missing references) //IL_0a2b: Unknown result type (might be due to invalid IL or missing references) //IL_0a30: Unknown result type (might be due to invalid IL or missing references) //IL_0c01: Unknown result type (might be due to invalid IL or missing references) //IL_0c06: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (Options.LowLoadMode.GetBool()) { if (!BufferTime.TryGetValue(__instance.PlayerId, out var value)) { BufferTime.TryAdd(__instance.PlayerId, 30); value = 30; } value--; if (value > 0) { flag = true; } else { value = 30; } BufferTime[__instance.PlayerId] = value; } if (!flag) { Zoom.OnFixedUpdate(); } if (GameStates.IsInGame) { Sniper.OnFixedUpdateGlobal(__instance); if (!flag) { NameNotifyManager.OnFixedUpdate(__instance); TargetArrow.OnFixedUpdate(__instance); LocateArrow.OnFixedUpdate(__instance); } } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (GameStates.IsLobby) { if (((ModUpdater.hasUpdate && ModUpdater.forceUpdate) || ModUpdater.isBroken || !Main.AllowPublicRoom || !VersionChecker.IsSupported) && ((InnerNetClient)AmongUsClient.Instance).IsGamePublic) { ((InnerNetClient)AmongUsClient.Instance).ChangeGamePublic(false); } bool flag2 = false; if (Options.ApplyAllowList.GetBool()) { flag2 = BanManager.CheckAllowList(__instance.Data.FriendCode); } if (!flag2 && !flag && !((InnerNetObject)__instance).AmOwner && Options.KickLowLevelPlayer.GetInt() != 0 && __instance.Data.PlayerLevel != 0 && __instance.Data.PlayerLevel < Options.KickLowLevelPlayer.GetInt()) { LevelKickBufferTime--; if (LevelKickBufferTime <= 0) { LevelKickBufferTime = 20; if (!Options.TempBanLowLevelPlayer.GetBool()) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), false); string text = string.Format(Translator.GetString("KickBecauseLowLevel"), __instance.GetRealName().RemoveHtmlTags()); Logger.SendInGame(text); Logger.Info(text, "Low Level Kick", escapeCRLF: true, 1105, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } else { if (__instance.GetClient().ProductUserId != "" && !BanManager.TempBanWhiteList.Contains(__instance.GetClient().GetHashedPuid())) { BanManager.TempBanWhiteList.Add(__instance.GetClient().GetHashedPuid()); } string text2 = string.Format(Translator.GetString("TempBannedBecauseLowLevel"), __instance.GetRealName().RemoveHtmlTags()); Logger.SendInGame(text2); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), true); Logger.Info(text2, "Low Level Temp Ban", escapeCRLF: true, 1117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } } if (KickPlayerPatch.AttemptedKickPlayerList.Any()) { foreach (KeyValuePair attemptedKickPlayer in KickPlayerPatch.AttemptedKickPlayerList) { KickPlayerPatch.AttemptedKickPlayerList[attemptedKickPlayer.Key]++; if (attemptedKickPlayer.Value > 11) { KickPlayerPatch.AttemptedKickPlayerList.Remove(attemptedKickPlayer.Key); } } } } DoubleTrigger.OnFixedUpdate(__instance); KillTimerManager.FixedUpdate(__instance); if (GameStates.IsInGame && __instance.GetRoleClass() is Mini mini && !__instance.Data.IsDead) { mini.OnFixedUpdates(__instance); } if (GameStates.IsInTask) { CustomRoleManager.OnFixedUpdate(__instance); if (Main.LateOutfits.TryGetValue(__instance.PlayerId, out var value2) && !__instance.CheckCamoflague()) { value2(); Main.LateOutfits.Remove(__instance.PlayerId); Logger.Info("Reset " + __instance.GetRealName() + "'s outfit", "LateOutfits..OnFixedUpdate", escapeCRLF: true, 1153, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } if (__instance.Is(CustomRoles.Statue) && __instance.IsAlive()) { Statue.OnFixedUpdate(__instance); } if (!flag) { CustomRoleManager.OnFixedUpdateLowLoad(__instance); if (Glow.IsEnable) { Glow.OnFixedUpdate(__instance); } if (Radar.IsEnable) { Radar.OnFixedUpdate(__instance); } if (Options.LadderDeath.GetBool() && __instance.IsAlive()) { FallFromLadder.FixedUpdate(__instance); } if (((InnerNetObject)__instance).AmOwner) { DisableDevice.FixedUpdate(); if (CustomRoles.Lovers.IsEnable()) { LoversSuicide(127); } if (Rainbow.isEnabled) { Rainbow.OnFixedUpdate(); } } } } if (!flag) { if (!Main.DoBlockNameChange) { Utils.ApplySuffix(__instance); } if (GameStates.IsInGame && Main.RefixCooldownDelay <= 0f) { PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (val.Is(CustomRoles.Vampire) || val.Is(CustomRoles.Warlock) || val.Is(CustomRoles.Ninja)) { Main.AllPlayerKillCooldown[val.PlayerId] = Options.DefaultKillCooldown * 2f; } if (val.Is(CustomRoles.Poisoner)) { Main.AllPlayerKillCooldown[val.PlayerId] = Poisoner.KillCooldown.GetFloat() * 2f; } } } } } if (((InnerNetObject)__instance).AmOwner && GameStates.IsInTask && !__instance.Is(Custom_Team.Impostor) && __instance.CanUseKillButton() && !__instance.Data.IsDead) { List playersInAbilityRangeSorted = __instance.GetPlayersInAbilityRangeSorted(); PlayerControl target = ((!playersInAbilityRangeSorted.Any()) ? null : playersInAbilityRangeSorted[0]); DestroyableSingleton.Instance.KillButton.SetTarget(target); } TextMeshPro component = ((Component)__instance.cosmetics.nameText.transform.Find("RoleText")).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)__instance != (Object)null && !flag) { if (GameStates.IsLobby) { if (Main.playerVersion.TryGetValue(__instance.GetClientId(), out var value3)) { if (Main.ForkId != value3.forkId) { ((TMP_Text)__instance.cosmetics.nameText).text = $"{value3.forkId}\n{((__instance != null) ? ((Object)__instance).name : null)}"; } else if (Main.version.CompareTo(value3.version) == 0) { ((TMP_Text)__instance.cosmetics.nameText).text = ((value3.tag == "f6840257(main)") ? ("" + ((Object)__instance).name + "") : $"{value3.tag}\n{((__instance != null) ? ((Object)__instance).name : null)}"); } else { ((TMP_Text)__instance.cosmetics.nameText).text = $"v{value3.version}\n{((__instance != null) ? ((Object)__instance).name : null)}"; } } else { TextMeshPro nameText = __instance.cosmetics.nameText; object text3; if (__instance == null) { text3 = null; } else { NetworkedPlayerInfo data = __instance.Data; text3 = ((data != null) ? data.PlayerName : null); } ((TMP_Text)nameText).text = (string)text3; } } if (GameStates.IsInGame) { (string, Color) roleAndSubText = Utils.GetRoleAndSubText(PlayerControl.LocalPlayer.PlayerId, __instance.PlayerId); ((TMP_Text)component).text = roleAndSubText.Item1; ((Graphic)component).color = roleAndSubText.Item2; if (Options.CurrentGameMode == CustomGameMode.FFA) { ((TMP_Text)component).text = string.Empty; } if (((InnerNetObject)__instance).AmOwner || Options.CurrentGameMode == CustomGameMode.FFA) { ((Behaviour)component).enabled = true; } else if (ExtendedPlayerControl.KnowRoleTarget(PlayerControl.LocalPlayer, __instance)) { ((Behaviour)component).enabled = true; } else { ((Behaviour)component).enabled = false; } if (!PlayerControl.LocalPlayer.Data.IsDead && Overseer.IsRevealedPlayer(PlayerControl.LocalPlayer, __instance) && __instance.Is(CustomRoles.Trickster)) { ((TMP_Text)component).text = Overseer.GetRandomRole(PlayerControl.LocalPlayer.PlayerId); ((TMP_Text)component).text = ((TMP_Text)component).text + TaskState.GetTaskState(); } if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 2) { ((Behaviour)component).enabled = false; if (!((InnerNetObject)__instance).AmOwner) { TextMeshPro nameText2 = __instance.cosmetics.nameText; object text4; if (__instance == null) { text4 = null; } else { NetworkedPlayerInfo data2 = __instance.Data; text4 = ((data2 != null) ? data2.PlayerName : null); } ((TMP_Text)nameText2).text = (string)text4; } } if (Main.VisibleTasksCount) { ((TMP_Text)component).text = ((TMP_Text)component).text + Utils.GetProgressText(__instance); } PlayerControl localPlayer = PlayerControl.LocalPlayer; RoleBase roleClass = localPlayer.GetRoleClass(); PlayerControl val2 = __instance; if ((Object)(object)localPlayer != (Object)(object)val2 && (Object)(object)localPlayer != (Object)(object)DollMaster.DollMasterTarget) { val2 = DollMaster.SwapPlayerInfo(val2); } string name = val2.GetRealName(); Mark.Clear(); Suffix.Clear(); if (((InnerNetObject)val2).AmOwner && GameStates.IsInTask) { if (Options.CurrentGameMode == CustomGameMode.FFA) { FFAManager.GetNameNotify(val2, ref name); } if (Pelican.IsEaten(localPlayer.PlayerId)) { name = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pelican)), Translator.GetString("EatenByPelican")); } if (Deathpact.IsInActiveDeathpact(localPlayer)) { name = Deathpact.GetDeathpactString(localPlayer); } if (NameNotifyManager.GetNameNotify(val2, out var name2)) { name = name2; } } name = name.ApplyNameColorData(localPlayer, val2, isMeeting: false); CustomRoles customRole = localPlayer.GetCustomRole(); Mark.Append(roleClass?.GetMark(localPlayer, val2)); Mark.Append(CustomRoleManager.GetMarkOthers(localPlayer, val2)); Suffix.Append(CustomRoleManager.GetLowerTextOthers(localPlayer, val2)); if (Radar.IsEnable) { Suffix.Append(Radar.GetPlayerArrow(localPlayer, val2)); } Suffix.Append(roleClass?.GetSuffix(localPlayer, val2)); Suffix.Append(CustomRoleManager.GetSuffixOthers(localPlayer, val2)); if (customRole.IsImpostor() && val2.GetPlayerTaskState().IsTaskFinished && val2.Is(CustomRoles.Snitch) && val2.Is(CustomRoles.Madmate)) { Mark.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), "★")); } if (val2.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) { Mark.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cyber)), "★")); } if (val2.Is(CustomRoles.Lovers) && localPlayer.Is(CustomRoles.Lovers)) { StringBuilder mark = Mark; StringBuilder stringBuilder = mark; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, mark); handler.AppendLiteral("♥"); stringBuilder.Append(ref handler); } else if (val2.Is(CustomRoles.Lovers) && localPlayer.Data.IsDead) { StringBuilder mark = Mark; StringBuilder stringBuilder2 = mark; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(17, 1, mark); handler.AppendLiteral("♥"); stringBuilder2.Append(ref handler); } if (Options.CurrentGameMode == CustomGameMode.FFA) { Suffix.Append(FFAManager.GetPlayerArrow(localPlayer, val2)); } if (CustomRoles.Devourer.HasEnabled() && Devourer.HideNameOfTheDevoured(val2.PlayerId)) { name = Translator.GetString("DevouredName"); } if (CustomRoles.DollMaster.HasEnabled() && customRole != CustomRoles.DollMaster && DollMaster.IsDoll(localPlayer.PlayerId)) { name = "■"; } if ((Utils.IsActive((SystemTypes)14) && Camouflage.IsActive) || Camouflager.AbilityActivated) { name = "" + name + " "; } string value4 = ((localPlayer.Data.IsDead && localPlayer.KnowDeathReason(val2)) ? (" (" + Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doctor)), Utils.GetVitalText(val2.PlayerId)) + ")") : string.Empty); string text5 = ((TMP_Text)val2.cosmetics.nameText).text; string text6 = $"{name}{value4}{Mark}\r\n{Suffix}"; if (text5 != text6) { ((TMP_Text)val2.cosmetics.nameText).text = text6; float num = 0.2f; float num2 = -0.2f; if (Suffix.ToString() != string.Empty) { num += 0.15f; num2 -= 0.2f; } GameObjectExtensions.SetLocalY(component.transform, num); GameObjectExtensions.SetLocalY(val2.cosmetics.colorBlindText.transform, num2); } } else { GameObjectExtensions.SetLocalY(component.transform, 0.2f); GameObjectExtensions.SetLocalY(__instance.cosmetics.colorBlindText.transform, -0.32f); } } return Task.CompletedTask; } public static void LoversSuicide(byte deathId = 127, bool isExiled = false) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Invalid comparison between Unknown and I4 if (!Options.LoverSuicide.GetBool() || Main.isLoversDead) { return; } PlayerControl[] array = Main.LoversPlayers.ToArray(); foreach (PlayerControl val in array) { if (val.IsAlive() && val.PlayerId != deathId) { continue; } Main.isLoversDead = true; PlayerControl[] array2 = Main.LoversPlayers.ToArray(); foreach (PlayerControl val2 in array2) { if (val.PlayerId == val2.PlayerId || val2.PlayerId == deathId || !val2.IsAlive() || !val2.Is(CustomRoles.Lovers)) { continue; } val2.SetDeathReason(PlayerState.DeathReason.FollowingSuicide); bool flag; if (isExiled) { if (Main.PlayersDiedInMeeting.Contains(deathId)) { val2.Data.IsDead = true; val2.RpcExileV2(); Main.PlayerStates[val2.PlayerId].SetDead(); MeetingHud instance = MeetingHud.Instance; VoteStates? val3 = ((instance != null) ? new VoteStates?(instance.state) : null); if (val3.HasValue) { VoteStates valueOrDefault = val3.GetValueOrDefault(); if (valueOrDefault - 1 <= 2) { flag = true; goto IL_0128; } } flag = false; goto IL_0128; } CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.FollowingSuicide, val2.PlayerId); continue; } val2.RpcMurderPlayer(val2); continue; IL_0128: if (flag) { MeetingHud instance2 = MeetingHud.Instance; if (instance2 != null) { instance2.CheckForEndVoting(); } } MurderPlayerPatch.AfterPlayerDeathTasks(val2, val2, inMeeting: true); new LateTask(delegate { HudManager instance3 = DestroyableSingleton.Instance; if (instance3 != null) { instance3.SetHudActive(false); } }, 0.3f, "SetHudActive in LoversSuicide", shoudLog: false); } } } } [HarmonyPatch(typeof(PlayerControl), "Start")] internal class PlayerStartPatch { public static void Postfix(PlayerControl __instance) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsHideNSeek) { TextMeshPro obj = Object.Instantiate(__instance.cosmetics.nameText); obj.transform.SetParent(__instance.cosmetics.nameText.transform); obj.transform.localPosition = new Vector3(0f, 0.2f, 0f); ((TMP_Text)obj).fontSize = 1.3f; ((TMP_Text)obj).text = "RoleText"; ((Object)((Component)obj).gameObject).name = "RoleText"; ((Behaviour)obj).enabled = false; } } } [HarmonyPatch(typeof(PlayerPhysics), "CoEnterVent")] internal class CoEnterVentPatch { public static bool Prefix(PlayerPhysics __instance, [HarmonyArgument(0)] int id) { //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Invalid comparison between Unknown and I4 if (!((InnerNetClient)AmongUsClient.Instance).AmHost || GameStates.IsHideNSeek) { return true; } Logger.Info($" {__instance.myPlayer.GetNameWithRole().RemoveHtmlTags()}, Vent ID: {id}", "CoEnterVent", escapeCRLF: true, 1454, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); if (Options.CurrentGameMode == CustomGameMode.FFA && FFAManager.CheckCoEnterVent(__instance, id)) { return true; } if (KillTimerManager.AllKillTimers.TryGetValue(__instance.myPlayer.PlayerId, out var value)) { KillTimerManager.AllKillTimers[__instance.myPlayer.PlayerId] = value + 0.5f; } if (CustomRoleManager.OthersCoEnterVent(__instance, id)) { return true; } RoleBase roleClass = __instance.myPlayer.GetRoleClass(); if (((int)__instance.myPlayer.Data.Role.Role != 3 && !__instance.myPlayer.CanUseImpostorVentButton()) || (roleClass != null && roleClass.CheckBootFromVent(__instance, id))) { try { PlayerPhysics obj = __instance; if (obj != null) { obj.RpcBootFromVent(id); } } catch { new LateTask(delegate { PlayerPhysics obj3 = __instance; if (obj3 != null) { obj3.RpcBootFromVent(id); } }, 0.5f, "Prevent Enter Vents"); } return false; } roleClass?.OnCoEnterVent(__instance, id); return true; } } [HarmonyPatch(typeof(Vent), "EnterVent")] internal class EnterVentPatch { public static void Postfix(Vent __instance, [HarmonyArgument(0)] PlayerControl pc) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return; } Main.LastEnteredVent.Remove(pc.PlayerId); Main.LastEnteredVent.Add(pc.PlayerId, __instance); Main.LastEnteredVentLocation.Remove(pc.PlayerId); Main.LastEnteredVentLocation.Add(pc.PlayerId, pc.GetCustomPosition()); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { pc.GetRoleClass()?.OnEnterVent(pc, __instance); if (pc.Is(CustomRoles.Unlucky)) { Unlucky.SuicideRand(pc, Unlucky.StateSuicide.EnterVent); } } } } [HarmonyPatch(typeof(PlayerPhysics), "CoExitVent")] internal class CoExitVentPatch { public static void Postfix(PlayerPhysics __instance, [HarmonyArgument(0)] int id) { if (!GameStates.IsHideNSeek) { Logger.Info($" {__instance.myPlayer.GetNameWithRole().RemoveHtmlTags()}, Vent ID: {id}", "CoExitVent", escapeCRLF: true, 1525, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); PlayerControl myPlayer = __instance.myPlayer; if (Options.CurrentGameMode == CustomGameMode.FFA && FFAManager.FFA_DisableVentingWhenKCDIsUp.GetBool()) { FFAManager.CoExitVent(myPlayer); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { myPlayer.GetRoleClass()?.OnExitVent(myPlayer, id); } } } } [HarmonyPatch(typeof(PlayerControl), "CompleteTask")] internal class PlayerControlCompleteTaskPatch { public static bool Prefix(PlayerControl __instance, object[] __args) { if (GameStates.IsHideNSeek) { return true; } Logger.Info("Task Complete: " + __instance.GetNameWithRole(), "CompleteTask.Prefix", escapeCRLF: true, 1547, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); TaskState playerTaskState = __instance.GetPlayerTaskState(); playerTaskState.Update(__instance); bool flag = true; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { RoleBase roleClass = __instance.GetRoleClass(); if (roleClass != null) { flag = roleClass.OnTaskComplete(__instance, playerTaskState.CompletedTasksCount, playerTaskState.AllTasksCount); } if ((Object)(object)__instance != (Object)null && __args != null && __args.Any()) { int taskIndex = Convert.ToInt32(__args.First()); PlayerTask val = ((IEnumerable)__instance.myTasks.ToArray()).FirstOrDefault((Func)((PlayerTask task) => task.Id == (uint)taskIndex)); if ((Object)(object)val != (Object)null) { CustomRoleManager.OthersCompleteThisTask(__instance, val); } } List customSubRoles = __instance.GetCustomSubRoles(); if (customSubRoles.Any()) { using List.Enumerator enumerator = customSubRoles.GetEnumerator(); while (enumerator.MoveNext()) { switch (enumerator.Current) { case CustomRoles.Unlucky: if (__instance.IsAlive()) { Unlucky.SuicideRand(__instance, Unlucky.StateSuicide.CompleteTask); } break; case CustomRoles.Tired: if (__instance.IsAlive()) { Tired.AfterActionTasks(__instance); } break; case CustomRoles.Bloodthirst: if (__instance.IsAlive()) { Bloodthirst.OnTaskComplete(__instance); } break; case CustomRoles.Ghoul: if (playerTaskState.CompletedTasksCount >= playerTaskState.AllTasksCount) { Ghoul.OnTaskComplete(__instance); } break; case CustomRoles.Madmate: if (playerTaskState.IsTaskFinished && __instance.Is(CustomRoles.Snitch)) { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl pc) => pc.Is(Custom_Team.Impostor)).ToArray(); for (int i = 0; i < array.Length; i++) { NameColorManager.Add(array[i].PlayerId, __instance.PlayerId, "#ff1919"); } } break; } } } } flag &= Workhorse.OnAddTask(__instance); Utils.NotifyRoles(__instance); Utils.NotifyRoles(null, __instance); return flag; } public static void Postfix() { if (!GameStates.IsHideNSeek) { GameData.Instance.RecomputeTaskCounts(); Logger.Info($"TotalTaskCounts = {GameData.Instance.CompletedTasks}/{GameData.Instance.TotalTasks}", "CompleteTask.Postfix", escapeCRLF: true, 1622, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } } [HarmonyPatch(typeof(PlayerControl), "CheckName")] internal class PlayerControlCheckNamePatch { public static void Postfix(PlayerControl __instance, ref string playerName) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !GameStates.IsLobby) { return; } playerName = __instance.Data.PlayerName ?? playerName; if (BanManager.CheckDenyNamePlayer(__instance, playerName)) { return; } if (!Main.AllClientRealNames.ContainsKey(((InnerNetObject)__instance).OwnerId)) { Main.AllClientRealNames.Add(((InnerNetObject)__instance).OwnerId, playerName); } string str = playerName; if (Options.FormatNameMode.GetInt() == 2 && __instance.Data.ClientId != ((InnerNetClient)AmongUsClient.Instance).ClientId) { str = Main.Get_TName_Snacks; } else { str = str.RemoveHtmlTags().Replace("\\", string.Empty).Replace("/", string.Empty) .Replace("\n", string.Empty) .Replace("\r", string.Empty) .Replace("<", string.Empty) .Replace(">", string.Empty); if (str.Length > 10) { str = str.Substring(0, 10); } if (Options.DisableEmojiName.GetBool()) { str = Regex.Replace(str, "\\p{Cs}", string.Empty); } if (Regex.Replace(Regex.Replace(str, "\\s", string.Empty), "[\\x01-\\x1F,\\x7F]", string.Empty).Length < 1) { str = Main.Get_TName_Snacks; } } Main.AllPlayerNames.Remove(__instance.PlayerId); Main.AllPlayerNames.TryAdd(__instance.PlayerId, str); Logger.Info($"PlayerId: {__instance.PlayerId} - playerName: {playerName} => {str}", "Name player", escapeCRLF: true, 1658, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); RPC.SyncAllPlayerNames(); if ((Object)(object)__instance != (Object)null && !str.Equals(playerName)) { Logger.Warn("Standard nickname: " + playerName + " => " + str, "Name Format", escapeCRLF: true, 1663, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); __instance.RpcSetName(str); } new LateTask(delegate { if ((Object)(object)__instance != (Object)null && !__instance.Data.Disconnected && !__instance.IsModClient()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)81, (SendOption)1, ((InnerNetObject)__instance).OwnerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } }, 0.6f, "Retry Version Check", shoudLog: false); } } [HarmonyPatch(typeof(PlayerControl), "CmdCheckName")] internal class CmdCheckNameVersionCheckPatch { public static void Postfix(PlayerControl __instance) { RPC.RpcVersionCheck(); } } [HarmonyPatch(typeof(PlayerControl), "ProtectPlayer")] internal class PlayerControlProtectPlayerPatch { public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target) { Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + " => " + target.GetNameWithRole().RemoveHtmlTags(), "ProtectPlayer", escapeCRLF: true, 1691, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } [HarmonyPatch(typeof(PlayerControl), "RemoveProtection")] internal class PlayerControlRemoveProtectionPatch { public static void Postfix(PlayerControl __instance) { Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() ?? "", "RemoveProtection", escapeCRLF: true, 1699, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } [HarmonyPatch(typeof(PlayerControl), "MixUpOutfit")] public static class PlayerControlMixupOutfitPatch { public static void Postfix(PlayerControl __instance) { if (__instance.IsAlive() && PlayerControl.LocalPlayer.Data.Role.IsImpostor && !PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) && Main.ResetCamPlayerList.Contains(PlayerControl.LocalPlayer.PlayerId)) { __instance.cosmetics.ToggleNameVisible(false); } } } [HarmonyPatch(typeof(PlayerControl), "FixMixedUpOutfit")] public static class PlayerControlFixMixedUpOutfitPatch { public static void Postfix(PlayerControl __instance) { if (__instance.IsAlive()) { __instance.cosmetics.ToggleNameVisible(true); } } } [HarmonyPatch(typeof(PlayerControl), "CheckSporeTrigger")] public static class PlayerControlCheckSporeTriggerPatch { public static bool Prefix() { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { return !Options.DisableSporeTriggerOnFungle.GetBool(); } return true; } } [HarmonyPatch(typeof(PlayerControl), "CheckUseZipline")] public static class PlayerControlCheckUseZiplinePatch { public static bool Prefix([HarmonyArgument(2)] bool fromTop) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && Options.DisableZiplineOnFungle.GetBool()) { if (Options.DisableZiplineFromTop.GetBool() && fromTop) { return false; } if (Options.DisableZiplineFromUnder.GetBool() && !fromTop) { return false; } } return true; } } [HarmonyPatch(typeof(PlayerControl), "Die")] public static class PlayerControlDiePatch { public static void Postfix(PlayerControl __instance) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } try { if (GameStates.IsNormalGame && GameStates.IsInGame && !GameEndCheckerForNormal.ForEndGame) { CollectionExtensions.Do((IEnumerable)CustomRoleManager.AllEnabledRoles, (Action)delegate(RoleBase x) { x.OnOtherTargetsReducedToAtoms(__instance); }); RoleBase roleClass = __instance.GetRoleClass(); Action action = Utils.LateExileTask.FirstOrDefault((Action x) => x.Target is RoleBase roleBase3 && roleBase3._state.PlayerId == __instance.PlayerId) ?? new Action(roleClass.OnSelfReducedToAtoms); if (GameStates.IsInTask && !GameStates.IsExilling) { action(obj: false); Utils.LateExileTask.RemoveWhere((Action x) => x.Target is RoleBase roleBase2 && roleBase2._state.PlayerId == __instance.PlayerId); } else { Utils.LateExileTask.RemoveWhere((Action x) => x.Target is RoleBase roleBase && roleBase._state.PlayerId == __instance.PlayerId); Utils.LateExileTask.Add(action); } } } catch (Exception value) { Logger.Error($"Error after Targetreducedtoatoms: {value}", "PlayerControl.Die", escapeCRLF: true, 1793, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } __instance.RpcRemovePet(); } } [HarmonyPatch(typeof(PlayerControl), "RpcSetRole")] internal class PlayerControlSetRolePatch { public static readonly Dictionary DidSetGhost = new Dictionary(); private static readonly Dictionary ghostRoles = new Dictionary(); public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] ref RoleTypes roleType, [HarmonyArgument(1)] ref bool canOverrideRole) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek || (Object)(object)__instance == (Object)null) { return true; } if (!((Behaviour)ShipStatus.Instance).enabled || !((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } string value = __instance.GetNameWithRole().RemoveHtmlTags(); RoleTypes value2 = roleType; if (value2 - 6 <= 1) { if (DidSetGhost.TryGetValue(__instance.PlayerId, out var value3) && value3) { return false; } try { Action item = __instance.GetRoleClass().OnSelfReducedToAtoms; GhostRoleAssign.GhostAssignPatch(__instance); if (__instance.GetCustomRole().IsGhostRole()) { Utils.LateExileTask.Add(item); } } catch (Exception value4) { Logger.Warn($"Error After RpcSetRole: {value4}", "RpcSetRole.Prefix.GhostAssignPatch", escapeCRLF: true, 1828, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } bool flag = __instance.Is(Custom_Team.Impostor) || Main.ResetCamPlayerList.Contains(__instance.PlayerId); ghostRoles.Clear(); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { bool flag2 = val.PlayerId == __instance.PlayerId; bool flag3 = val.Is(Custom_Team.Impostor) || Main.ResetCamPlayerList.Contains(val.PlayerId); if (__instance.GetCustomRole().IsGhostRole() || __instance.IsAnySubRole((CustomRoles x) => x.IsGhostRole())) { ghostRoles[val] = (RoleTypes)4; } else if ((flag2 && flag) || (!flag3 && __instance.Is(Custom_Team.Impostor))) { ghostRoles[val] = (RoleTypes)7; } else { ghostRoles[val] = (RoleTypes)6; } } if (ghostRoles.All((KeyValuePair kvp) => (int)kvp.Value == 4)) { roleType = (RoleTypes)4; return true; } if (ghostRoles.All((KeyValuePair kvp) => (int)kvp.Value == 6)) { roleType = (RoleTypes)6; return true; } if (ghostRoles.All((KeyValuePair kvp) => (int)kvp.Value == 7)) { roleType = (RoleTypes)7; return true; } foreach (KeyValuePair ghostRole in ghostRoles) { ghostRole.Deconstruct(out var key, out value2); PlayerControl val2 = key; RoleTypes val3 = value2; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)__instance == (Object)null)) { Logger.Info($"Desync {value} => {val3} for {val2.GetNameWithRole().RemoveHtmlTags()}", "PlayerControl.RpcSetRole", escapeCRLF: true, 1875, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); __instance.RpcSetRoleDesync(val3, canOverride: false, val2.GetClientId()); } } return false; } return true; } public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] ref RoleTypes roleType, [HarmonyArgument(1)] ref bool canOverrideRole, bool __runOriginal) { //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Invalid comparison between Unknown and I4 //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Invalid comparison between Unknown and I4 if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (Object)(object)__instance == (Object)null) { return; } try { if ((int)roleType == 4 && !DidSetGhost.ContainsKey(__instance.PlayerId)) { Utils.NotifyRoles(null, __instance); new LateTask(delegate { //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) __instance.RpcResetAbilityCooldown(); if (Options.SendRoleDescriptionFirstMeeting.GetBool()) { PlayerControl localPlayer = PlayerControl.LocalPlayer; string playerName = localPlayer.Data.PlayerName; PlayerControl player = __instance; StringBuilder stringBuilder = new StringBuilder(); StringBuilder sb = new StringBuilder(); CustomRoles customRole = __instance.GetCustomRole(); string roleColorCode = Utils.GetRoleColorCode(customRole); stringBuilder.Append(customRole.GetRoleTitle() + player.GetRoleInfo(InfoLong: true)); if (Options.CustomRoleSpawnChances.TryGetValue(customRole, out var _)) { Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[customRole], ref sb); } string text = sb.ToString(); sb.Clear().Append($"{Translator.GetString(customRole.ToString())} {Translator.GetString("Settings:")}\n" + text + ""); CustomRpcSender customRpcSender = CustomRpcSender.Create("SendGhostRoleInfo", (SendOption)0); customRpcSender.StartMessage(__instance.GetClientId()); customRpcSender.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)6).Write(((InnerNetObject)localPlayer.Data).NetId).Write(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(customRole)), Translator.GetString("GhostTransformTitle"))) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)13).Write(stringBuilder.ToString()).EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); CustomRpcSender customRpcSender2 = CustomRpcSender.Create("SendGhostRoleConfig", (SendOption)0); customRpcSender2.StartMessage(__instance.GetClientId()); customRpcSender2.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)13).Write(sb.ToString()).EndRpc(); customRpcSender2.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)6).Write(((InnerNetObject)localPlayer.Data).NetId).Write(playerName) .EndRpc(); customRpcSender2.EndMessage(); customRpcSender2.SendMessage(); } }, 0.1f, $"SetGuardianAngel for playerId: {__instance.PlayerId}"); } if (__runOriginal) { Logger.Info($" {__instance.GetRealName()} => {roleType}", "PlayerControl.RpcSetRole", escapeCRLF: true, 1945, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); RoleTypes val = roleType; bool flag = (((int)val == 4 || val - 6 <= 1) ? true : false); if (flag && !DidSetGhost.ContainsKey(__instance.PlayerId)) { DidSetGhost.Add(__instance.PlayerId, value: true); } } } catch (Exception value) { Logger.Error($"Role Type:{roleType} - Run Original:{__runOriginal} - Error: {value}", "RpcSetRole.Postfix", escapeCRLF: true, 1954, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerControlPatch.cs"); } } } [HarmonyPatch(typeof(PlayerControl), "CoSetRole")] internal class PlayerControlLocalSetRolePatch { public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] RoleTypes role, [HarmonyArgument(1)] bool canOverrideRole) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected I4, but got Unknown if (!((InnerNetClient)AmongUsClient.Instance).AmHost && GameStates.IsNormalGame && !GameStates.IsModHost) { CustomRoles customRoles = (int)role switch { 0 => CustomRoles.CrewmateTOHE, 1 => CustomRoles.ImpostorTOHE, 2 => CustomRoles.ScientistTOHE, 3 => CustomRoles.EngineerTOHE, 5 => CustomRoles.ShapeshifterTOHE, 8 => CustomRoles.NoisemakerTOHE, 9 => CustomRoles.PhantomTOHE, 10 => CustomRoles.TrackerTOHE, _ => CustomRoles.NotAssigned, }; if (customRoles != CustomRoles.NotAssigned) { Main.PlayerStates[__instance.PlayerId].SetMainRole(customRoles); } } } } [HarmonyPatch(typeof(PlayerControl), "AssertWithTimeout")] internal class AssertWithTimeoutPatch { public static bool Prefix() { return false; } } [HarmonyPatch(typeof(AmongUsClient), "OnGameJoined")] internal class OnGameJoinedPatch { public static void Postfix(AmongUsClient __instance) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected I4, but got Unknown while (!Options.IsLoaded) { Task.Delay(1); } Logger.Info($"{((InnerNetClient)__instance).GameId} Joining room", "OnGameJoined", escapeCRLF: true, 23, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); Main.IsHostVersionCheating = false; Main.playerVersion = new Dictionary(); SoundManager.Instance.ChangeAmbienceVolume(DataManager.Settings.Audio.AmbienceVolume); Main.HostClientId = ((InnerNetClient)AmongUsClient.Instance).HostId; if (!DebugModeManager.AmDebugger && Main.VersionCheat.Value) { Main.VersionCheat.Value = false; } ChatUpdatePatch.DoBlockChat = false; GameStates.InGame = false; ErrorText.Instance.Clear(); EAC.Init(); Main.AllClientRealNames.Clear(); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { EndGameManagerPatch.IsRestarting = false; if (!RehostManager.IsAutoRehostDone) { ((InnerNetClient)AmongUsClient.Instance).ChangeGamePublic(RehostManager.ShouldPublic); RehostManager.IsAutoRehostDone = true; } Main.HostRealName = DataManager.Player.Customization.Name; if (!Main.AllClientRealNames.ContainsKey(((InnerNetClient)__instance).ClientId)) { Main.AllClientRealNames.Add(((InnerNetClient)__instance).ClientId, DataManager.Player.Customization.Name); } GameStartManagerPatch.GameStartManagerUpdatePatch.exitTimer = -1f; Main.DoBlockNameChange = false; RoleAssign.SetRoles = new Dictionary(); GhostRoleAssign.forceRole = new Dictionary(); EAC.DeNum = 0; Main.AllPlayerNames.Clear(); Main.PlayerQuitTimes.Clear(); KickPlayerPatch.AttemptedKickPlayerList = new Dictionary(); GameModes gameMode = GameOptionsManager.Instance.CurrentGameOptions.GameMode; switch ((int)gameMode) { case 1: case 3: Logger.Info(" Is Normal Game", "Game Mode", escapeCRLF: true, 67, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); if (Main.NormalOptions.KillCooldown == 0f) { Main.NormalOptions.KillCooldown = Main.LastKillCooldown.Value; } AURoleOptions.SetOpt(((Il2CppObjectBase)Main.NormalOptions).Cast()); if (AURoleOptions.ShapeshifterCooldown == 0f) { AURoleOptions.ShapeshifterCooldown = Main.LastShapeshifterCooldown.Value; } if (Options.CurrentGameMode == CustomGameMode.HidenSeekTOHE) { Options.GameMode.SetValue(0); } break; case 2: case 4: { Logger.Info(" Is Hide & Seek", "Game Mode", escapeCRLF: true, 86, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); CustomGameMode currentGameMode = Options.CurrentGameMode; if ((uint)(currentGameMode - 1) <= 1u) { Options.GameMode.SetValue(2); } break; } case 0: Logger.Info(" Is None", "Game Mode", escapeCRLF: true, 97, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); break; default: Logger.Info(" No found", "Game Mode", escapeCRLF: true, 101, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); break; } } new LateTask(delegate { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) try { if (GameStates.IsOnlineGame) { if (!GameStates.IsModHost) { RPC.RpcRequestRetryVersionCheck(); } if (BanManager.CheckEACList(PlayerControl.LocalPlayer.FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid()) && GameStates.IsOnlineGame) { AmongUsClient.Instance.ExitGame((DisconnectReasons)6); SceneChanger.ChangeScene("MainMenu"); } else { ClientData clientFromCharacter = ((InnerNetClient)AmongUsClient.Instance).GetClientFromCharacter(PlayerControl.LocalPlayer); ClientData host = ((InnerNetClient)AmongUsClient.Instance).GetHost(); if (!GameStates.IsVanillaServer) { RPC.RpcSetFriendCode(DestroyableSingleton.Instance.FriendCode); } Logger.Info($"{clientFromCharacter.PlayerName.RemoveHtmlTags()}(ClientID:{clientFromCharacter.Id}/FriendCode:{clientFromCharacter.FriendCode}/HashPuid:{clientFromCharacter.GetHashedPuid()}/Platform:{clientFromCharacter.PlatformData.Platform}) finished join room", "Session: OnGameJoined", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); Logger.Info($"{host.PlayerName.RemoveHtmlTags()}(ClientID:{host.Id}/FriendCode:{host.FriendCode}/HashPuid:{host.GetHashedPuid()}/Platform:{host.PlatformData.Platform}) is the host", "Session: OnGameJoined", escapeCRLF: true, 129, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } } } catch { Logger.Error("Error while trying to log local client data.", "OnGameJoinedPatch", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); new LateTask(delegate { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) try { if (GameStates.IsOnlineGame || GameStates.IsLocalGame) { ClientData clientFromCharacter2 = ((InnerNetClient)AmongUsClient.Instance).GetClientFromCharacter(PlayerControl.LocalPlayer); ClientData host2 = ((InnerNetClient)AmongUsClient.Instance).GetHost(); Logger.Info($"{clientFromCharacter2.PlayerName.RemoveHtmlTags()}(ClientID:{clientFromCharacter2.Id}/FriendCode:{clientFromCharacter2.FriendCode}/HashPuid:{clientFromCharacter2.GetHashedPuid()}/Platform:{clientFromCharacter2.PlatformData.Platform}) finished join room", "Session: OnGameJoined Retry", escapeCRLF: true, 141, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); Logger.Info($"{host2.PlayerName.RemoveHtmlTags()}(ClientID:{host2.Id}/FriendCode:{host2.FriendCode}/HashPuid:{host2.GetHashedPuid()}/Platform:{host2.PlatformData.Platform}) is the host", "Session: OnGameJoined Retry", escapeCRLF: true, 142, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } } catch { } }, 1.5f, "Retry Log Local Client"); } }, 0.7f, "OnGameJoinedPatch"); } } [HarmonyPatch(typeof(InnerNetClient), "DisconnectInternal")] internal class DisconnectInternalPatch { public static void Prefix(InnerNetClient __instance, DisconnectReasons reason, string stringReason) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) Logger.Info($"Disconnect (Reason:{reason}:{stringReason}, ping:{__instance.Ping})", "Reason Disconnect", escapeCRLF: true, 155, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); RehostManager.OnDisconnectInternal(reason); } } [HarmonyPatch(typeof(AmongUsClient), "OnPlayerJoined")] public static class OnPlayerJoinedPatch { public static bool IsDisconnected(this ClientData client) { AmongUsClient instance = AmongUsClient.Instance; for (int i = 0; i < ((InnerNetClient)instance).allClients.Count; i++) { if (((InnerNetClient)instance).allClients[i].Id == client.Id) { return true; } } return false; } public static bool HasInvalidFriendCode(string friendcode) { if (string.IsNullOrEmpty(friendcode)) { return true; } if (friendcode.Length < 7) { return true; } if (friendcode.Count((char c) => c == '#') != 1) { return true; } string pattern = "[\\W\\d]"; if (Regex.IsMatch(friendcode.Substring(0, friendcode.IndexOf("#")), pattern)) { return true; } return false; } public static void Postfix([HarmonyArgument(0)] ClientData client) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Invalid comparison between Unknown and I4 //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Invalid comparison between Unknown and I4 //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Invalid comparison between Unknown and I4 //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Invalid comparison between Unknown and I4 //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Invalid comparison between Unknown and I4 Logger.Info($"{client.PlayerName}(ClientID:{client.Id}/FriendCode:{client.FriendCode}/HashPuid:{client.GetHashedPuid()}/Platform:{client.PlatformData.Platform}) Joining room", "Session: OnPlayerJoined", escapeCRLF: true, 203, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); Main.AssignRolesIsStarted = false; new LateTask(delegate { try { PlayerVersion value; if (((InnerNetClient)AmongUsClient.Instance).AmHost && !client.IsDisconnected() && client.Character.Data.IsIncomplete) { Logger.SendInGame(Translator.GetString("Error.InvalidColor") + $" {client.Id}/{client.PlayerName}"); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, false); Logger.Info($"Kicked client {client.Id}/{client.PlayerName} bcz PlayerControl is not spawned in time.", "OnPlayerJoinedPatchPostfix", escapeCRLF: true, 215, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } else if (((InnerNetClient)AmongUsClient.Instance).AmHost && !Main.playerVersion.TryGetValue(client.Id, out value)) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)81, (SendOption)0, client.Id); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } catch { } }, 3f, "green bean kick late task", shoudLog: false); if (((InnerNetClient)AmongUsClient.Instance).AmHost && HasInvalidFriendCode(client.FriendCode) && Options.KickPlayerFriendCodeInvalid.GetBool() && !GameStates.IsLocalGame) { if (!Options.TempBanPlayerFriendCodeInvalid.GetBool()) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, false); Logger.SendInGame(string.Format(Translator.GetString("Message.KickedByInvalidFriendCode"), client.PlayerName)); ClientData obj = client; Logger.Info("Kicked a player " + ((obj != null) ? obj.PlayerName : null) + " because of invalid friend code", "Kick", escapeCRLF: true, 235, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } else { if (!BanManager.TempBanWhiteList.Contains(client.GetHashedPuid())) { BanManager.TempBanWhiteList.Add(client.GetHashedPuid()); } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, true); Logger.SendInGame(string.Format(Translator.GetString("Message.TempBannedByInvalidFriendCode"), client.PlayerName)); ClientData obj2 = client; Logger.Info("TempBanned a player " + ((obj2 != null) ? obj2.PlayerName : null) + " because of invalid friend code", "Temp Ban", escapeCRLF: true, 243, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } } if (Options.AllowOnlyWhiteList.GetBool()) { ClientData obj3 = client; if (!BanManager.CheckAllowList((obj3 != null) ? obj3.FriendCode : null) && !GameStates.IsLocalGame) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, false); Logger.SendInGame(string.Format(Translator.GetString("Message.KickedByWhiteList"), client.PlayerName)); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(60, 2); defaultInterpolatedStringHandler.AppendLiteral("Kicked player "); ClientData obj4 = client; defaultInterpolatedStringHandler.AppendFormatted((obj4 != null) ? obj4.PlayerName : null); defaultInterpolatedStringHandler.AppendLiteral(", because friendcode: "); ClientData obj5 = client; defaultInterpolatedStringHandler.AppendFormatted((obj5 != null) ? obj5.FriendCode : null); defaultInterpolatedStringHandler.AppendLiteral(" is not in WhiteList.txt"); Logger.Warn(defaultInterpolatedStringHandler.ToStringAndClear(), "Kick", escapeCRLF: true, 251, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } } Platforms platform = client.PlatformData.Platform; if (((InnerNetClient)AmongUsClient.Instance).AmHost && Options.KickOtherPlatformPlayer.GetBool() && (int)platform != 0 && !GameStates.IsLocalGame && (((int)platform == 7 && Options.OptKickAndroidPlayer.GetBool()) || ((int)platform == 6 && Options.OptKickIphonePlayer.GetBool()) || ((int)platform == 9 && Options.OptKickXboxPlayer.GetBool()) || ((int)platform == 10 && Options.OptKickPlayStationPlayer.GetBool()) || ((int)platform == 8 && Options.OptKickNintendoPlayer.GetBool()))) { string @string = Translator.GetString("MsgKickOtherPlatformPlayer"); ClientData obj6 = client; string text = string.Format(@string, (obj6 != null) ? obj6.PlayerName : null, ((object)(Platforms)(ref platform)).ToString()); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, false); Logger.SendInGame(text); Logger.Info(text, "Other Platform Kick", escapeCRLF: true, 266, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } if (DestroyableSingleton.Instance.IsPlayerBlockedUsername(client.FriendCode) && ((InnerNetClient)AmongUsClient.Instance).AmHost) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, true); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(32, 2); defaultInterpolatedStringHandler.AppendLiteral("Ban Player ー "); ClientData obj7 = client; defaultInterpolatedStringHandler.AppendFormatted((obj7 != null) ? obj7.PlayerName : null); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(client.FriendCode); defaultInterpolatedStringHandler.AppendLiteral(") has been banned."); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "BAN", escapeCRLF: true, 272, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } BanManager.CheckBanPlayer(client); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if (Main.SayStartTimes.ContainsKey(client.Id)) { Main.SayStartTimes.Remove(client.Id); } if (Main.SayBanwordsTimes.ContainsKey(client.Id)) { Main.SayBanwordsTimes.Remove(client.Id); } if (client.GetHashedPuid() != "" && Options.TempBanPlayersWhoKeepQuitting.GetBool() && !BanManager.CheckAllowList(client.FriendCode) && !GameStates.IsLocalGame && Main.PlayerQuitTimes.ContainsKey(client.GetHashedPuid()) && Main.PlayerQuitTimes[client.GetHashedPuid()] >= Options.QuitTimesTillTempBan.GetInt()) { if (!BanManager.TempBanWhiteList.Contains(client.GetHashedPuid())) { BanManager.TempBanWhiteList.Add(client.GetHashedPuid()); } ((InnerNetClient)AmongUsClient.Instance).KickPlayer(client.Id, true); Logger.SendInGame(string.Format(Translator.GetString("Message.TempBannedForSpamQuitting"), client.PlayerName)); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(42, 2); defaultInterpolatedStringHandler.AppendLiteral("Temp Ban Player ー "); ClientData obj8 = client; defaultInterpolatedStringHandler.AppendFormatted((obj8 != null) ? obj8.PlayerName : null); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(client.FriendCode); defaultInterpolatedStringHandler.AppendLiteral(") has been temp banned."); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "BAN", escapeCRLF: true, 293, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } } } [HarmonyPatch(typeof(AmongUsClient), "OnPlayerLeft")] internal class OnPlayerLeftPatch { public static bool StartingProcessing; private static void Prefix([HarmonyArgument(0)] ClientData data) { StartingProcessing = true; if (GameStates.IsInGame) { Main.PlayerStates[data.Character.PlayerId].Disconnected = true; } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if (Main.AssignRolesIsStarted) { Logger.Warn($"Assign roles not ended, try remove player {data.Character.PlayerId} from role assign", "OnPlayerLeft", escapeCRLF: true, 317, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); RoleAssign.RoleResult?.Remove(data.Character); SelectRolesPatch.RpcSetRoleReplacer.senders?.Remove(data.Character.PlayerId); SelectRolesPatch.RpcSetRoleReplacer.StoragedData?.Remove(data.Character); } if (GameStates.IsNormalGame && GameStates.IsInGame) { MurderPlayerPatch.AfterPlayerDeathTasks((data != null) ? data.Character : null, (data != null) ? data.Character : null, GameStates.IsMeeting); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !((Object)(object)data.Character != (Object)null)) { return; } for (int i = 0; i < Main.MessagesToSend.Count; i++) { byte item = Main.MessagesToSend[i].Item2; if (item == data.Character.PlayerId) { Main.MessagesToSend.RemoveAt(i); i--; } } uint netid = ((InnerNetObject)data.Character).NetId; new LateTask(delegate { if (GameStates.IsOnlineGame && ((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter obj = ((Il2CppArrayBase)(object)((InnerNetClient)AmongUsClient.Instance).Streams)[1]; obj.StartMessage((byte)5); obj.WritePacked(netid); obj.EndMessage(); } }, 2.5f, "Repeat Despawn", shoudLog: false); } public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ClientData data, [HarmonyArgument(1)] DisconnectReasons reason) { //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Invalid comparison between Unknown and I4 //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Invalid comparison between Unknown and I4 //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_06b7: Unknown result type (might be due to invalid IL or missing references) //IL_06bc: Unknown result type (might be due to invalid IL or missing references) //IL_06be: Unknown result type (might be due to invalid IL or missing references) //IL_06c1: Unknown result type (might be due to invalid IL or missing references) //IL_06c3: Invalid comparison between Unknown and I4 try { if (GameStates.IsNormalGame && GameStates.IsInGame) { CustomRoleManager.AllEnabledRoles.ForEach(delegate(RoleBase r) { r.OnOtherTargetsReducedToAtoms(data.Character); }); if (data.Character.Is(CustomRoles.Lovers) && !data.Character.Data.IsDead) { PlayerControl[] array = Main.LoversPlayers.ToArray(); foreach (PlayerControl val in array) { Main.isLoversDead = true; Main.LoversPlayers.Remove(val); Main.PlayerStates[val.PlayerId].RemoveSubRole(CustomRoles.Lovers); } } if (Spiritualist.HasEnabled) { Spiritualist.RemoveTarget(data.Character.PlayerId); } Main.PlayerStates[data.Character.PlayerId].Disconnected = true; Main.PlayerStates[data.Character.PlayerId].SetDead(); if (data.Character.Notifying()) { NameNotifyManager.Notice.Remove(data.Character.PlayerId); } AntiBlackout.OnDisconnect(data.Character.Data); PlayerGameOptionsSender.RemoveSender(data.Character); } if (Main.HostClientId != data.Id && Main.playerVersion.ContainsKey(data.Id)) { Main.playerVersion.Remove(data.Id); } if (Main.HostClientId == data.Id && Main.playerVersion.ContainsKey(data.Id)) { int targetClientId = -1; PlayerControl localPlayer = PlayerControl.LocalPlayer; string text = "" + Translator.GetString("DefaultSystemMessageTitle") + ""; object obj; if (localPlayer == null) { obj = null; } else { NetworkedPlayerInfo data2 = localPlayer.Data; obj = ((data2 != null) ? data2.PlayerName : null); } string name = (string)obj; string text2 = ""; if (GameStates.IsInGame) { Utils.ErrorEnd("Host exits the game"); text2 = Translator.GetString("Message.HostLeftGameInGame"); } else if (GameStates.IsLobby) { text2 = Translator.GetString("Message.HostLeftGameInLobby"); } localPlayer.SetName(text); DestroyableSingleton.Instance.Chat.AddChat(localPlayer, text2, true); localPlayer.SetName(name); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(targetClientId); customRpcSender.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)6).Write(((InnerNetObject)localPlayer.Data).NetId).Write(text) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)13).Write(text2).EndRpc(); customRpcSender.StartRpc(((InnerNetObject)localPlayer).NetId, (byte)6).Write(((InnerNetObject)localPlayer.Data).NetId).Write(localPlayer.Data.PlayerName) .EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } Main.HostClientId = ((InnerNetClient)AmongUsClient.Instance).HostId; new LateTask(delegate { if (GameStates.IsOnlineGame) { if (Main.playerVersion.ContainsKey(((InnerNetClient)AmongUsClient.Instance).HostId)) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Utils.SendMessage(string.Format(Translator.GetString("Message.HostLeftGameNewHostIsMod"), ((InnerNetClient)AmongUsClient.Instance).GetHost().Character?.GetRealName() ?? "null")); } } else { PlayerControl localPlayer2 = PlayerControl.LocalPlayer; string name2 = "" + Translator.GetString("DefaultSystemMessageTitle") + ""; object obj9; if (localPlayer2 == null) { obj9 = null; } else { NetworkedPlayerInfo data3 = localPlayer2.Data; obj9 = ((data3 != null) ? data3.PlayerName : null); } string name3 = (string)obj9; string text3 = string.Format(Translator.GetString("Message.HostLeftGameNewHostIsNotMod"), ((InnerNetClient)AmongUsClient.Instance).GetHost().Character?.GetRealName() ?? "null"); localPlayer2.SetName(name2); DestroyableSingleton.Instance.Chat.AddChat(localPlayer2, text3, true); localPlayer2.SetName(name3); } } }, 0.5f, "On Host Disconnected"); } if ((int)reason != 10) { if ((int)reason == 17) { string @string = Translator.GetString("PlayerLeftByError"); ClientData obj2 = data; Logger.SendInGame(string.Format(@string, (obj2 != null) ? obj2.PlayerName : null)); new LateTask(delegate { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); ((Behaviour)GameManager.Instance).enabled = false; GameManager.Instance.RpcEndGame((GameOverReason)5, false); }, 3f, "Disconnect Error Auto-end"); } } else { string string2 = Translator.GetString("PlayerLeftByAU-Anticheat"); ClientData obj3 = data; Logger.SendInGame(string.Format(string2, (obj3 != null) ? obj3.PlayerName : null)); } DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(79, 7); ClientData obj4 = data; defaultInterpolatedStringHandler.AppendFormatted((obj4 != null) ? obj4.PlayerName : null); defaultInterpolatedStringHandler.AppendLiteral(" - (ClientID:"); ClientData obj5 = data; defaultInterpolatedStringHandler.AppendFormatted((obj5 != null) ? new int?(obj5.Id) : null); defaultInterpolatedStringHandler.AppendLiteral(" / FriendCode:"); ClientData obj6 = data; defaultInterpolatedStringHandler.AppendFormatted((obj6 != null) ? obj6.FriendCode : null); defaultInterpolatedStringHandler.AppendLiteral(" / HashPuid:"); defaultInterpolatedStringHandler.AppendFormatted(data?.GetHashedPuid()); defaultInterpolatedStringHandler.AppendLiteral(" / Platform:"); ClientData obj7 = data; defaultInterpolatedStringHandler.AppendFormatted((obj7 != null) ? new Platforms?(obj7.PlatformData.Platform) : null); defaultInterpolatedStringHandler.AppendLiteral(") Disconnect (Reason:"); defaultInterpolatedStringHandler.AppendFormatted(reason); defaultInterpolatedStringHandler.AppendLiteral(",Ping:"); defaultInterpolatedStringHandler.AppendFormatted(((InnerNetClient)AmongUsClient.Instance).Ping); defaultInterpolatedStringHandler.AppendLiteral(")"); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Session OnPlayerLeftPatch", escapeCRLF: true, 469, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); if (Main.AssignRolesIsStarted) { Utils.ErrorEnd("The player left the game during assigning roles"); } if (data != null) { Main.playerVersion.Remove(data.Id); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Main.SayStartTimes.Remove(((InnerNetClient)__instance).ClientId); Main.SayBanwordsTimes.Remove(((InnerNetClient)__instance).ClientId); if (GameStates.IsLobby && !GameStates.IsLocalGame && data?.GetHashedPuid() != "" && Options.TempBanPlayersWhoKeepQuitting.GetBool()) { ClientData obj8 = data; if (!BanManager.CheckAllowList((obj8 != null) ? obj8.FriendCode : null)) { if (!Main.PlayerQuitTimes.ContainsKey(data?.GetHashedPuid())) { Main.PlayerQuitTimes.Add(data?.GetHashedPuid(), 1); } else { Main.PlayerQuitTimes[data?.GetHashedPuid()]++; } if (Main.PlayerQuitTimes[data?.GetHashedPuid()] >= Options.QuitTimesTillTempBan.GetInt()) { BanManager.TempBanWhiteList.Add(data?.GetHashedPuid()); } } } if (GameStates.IsMeeting) { Swapper.CheckSwapperTarget(data.Character.PlayerId); VoteStates state = MeetingHud.Instance.state; if (state - 1 <= 2) { MeetingHud.Instance.CheckForEndVoting(); } } } } catch (Exception ex) { Logger.Error(ex.ToString(), "OnPlayerLeftPatch.Postfix", escapeCRLF: true, 517, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } StartingProcessing = false; } } [HarmonyPatch(typeof(InnerNetClient), "Spawn")] internal class InnerNetClientSpawnPatch { public static void Postfix([HarmonyArgument(1)] int ownerId, [HarmonyArgument(2)] SpawnFlags flags) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (int)flags != 1) { return; } ClientData client = Utils.GetClientById(ownerId); Logger.Msg($"Spawn player data: ID {ownerId}: {client.PlayerName}", "InnerNetClientSpawn", escapeCRLF: true, 533, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); if (client == null || (Object)(object)client.Character == (Object)null || client.ColorId < 0 || ((Il2CppArrayBase)(object)Palette.PlayerColors).Length <= client.ColorId) { Logger.Warn("client is null or client have invalid color", "TrySyncAndSendMessage", escapeCRLF: true, 538, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } else { new LateTask(delegate { OptionItem.SyncAllOptions(client.Id); }, 3f, "Sync All Options For New Player"); new LateTask(delegate { if (Main.OverrideWelcomeMsg != "") { Utils.SendMessage(Main.OverrideWelcomeMsg, client.Character.PlayerId); } else { TemplateManager.SendTemplate("welcome", client.Character.PlayerId, noErr: true); } }, 3f, "Welcome Message"); new LateTask(delegate { if (client == null || (Object)(object)client.Character == (Object)null) { Logger.Warn("client is null", "Spawn.RPCRequestRetryVersionCheck", escapeCRLF: true, 557, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\PlayerJoinAndLeftPatch.cs"); } else { MessageWriter val3 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)81, (SendOption)1, ((InnerNetObject)client.Character).OwnerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val3); } }, 3f, "RPC Request Retry Version Check"); if (GameStates.IsOnlineGame) { new LateTask(delegate { if (GameStates.IsLobby && (Object)(object)client.Character != (Object)null && (Object)(object)LobbyBehaviour.Instance != (Object)null && GameStates.IsVanillaServer) { if (!((InnerNetObject)(object)client.Character).OwnedByHost() && !client.Character.IsModClient()) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)LobbyBehaviour.Instance).NetId, (byte)60, (SendOption)0, client.Id); val.WritePacked((int)GameStartManagerPatch.timer); val.Write(false); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else if (!((InnerNetObject)(object)client.Character).OwnedByHost() && client.Character.IsModClient()) { MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)124, (SendOption)1, client.Id); val2.WritePacked((int)GameStartManagerPatch.timer); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); } } }, 3.1f, "Send RPC or Sync Lobby Timer"); } if (Options.GradientTagsOpt.GetBool()) { new LateTask(delegate { Utils.SendMessage(Translator.GetString("Warning.GradientTags"), client.Character.PlayerId); }, 3.3f, "GradientWarning"); } } Main.GuessNumber[client.Character.PlayerId] = new List(2) { -1, 7 }; if (!(Main.OverrideWelcomeMsg == "") || Main.PlayerStates.Count == 0 || !Main.clientIdList.Contains(client.Id) || !GameStates.IsNormalGame) { return; } if (Options.AutoDisplayKillLog.GetBool() && Main.PlayerStates.Count != 0 && Main.clientIdList.Contains(client.Id)) { new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (Object)(object)client.Character != (Object)null) { Main.isChatCommand = true; Utils.ShowKillLog(client.Character.PlayerId); } }, 3f, "DisplayKillLog"); } if (Options.AutoDisplayLastRoles.GetBool()) { new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (Object)(object)client.Character != (Object)null) { Main.isChatCommand = true; Utils.ShowLastRoles(client.Character.PlayerId); } }, 3.1f, "DisplayLastRoles"); } if (Options.AutoDisplayLastResult.GetBool()) { new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (Object)(object)client.Character != (Object)null) { Main.isChatCommand = true; Utils.ShowLastResult(client.Character.PlayerId); } }, 3.2f, "DisplayLastResult"); } if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp || !Options.EnableUpMode.GetBool()) { return; } new LateTask(delegate { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted && (Object)(object)client.Character != (Object)null) { Main.isChatCommand = true; } }, 3.3f, "DisplayUpWarnning"); } } internal class RandomSpawn { [HarmonyPatch(typeof(CustomNetworkTransform), "HandleRpc")] public class CustomNetworkTransformHandleRpcPatch { private static readonly HashSet<(int x, int y)> decupleVanillaSpawnPositions = new HashSet<(int, int)> { (-7, 85), (-7, -10), (-70, -115), (335, -15), (200, 105), (155, 0) }; public static bool Prefix(CustomNetworkTransform __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (!((Behaviour)__instance).isActiveAndEnabled) { return false; } if (callId == 21 && GameStates.AirshipIsActive) { PlayerControl myPlayer = __instance.myPlayer; if (!Main.PlayerStates[myPlayer.PlayerId].HasSpawned) { MessageReader obj = MessageReader.Get(reader); Vector2 val = NetHelpers.ReadVector2(obj); obj.Recycle(); Logger.Info($"SnapTo: {myPlayer.GetRealName()}, ({val.x}, {val.y})", "RandomSpawn", escapeCRLF: true, 37, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\RandomSpawnPatch.cs"); if (IsAirshipVanillaSpawnPosition(val)) { AirshipSpawn(myPlayer); return !IsRandomSpawn(); } Logger.Info("Position is not a spring position", "RandomSpawn", escapeCRLF: true, 47, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\RandomSpawnPatch.cs"); } } return true; } private static bool IsAirshipVanillaSpawnPosition(Vector2 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) float num = position.x * 10f; float num2 = position.y * 10f; int num3 = Mathf.RoundToInt(num); if (Mathf.Abs((float)num3 - num) >= 0.09f) { return false; } int num4 = Mathf.RoundToInt(num2); if (Mathf.Abs((float)num4 - num2) >= 0.09f) { return false; } (int, int) item = (num3, num4); return decupleVanillaSpawnPositions.Contains(item); } } [HarmonyPatch(typeof(SpawnInMinigame), "SpawnAt")] public static class SpawnInMinigameSpawnAtPatch { public static bool Prefix(SpawnInMinigame __instance, [HarmonyArgument(0)] SpawnLocation spawnPoint) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if ((int)((Minigame)__instance).amClosing != 0) { return false; } if (IsRandomSpawn()) { __instance.gotButton = true; PlayerControl.LocalPlayer.SetKinematic(true); PlayerControl.LocalPlayer.NetTransform.SetPaused(true); AirshipSpawn(PlayerControl.LocalPlayer); DestroyableSingleton.Instance.PlayerCam.SnapToTarget(); ((MonoBehaviour)__instance).StopAllCoroutines(); ((MonoBehaviour)__instance).StartCoroutine(__instance.CoSpawnAt(PlayerControl.LocalPlayer, spawnPoint)); return false; } AirshipSpawn(PlayerControl.LocalPlayer); return true; } } private enum RandomSpawnOpt { RandomSpawnMode, RandomSpawn_SpawnRandomLocation, RandomSpawn_AirshipAdditionalSpawn, RandomSpawn_SpawnRandomVents } public abstract class SpawnMap { public abstract Dictionary Positions { get; } public virtual void RandomTeleport(PlayerControl player) { Teleport(player, isRadndom: true); } public virtual void FirstTeleport(PlayerControl player) { Teleport(player, isRadndom: false); } private void Teleport(PlayerControl player, bool isRadndom) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) int num; if (isRadndom && Options.CurrentGameMode != CustomGameMode.FFA) { num = (SpawnRandomLocation.GetBool() ? 1 : 2); if (SpawnRandomLocation.GetBool() && SpawnRandomVents.GetBool()) { num = IRandom.Instance.Next(1, 3); } else if (!SpawnRandomLocation.GetBool() && !SpawnRandomVents.GetBool()) { num = 0; } } else { num = 1; } if (num == 1) { Vector2 location = GetLocation(!isRadndom); Logger.Info($"{player.Data.PlayerName}:{location}", "RandomSpawnInLocation", escapeCRLF: true, 211, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\RandomSpawnPatch.cs"); player.RpcTeleport(location, isRandomSpawn: true); } else { Logger.Info(player.Data.PlayerName ?? "", "RandomSpawnInVent", escapeCRLF: true, 216, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\RandomSpawnPatch.cs"); player.RpcRandomVentTeleport(); } } public Vector2 GetLocation(bool first = false) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) KeyValuePair[] array = Positions.ToArray(); if (first) { return array[0].Value; } KeyValuePair keyValuePair = (from _ in array.ToArray() orderby Guid.NewGuid() select _).Take(1).FirstOrDefault(); if (GameStates.AirshipIsActive && !AirshipAdditionalSpawn.GetBool()) { keyValuePair = array.ToArray()[0..6].OrderBy((KeyValuePair _) => Guid.NewGuid()).Take(1).FirstOrDefault(); } return keyValuePair.Value; } } public class SkeldSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new Dictionary { ["Cafeteria"] = new Vector2(-1f, 3f), ["Weapons"] = new Vector2(9.3f, 1f), ["O2"] = new Vector2(6.5f, -3.8f), ["Navigation"] = new Vector2(16.5f, -4.8f), ["Shields"] = new Vector2(9.3f, -12.3f), ["Communications"] = new Vector2(4f, -15.5f), ["Storage"] = new Vector2(-1.5f, -15.5f), ["Admin"] = new Vector2(4.5f, -7.9f), ["Electrical"] = new Vector2(-7.5f, -8.8f), ["LowerEngine"] = new Vector2(-17f, -13.5f), ["UpperEngine"] = new Vector2(-17f, -1.3f), ["Security"] = new Vector2(-13.5f, -5.5f), ["Reactor"] = new Vector2(-20.5f, -5.5f), ["MedBay"] = new Vector2(-9f, -4f) }; } public class MiraHQSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new Dictionary { ["Cafeteria"] = new Vector2(25.5f, 2f), ["Balcony"] = new Vector2(24f, -2f), ["Storage"] = new Vector2(19.5f, 4f), ["ThreeWay"] = new Vector2(17.8f, 11.5f), ["Communications"] = new Vector2(15.3f, 3.8f), ["MedBay"] = new Vector2(15.5f, -0.5f), ["LockerRoom"] = new Vector2(9f, 1f), ["Decontamination"] = new Vector2(6.1f, 6f), ["Laboratory"] = new Vector2(9.5f, 12f), ["Reactor"] = new Vector2(2.5f, 10.5f), ["Launchpad"] = new Vector2(-4.5f, 2f), ["Admin"] = new Vector2(21f, 17.5f), ["Office"] = new Vector2(15f, 19f), ["Greenhouse"] = new Vector2(17.8f, 23f) }; } public class PolusSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new Dictionary { ["OfficeLeft"] = new Vector2(19.5f, -18f), ["OfficeRight"] = new Vector2(26f, -17f), ["Admin"] = new Vector2(24f, -22.5f), ["Communications"] = new Vector2(12.5f, -16f), ["Weapons"] = new Vector2(12f, -23.5f), ["BoilerRoom"] = new Vector2(2.3f, -24f), ["O2"] = new Vector2(2f, -17.5f), ["Electrical"] = new Vector2(9.5f, -12.5f), ["Security"] = new Vector2(3f, -12f), ["Dropship"] = new Vector2(16.7f, -3f), ["Storage"] = new Vector2(20.5f, -12f), ["Rocket"] = new Vector2(26.7f, -8.5f), ["Laboratory"] = new Vector2(36.5f, -7.5f), ["Toilet"] = new Vector2(34f, -10f), ["SpecimenRoom"] = new Vector2(36.5f, -22f) }; } public class DleksSpawnMap : SpawnMap { public static Dictionary TempPositions = ((IEnumerable>)new SkeldSpawnMap().Positions).ToDictionary((Func, string>)((KeyValuePair e) => e.Key), (Func, Vector2>)((KeyValuePair e) => new Vector2(0f - e.Value.x, e.Value.y))); public override Dictionary Positions { get; } = TempPositions; } public class AirshipSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new Dictionary { ["Brig"] = new Vector2(-0.7f, 8.5f), ["Engine"] = new Vector2(-0.7f, -1f), ["Kitchen"] = new Vector2(-7f, -11.5f), ["CargoBay"] = new Vector2(33.5f, -1.5f), ["Records"] = new Vector2(20f, 10.5f), ["MainHall"] = new Vector2(15.5f, 0f), ["NapRoom"] = new Vector2(6.3f, 2.5f), ["MeetingRoom"] = new Vector2(17.1f, 14.9f), ["GapRoom"] = new Vector2(12f, 8.5f), ["Vault"] = new Vector2(-8.9f, 12.2f), ["Communications"] = new Vector2(-13.3f, 1.3f), ["Cockpit"] = new Vector2(-23.5f, -1.6f), ["Armory"] = new Vector2(-10.3f, -5.9f), ["ViewingDeck"] = new Vector2(-13.7f, -12.6f), ["Security"] = new Vector2(5.8f, -10.8f), ["Electrical"] = new Vector2(16.3f, -8.8f), ["Medical"] = new Vector2(29f, -6.2f), ["Toilet"] = new Vector2(30.9f, 6.8f), ["Showers"] = new Vector2(21.2f, -0.8f) }; } public class FungleSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new Dictionary { ["FirstSpawn"] = new Vector2(-9.8f, 3.4f), ["Dropship"] = new Vector2(-7.8f, 10.6f), ["Cafeteria"] = new Vector2(-16.4f, 7.3f), ["SplashZone"] = new Vector2(-15.6f, -1.8f), ["Shore"] = new Vector2(-22.8f, -0.6f), ["Kitchen"] = new Vector2(-15.5f, -7.5f), ["Dock"] = new Vector2(-23.1f, -7f), ["Storage"] = new Vector2(1.7f, 4.4f), ["MeetingRoom"] = new Vector2(-3f, -2.6f), ["TheDorm"] = new Vector2(2.6f, -1.3f), ["Laboratory"] = new Vector2(-4.3f, -8.6f), ["Jungle"] = new Vector2(0.8f, -11.7f), ["Greenhouse"] = new Vector2(9.3f, -9.8f), ["Reactor"] = new Vector2(22.3f, -7f), ["Lookout"] = new Vector2(9.5f, 1.2f), ["MiningPit"] = new Vector2(12.6f, 9.8f), ["UpperEngine"] = new Vector2(22.4f, 3.4f), ["Communications"] = new Vector2(22.2f, 13.7f) }; } private static OptionItem RandomSpawnMode; private static OptionItem SpawnRandomLocation; private static OptionItem AirshipAdditionalSpawn; private static OptionItem SpawnRandomVents; public static void AirshipSpawn(PlayerControl player) { Logger.Info("Spawn: " + player.GetRealName(), "RandomSpawn", escapeCRLF: true, 124, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\RandomSpawnPatch.cs"); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (player.GetRoleClass() is Penguin penguin) { penguin.OnSpawnAirship(); } if (GameStates.IsNormalGame) { player.RpcResetAbilityCooldown(); } if (IsRandomSpawn()) { new AirshipSpawnMap().RandomTeleport(player); } else if (player.Is(CustomRoles.GM)) { new AirshipSpawnMap().FirstTeleport(player); } } Main.PlayerStates[player.PlayerId].HasSpawned = true; } public static bool IsRandomSpawn() { return RandomSpawnMode.GetBool(); } public static void SetupCustomOption() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) RandomSpawnMode = BooleanOptionItem.Create(60470, RandomSpawnOpt.RandomSpawnMode, defaultValue: false, TabGroup.ModSettings, isSingleValue: false).HideInFFA().SetColor(Color32.op_Implicit(new Color32((byte)19, (byte)188, (byte)233, byte.MaxValue))); SpawnRandomLocation = BooleanOptionItem.Create(60471, RandomSpawnOpt.RandomSpawn_SpawnRandomLocation, defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomSpawnMode); AirshipAdditionalSpawn = BooleanOptionItem.Create(60472, RandomSpawnOpt.RandomSpawn_AirshipAdditionalSpawn, defaultValue: true, TabGroup.ModSettings, isSingleValue: false).SetParent(SpawnRandomLocation); SpawnRandomVents = BooleanOptionItem.Create(60475, RandomSpawnOpt.RandomSpawn_SpawnRandomVents, defaultValue: false, TabGroup.ModSettings, isSingleValue: false).SetParent(RandomSpawnMode); } } [HarmonyPatch(typeof(GameData), "RecomputeTaskCounts")] internal class CustomTaskCountsPatch { public static bool Prefix(GameData __instance) { if (GameStates.IsHideNSeek) { return true; } __instance.TotalTasks = 0; __instance.CompletedTasks = 0; Enumerator enumerator = __instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { NetworkedPlayerInfo current = enumerator.Current; if ((Object)(object)current == (Object)null || !Utils.HasTasks(current) || Main.PlayerStates[current.PlayerId].TaskState.AllTasksCount <= 0) { continue; } Enumerator enumerator2 = current.Tasks.GetEnumerator(); while (enumerator2.MoveNext()) { TaskInfo current2 = enumerator2.Current; int totalTasks = __instance.TotalTasks; __instance.TotalTasks = totalTasks + 1; if (current2.Complete) { totalTasks = __instance.CompletedTasks; __instance.CompletedTasks = totalTasks + 1; } } } return false; } } public class SabotageSystemPatch { [HarmonyPatch(typeof(ReactorSystemType), "Deteriorate")] private static class ReactorSystemTypePatch { private static void Prefix(ReactorSystemType __instance) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected I4, but got Unknown if (!Options.SabotageTimeControl.GetBool() || GameStates.AirshipIsActive) { return; } if (!__instance.IsActive || !SetDurationForReactorSabotage) { if (!SetDurationForReactorSabotage && !__instance.IsActive) { SetDurationForReactorSabotage = true; } return; } Logger.Info($" {ShipStatus.Instance.Type}", "ReactorSystemTypePatch - ShipStatus.Instance.Type", escapeCRLF: true, 37, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); Logger.Info($" {SetDurationForReactorSabotage}", "ReactorSystemTypePatch - SetDurationCriticalSabotage", escapeCRLF: true, 38, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); SetDurationForReactorSabotage = false; MapType type = ShipStatus.Instance.Type; switch ((int)type) { case 0: __instance.Countdown = Options.SkeldReactorTimeLimit.GetFloat(); break; case 1: __instance.Countdown = Options.MiraReactorTimeLimit.GetFloat(); break; case 2: __instance.Countdown = Options.PolusReactorTimeLimit.GetFloat(); break; case 3: __instance.Countdown = Options.FungleReactorTimeLimit.GetFloat(); break; } } } [HarmonyPatch(typeof(HeliSabotageSystem), "Deteriorate")] private static class HeliSabotageSystemPatch { private static void Prefix(HeliSabotageSystem __instance) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (!Options.SabotageTimeControl.GetBool() || !GameStates.AirshipIsActive) { return; } if (!__instance.IsActive || (Object)(object)ShipStatus.Instance == (Object)null || !SetDurationForReactorSabotage) { if (!SetDurationForReactorSabotage && !__instance.IsActive) { SetDurationForReactorSabotage = true; } return; } Logger.Info($" {ShipStatus.Instance.Type}", "HeliSabotageSystemPatch - ShipStatus.Instance.Type", escapeCRLF: true, 79, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); Logger.Info($" {SetDurationForReactorSabotage}", "HeliSabotageSystemPatch - SetDurationCriticalSabotage", escapeCRLF: true, 80, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); SetDurationForReactorSabotage = false; __instance.Countdown = Options.AirshipReactorTimeLimit.GetFloat(); } } [HarmonyPatch(typeof(LifeSuppSystemType), "Deteriorate")] private static class LifeSuppSystemTypePatch { private static void Prefix(LifeSuppSystemType __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Invalid comparison between Unknown and I4 if (!Options.SabotageTimeControl.GetBool()) { return; } MapNames activeMapName = Utils.GetActiveMapName(); if (((int)activeMapName == 2 || activeMapName - 4 <= 1) ? true : false) { return; } if (!__instance.IsActive || !SetDurationForO2Sabotage) { if (!SetDurationForO2Sabotage && !__instance.IsActive) { SetDurationForO2Sabotage = true; } return; } Logger.Info($" {ShipStatus.Instance.Type}", "LifeSuppSystemType - ShipStatus.Instance.Type", escapeCRLF: true, 105, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); Logger.Info($" {SetDurationForO2Sabotage}", "LifeSuppSystemType - SetDurationCriticalSabotage", escapeCRLF: true, 106, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); SetDurationForO2Sabotage = false; MapType type = ShipStatus.Instance.Type; if ((int)type != 0) { if ((int)type == 1) { __instance.Countdown = Options.MiraO2TimeLimit.GetFloat(); } } else { __instance.Countdown = Options.SkeldO2TimeLimit.GetFloat(); } } } [HarmonyPatch(typeof(MushroomMixupSabotageSystem), "UpdateSystem")] public static class MushroomMixupSabotageSystemUpdateSystemPatch { public static void Postfix() { Logger.Info(" IsActive", "MushroomMixupSabotageSystem.UpdateSystem.Postfix", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl player) => !player.Is(Custom_Team.Impostor) && Main.ResetCamPlayerList.Contains(player.PlayerId)).ToArray(); for (int i = 0; i < array.Length; i++) { Utils.NotifyRoles(array[i], null, isForMeeting: false, NoCache: false, ForceLoop: true, CamouflageIsForMeeting: false, MushroomMixupIsActive: true); } } } [HarmonyPatch(typeof(MushroomMixupSabotageSystem), "Deteriorate")] private static class MushroomMixupSabotageSystemPatch { private static void Prefix(MushroomMixupSabotageSystem __instance, ref bool __state) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) __state = __instance.IsActive; if (!Options.SabotageTimeControl.GetBool() || !GameStates.FungleIsActive) { return; } if (!__instance.IsActive || !SetDurationMushroomMixupSabotage) { if (!SetDurationMushroomMixupSabotage && !__instance.IsActive) { SetDurationMushroomMixupSabotage = true; } return; } Logger.Info($" {ShipStatus.Instance.Type}", "MushroomMixupSabotageSystem - ShipStatus.Instance.Type", escapeCRLF: true, 157, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); Logger.Info($" {SetDurationMushroomMixupSabotage}", "MushroomMixupSabotageSystem - SetDurationCriticalSabotage", escapeCRLF: true, 158, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); SetDurationMushroomMixupSabotage = false; __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); } public static void Postfix(MushroomMixupSabotageSystem __instance, bool __state) { if (GameStates.IsHideNSeek || __instance.IsActive == __state || Main.MeetingIsStarted) { return; } Logger.Info(" IsEnd", "MushroomMixupSabotageSystem.Deteriorate.Postfix", escapeCRLF: true, 171, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } new LateTask(delegate { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; for (int j = 0; j < allAlivePlayerControls.Length; j++) { allAlivePlayerControls[j].RpcResetAbilityCooldown(); } }, 1.2f, "Reset Ability Cooldown Arter Mushroom Mixup"); PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl player) => !player.Is(Custom_Team.Impostor) && Main.ResetCamPlayerList.Contains(player.PlayerId)).ToArray(); for (int i = 0; i < array.Length; i++) { Utils.NotifyRoles(array[i]); } } } [HarmonyPatch(typeof(SwitchSystem), "UpdateSystem")] private static class SwitchSystemUpdatePatch { private static bool Prefix(SwitchSystem __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return false; } MessageReader obj = MessageReader.Get(msgReader); byte b = obj.ReadByte(); obj.Recycle(); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (Extensions.HasBit(b, SwitchSystem.DamageSystem)) { return true; } if (GameStates.AirshipIsActive) { Vector2 customPosition = player.GetCustomPosition(); if (Options.DisableAirshipViewingDeckLightsPanel.GetBool() && Vector2.Distance(customPosition, new Vector2(-12.93f, -11.28f)) <= 2f) { return false; } if (Options.DisableAirshipGapRoomLightsPanel.GetBool() && Vector2.Distance(customPosition, new Vector2(13.92f, 6.43f)) <= 2f) { return false; } if (Options.DisableAirshipCargoLightsPanel.GetBool() && Vector2.Distance(customPosition, new Vector2(30.56f, 2.12f)) <= 2f) { return false; } } if (Fool.IsEnable && player.Is(CustomRoles.Fool)) { return false; } if (Options.BlockDisturbancesToSwitches.GetBool()) { byte b2 = (byte)(1 << (int)b); if ((__instance.ActualSwitches & b2) == (__instance.ExpectedSwitches & b2)) { return false; } } return true; } } [HarmonyPatch(typeof(ElectricTask), "Initialize")] public static class ElectricTaskInitializePatch { public static void Postfix() { Utils.MarkEveryoneDirtySettings(); if (!GameStates.IsMeeting) { Utils.NotifyRoles(); } } } [HarmonyPatch(typeof(ElectricTask), "Complete")] public static class ElectricTaskCompletePatch { public static void Postfix() { Utils.MarkEveryoneDirtySettings(); if (!GameStates.IsMeeting) { Utils.NotifyRoles(); } } } [HarmonyPatch(typeof(SabotageSystemType), "UpdateSystem")] public static class SabotageSystemTypeRepairDamagePatch { [HarmonyPatch(typeof(SecurityCameraSystemType), "UpdateSystem")] private static class SecurityCameraSystemTypeUpdateSystemPatch { private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected I4, but got Unknown MessageReader obj = MessageReader.Get(msgReader); byte b = obj.ReadByte(); obj.Recycle(); if (b == SecurityCameraSystemType.IncrementOp) { MapNames activeMapName = Utils.GetActiveMapName(); bool flag; switch ((int)activeMapName) { case 0: case 3: flag = Options.DisableSkeldCamera.GetBool(); break; case 2: flag = Options.DisablePolusCamera.GetBool(); break; case 4: flag = Options.DisableAirshipCamera.GetBool(); break; default: flag = false; break; } return !flag; } return true; } } private static bool isCooldownModificationEnabled; private static float modifiedCooldownSec; public static void Initialize() { isCooldownModificationEnabled = Options.SabotageCooldownControl.GetBool(); modifiedCooldownSec = Options.SabotageCooldown.GetFloat(); } private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return false; } MessageReader obj = MessageReader.Get(msgReader); byte b = obj.ReadByte(); obj.Recycle(); SystemTypes val = (SystemTypes)b; if (Options.DisableSabotage.GetBool()) { return false; } Logger.Info($"PlayerName: {player.GetNameWithRole()}, SabotageType: {val}, amount {b}", "SabotageSystemType.UpdateSystem", escapeCRLF: true, 305, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); return CanSabotage(player, val); } private static bool CanSabotage(PlayerControl player, SystemTypes systemType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)systemType == 14 && Camouflager.CantPressCommsSabotageButton(player)) { return false; } if (player.GetRoleClass() is Glitch glitch) { glitch.Mimic(player); return false; } return player.CanUseSabotage(); } public static void Postfix(SabotageSystemType __instance, bool __runOriginal) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && !GameStates.IsHideNSeek && isCooldownModificationEnabled && __runOriginal) { __instance.Timer = modifiedCooldownSec; __instance.IsDirty = true; } } } [HarmonyPatch(typeof(DoorsSystemType), "UpdateSystem")] public static class DoorsSystemTypePatch { public static void Prefix(PlayerControl player, MessageReader msgReader) { MessageReader obj = MessageReader.Get(msgReader); byte value = obj.ReadByte(); obj.Recycle(); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(28, 2); defaultInterpolatedStringHandler.AppendLiteral("Door is opened by "); object value2; if (player == null) { value2 = null; } else { NetworkedPlayerInfo data = player.Data; value2 = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral(", amount: "); defaultInterpolatedStringHandler.AppendFormatted(value); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "DoorsSystemType.UpdateSystem", escapeCRLF: true, 379, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\SabotageSystemPatch.cs"); } } private static bool SetDurationForReactorSabotage = true; private static bool SetDurationForO2Sabotage = true; private static bool SetDurationMushroomMixupSabotage = true; } [HarmonyPatch(typeof(ShipStatus), "FixedUpdate")] internal class ShipFixedUpdatePatch { public static void Postfix() { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (Main.IsFixedCooldown && Main.RefixCooldownDelay >= 0f) { Main.RefixCooldownDelay -= Time.fixedDeltaTime; } else if (!float.IsNaN(Main.RefixCooldownDelay)) { Utils.MarkEveryoneDirtySettings(); Main.RefixCooldownDelay = float.NaN; Logger.Info("Refix Cooldown", "CoolDown", escapeCRLF: true, 28, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); } } } } [HarmonyPatch(typeof(ShipStatus), "UpdateSystem", new Type[] { typeof(SystemTypes), typeof(PlayerControl), typeof(MessageReader) })] public static class MessageReaderUpdateSystemPatch { public static bool Prefix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] MessageReader reader) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if ((int)systemType <= 18) { if ((int)systemType == 11 || (int)systemType == 18) { goto IL_0020; } } else if ((int)systemType == 26 || (int)systemType == 37 || (int)systemType == 47) { goto IL_0020; } bool flag = false; goto IL_0026; IL_0020: flag = true; goto IL_0026; IL_0026: if (flag) { return true; } if (GameStates.IsHideNSeek) { return true; } byte amount = MessageReader.Get(reader).ReadByte(); if (EAC.RpcUpdateSystemCheck(player, systemType, amount)) { Logger.Info("Eac patched Sabotage RPC", "MessageReaderUpdateSystemPatch", escapeCRLF: true, 49, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); return false; } return UpdateSystemPatch.Prefix(__instance, systemType, player, amount); } public static void Postfix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] MessageReader reader) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((int)systemType <= 18) { if ((int)systemType == 11 || (int)systemType == 18) { goto IL_0020; } } else if ((int)systemType == 26 || (int)systemType == 37 || (int)systemType == 47) { goto IL_0020; } bool flag = false; goto IL_0026; IL_0020: flag = true; goto IL_0026; IL_0026: if (!flag && !GameStates.IsHideNSeek) { UpdateSystemPatch.Postfix(__instance, systemType, player, MessageReader.Get(reader).ReadByte()); } } } [HarmonyPatch(typeof(ShipStatus), "UpdateSystem", new Type[] { typeof(SystemTypes), typeof(PlayerControl), typeof(byte) })] internal class UpdateSystemPatch { public static bool Prefix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] byte amount) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Invalid comparison between Unknown and I4 //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Invalid comparison between Unknown and I4 //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Invalid comparison between Unknown and I4 //IL_015f: Unknown result type (might be due to invalid IL or missing references) Logger.Msg($"SystemType: {systemType}, PlayerName: {player.GetNameWithRole().RemoveHtmlTags()}, amount: {amount}", "ShipStatus.UpdateSystem", escapeCRLF: true, 77, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); if (RepairSender.enabled && (int)((InnerNetClient)AmongUsClient.Instance).NetworkMode != 1) { Logger.SendInGame($"SystemType: {systemType}, PlayerName: {player.GetNameWithRole().RemoveHtmlTags()}, amount: {amount}"); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (Options.CurrentGameMode == CustomGameMode.FFA && (int)systemType == 17) { return false; } if (Options.DisableSabotage.GetBool() && (int)systemType == 17) { return false; } if (Fool.IsEnable && Fool.BlockFixSabotage(player, systemType)) { return false; } if (player.Is(CustomRoles.Unlucky) && player.IsAlive() && (int)systemType == 16 && Unlucky.SuicideRand(player, Unlucky.StateSuicide.OpenDoor)) { return false; } player.GetRoleClass()?.UpdateSystem(__instance, systemType, amount, player); if (Quizmaster.HasEnabled) { Quizmaster.OnSabotageCall(systemType); } return true; } public static void Postfix(ShipStatus __instance, [HarmonyArgument(0)] SystemTypes systemType, [HarmonyArgument(1)] PlayerControl player, [HarmonyArgument(2)] byte amount) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 Camouflage.CheckCamouflage(); if ((int)systemType == 7 && 0 <= amount && amount <= 4) { SwitchSystem val = ((Il2CppObjectBase)ShipStatus.Instance.Systems[(SystemTypes)7]).Cast(); if (val != null && val.IsActive) { player.GetRoleClass()?.SwitchSystemUpdate(val, amount, player); } } } public static void CheckAndOpenDoorsRange(ShipStatus __instance, int amount, int min, int max) { List list = new List(); for (int i = min; i <= max; i++) { list.Add(i); } int num = 0; int[] array = new int[list.Count]; foreach (int item in list) { array[num] = item; num++; } CheckAndOpenDoors(__instance, amount, array); } private static void CheckAndOpenDoors(ShipStatus __instance, int amount, params int[] DoorIds) { if (DoorIds.Contains(amount)) { foreach (int num in DoorIds) { __instance.RpcUpdateSystem((SystemTypes)16, (byte)num); } } } } [HarmonyPatch(typeof(ShipStatus), "CloseDoorsOfType")] internal class ShipStatusCloseDoorsPatch { public static bool Prefix(SystemTypes room) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Logger.Info($"Trying to close the door in the room: {room}", "CloseDoorsOfType", escapeCRLF: true, 155, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); bool flag = ((Options.CurrentGameMode != CustomGameMode.FFA && !Options.DisableCloseDoor.GetBool()) ? true : false); if (flag) { Logger.Info($"The door is closed in room: {room}", "CloseDoorsOfType", escapeCRLF: true, 163, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); } return flag; } } [HarmonyPatch(typeof(ShipStatus), "Start")] internal class StartPatch { public static void Postfix() { //IL_0146: Unknown result type (might be due to invalid IL or missing references) Logger.CurrentMethod(173, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); Logger.Info("-----------Start of game-----------", "Phase", escapeCRLF: true, 174, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); Utils.CountAlivePlayers(sendLog: true); if (Options.AllowConsole.GetBool() && PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) { if (!ConsoleManager.ConsoleActive && ConsoleManager.ConsoleEnabled) { ConsoleManager.CreateConsole(); } } else if (ConsoleManager.ConsoleActive && !DebugModeManager.AmDebugger) { ConsoleManager.DetachConsole(); Logger.SendInGame(Translator.GetString("Warning.CanNotUseBepInExConsole")); } if (GameStates.PolusIsActive && Main.EnableCustomDecorations.Value) { GameObject val = GameObject.Find("Dropship/panel_fuel"); if ((Object)(object)val != (Object)null) { GameObject obj = GameObject.Find("Dropship"); GameObject obj2 = Object.Instantiate(val, (obj != null) ? obj.transform : null); ((Object)obj2).name = "Dropship_Decorations"; GameObjectExtensions.DestroyChildren(obj2.transform); Object.Destroy((Object)(object)obj2.GetComponent()); Object.Destroy((Object)(object)obj2.GetComponent()); Object.Destroy((Object)(object)obj2.GetComponent()); obj2.GetComponent().sprite = Utils.LoadSprite("TOHE.Resources.Images.Dropship-Decorations.png", 100f); obj2.transform.SetSiblingIndex(1); obj2.transform.localPosition = new Vector3(0.0709f, 0.73f); } } } } [HarmonyPatch(typeof(ShipStatus), "StartMeeting")] internal class StartMeetingPatch { public static void Prefix(ShipStatus __instance, PlayerControl reporter, NetworkedPlayerInfo target) { if (!GameStates.IsHideNSeek) { MeetingStates.ReportTarget = target; MeetingStates.DeadBodies = Il2CppArrayBase.op_Implicit(Object.FindObjectsOfType()); } } public static void Postfix() { foreach (PlayerState value in Main.PlayerStates.Values) { value.HasSpawned = false; } } } [HarmonyPatch(typeof(ShipStatus), "Begin")] internal class BeginPatch { public static void Postfix() { Logger.CurrentMethod(233, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ShipStatusPatch.cs"); } } [HarmonyPatch(typeof(GameManager), "CheckTaskCompletion")] internal class CheckTaskCompletionPatch { public static bool Prefix(ref bool __result) { if (Options.DisableTaskWin.GetBool() || Options.NoGameEnd.GetBool() || TaskState.InitialTotalTasks == 0 || Options.CurrentGameMode == CustomGameMode.FFA) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(TaskAdderGame), "ShowFolder")] internal class ShowFolderPatch { private static TaskFolder CustomRolesFolder; public static void Prefix(TaskAdderGame __instance, [HarmonyArgument(0)] TaskFolder taskFolder) { if (!GameStates.IsHideNSeek && (Object)(object)__instance.Root == (Object)(object)taskFolder && (Object)(object)CustomRolesFolder == (Object)null) { TaskFolder val = Object.Instantiate(__instance.RootFolderPrefab, ((Component)__instance).transform); ((Component)val).gameObject.SetActive(false); val.FolderName = Main.ModName; CustomRolesFolder = val; __instance.Root.SubFolders.Add(val); } } public static void Postfix(TaskAdderGame __instance, [HarmonyArgument(0)] TaskFolder taskFolder) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return; } Logger.Info("Opened " + taskFolder.FolderName, "TaskFolder", escapeCRLF: true, 30, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\TaskAdderPatch.cs"); float num = 0f; float num2 = 0f; float num3 = 0f; if ((Object)(object)CustomRolesFolder != (Object)null && CustomRolesFolder.FolderName == taskFolder.FolderName) { ((IEnumerable)DestroyableSingleton.Instance.AllRoles).FirstOrDefault((Func)((RoleBehaviour role) => (int)role.Role == 0)); CustomRoles[] allRoles = CustomRolesHelper.AllRoles; foreach (CustomRoles customRoles in allRoles) { TaskAddButton val = Object.Instantiate(__instance.RoleButton); ((TMP_Text)val.Text).text = Utils.GetRoleName(customRoles); __instance.AddFileAsChild(CustomRolesFolder, val, ref num, ref num2, ref num3); RoleBehaviour role2 = new RoleBehaviour { Role = (RoleTypes)(ushort)((ushort)customRoles + 1000) }; val.Role = role2; _ = Color.white; Color roleColor = Utils.GetRoleColor(customRoles); val.FileImage.color = roleColor; val.RolloverHandler.OutColor = roleColor; val.RolloverHandler.OverColor = new Color(roleColor.r * 0.5f, roleColor.g * 0.5f, roleColor.b * 0.5f); } } } } [HarmonyPatch(typeof(TaskAddButton), "Update")] internal class TaskAddButtonUpdatePatch { public static bool Prefix(TaskAddButton __instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected I4, but got Unknown if (GameStates.IsHideNSeek) { return true; } try { if ((int)__instance.Role.Role >= 1000) { CustomRoles customRole = PlayerControl.LocalPlayer.GetCustomRole(); CustomRoles customRoles = (CustomRoles)(__instance.Role.Role - 1000); ((Renderer)__instance.Overlay).enabled = customRole == customRoles; } } catch { } return true; } } [HarmonyPatch(typeof(TaskAddButton), "AddTask")] internal class AddTaskButtonPatch { public static bool Prefix(TaskAddButton __instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return true; } try { if ((int)__instance.Role.Role >= 1000) { CustomRoles role = (CustomRoles)(__instance.Role.Role - 1000); PlayerControl.LocalPlayer.RpcSetCustomRole(role); PlayerControl.LocalPlayer.RpcSetRole(role.GetRoleTypes(), false); return false; } } catch { } return true; } } [HarmonyPatch(typeof(ShipStatus), "AddTasksFromList")] internal class AddTasksFromListPatch { public static void Prefix(ShipStatus __instance, [HarmonyArgument(4)] List unusedTasks) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Expected I4, but got Unknown //IL_0762: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || (Object)(object)__instance == (Object)null || (!Options.DisableShortTasks.GetBool() && !Options.DisableCommonTasks.GetBool() && !Options.DisableLongTasks.GetBool() && !Options.DisableOtherTasks.GetBool())) { return; } List list = new List(); Enumerator enumerator = unusedTasks.GetEnumerator(); while (enumerator.MoveNext()) { NormalPlayerTask current = enumerator.Current; TaskTypes taskType = ((PlayerTask)current).TaskType; switch ((int)taskType) { case 5: if (!Options.DisableSwipeCard.GetBool()) { continue; } break; case 0: if (!Options.DisableSubmitScan.GetBool()) { continue; } break; case 47: if (!Options.DisableUnlockSafe.GetBool()) { continue; } break; case 7: if (!Options.DisableUploadData.GetBool()) { continue; } break; case 4: if (!Options.DisableStartReactor.GetBool()) { continue; } break; case 44: if (!Options.DisableResetBreaker.GetBool()) { continue; } break; case 60: if (!Options.DisableCleanVent.GetBool()) { continue; } break; case 13: if (!Options.DisableCalibrateDistributor.GetBool()) { continue; } break; case 3: if (!Options.DisableChartCourse.GetBool()) { continue; } break; case 21: if (!Options.DisableStabilizeSteering.GetBool()) { continue; } break; case 18: if (!Options.DisableCleanO2Filter.GetBool()) { continue; } break; case 15: if (!Options.DisableUnlockManifolds.GetBool()) { continue; } break; case 1: if (!Options.DisablePrimeShields.GetBool()) { continue; } break; case 24: if (!Options.DisableMeasureWeather.GetBool()) { continue; } break; case 26: if (!Options.DisableBuyBeverage.GetBool()) { continue; } break; case 22: if (!Options.DisableAssembleArtifact.GetBool()) { continue; } break; case 27: if (!Options.DisableProcessData.GetBool()) { continue; } break; case 28: if (!Options.DisableRunDiagnostics.GetBool()) { continue; } break; case 39: if (!Options.DisableRepairDrill.GetBool()) { continue; } break; case 40: if (!Options.DisableAlignTelescope.GetBool()) { continue; } break; case 41: if (!Options.DisableRecordTemperature.GetBool()) { continue; } break; case 32: if (!Options.DisableFillCanisters.GetBool()) { continue; } break; case 30: if (!Options.DisableMonitorTree.GetBool()) { continue; } break; case 31: if (!Options.DisableStoreArtifacts.GetBool()) { continue; } break; case 49: if (!Options.DisablePutAwayPistols.GetBool()) { continue; } break; case 58: if (!Options.DisablePutAwayRifles.GetBool()) { continue; } break; case 46: if (!Options.DisableMakeBurger.GetBool()) { continue; } break; case 51: if (!Options.DisableCleanToilet.GetBool()) { continue; } break; case 45: if (!Options.DisableDecontaminate.GetBool()) { continue; } break; case 48: if (!Options.DisableSortRecords.GetBool()) { continue; } break; case 50: if (!Options.DisableFixShower.GetBool()) { continue; } break; case 53: if (!Options.DisablePickUpTowels.GetBool()) { continue; } break; case 43: if (!Options.DisablePolishRuby.GetBool()) { continue; } break; case 52: if (!Options.DisableDressMannequin.GetBool()) { continue; } break; case 11: if (!Options.DisableAlignEngineOutput.GetBool()) { continue; } break; case 8: if (!Options.DisableInspectSample.GetBool()) { continue; } break; case 9: if (!Options.DisableEmptyChute.GetBool()) { continue; } break; case 6: if (!Options.DisableClearAsteroids.GetBool()) { continue; } break; case 29: if (!Options.DisableWaterPlants.GetBool()) { continue; } break; case 37: if (!Options.DisableOpenWaterways.GetBool()) { continue; } break; case 38: if (!Options.DisableReplaceWaterJug.GetBool()) { continue; } break; case 42: if (!Options.DisableRebootWifi.GetBool()) { continue; } break; case 56: if (!Options.DisableDevelopPhotos.GetBool()) { continue; } break; case 54: if (!Options.DisableRewindTapes.GetBool()) { continue; } break; case 55: if (!Options.DisableStartFans.GetBool()) { continue; } break; case 12: if (!Options.DisableFixWiring.GetBool()) { continue; } break; case 25: if (!Options.DisableEnterIdCode.GetBool()) { continue; } break; case 34: if (!Options.DisableInsertKeys.GetBool()) { continue; } break; case 36: if (!Options.DisableScanBoardingPass.GetBool()) { continue; } break; case 10: if (!Options.DisableEmptyGarbage.GetBool()) { continue; } break; case 2: if (!Options.DisableFuelEngines.GetBool()) { continue; } break; case 14: if (!Options.DisableDivertPower.GetBool()) { continue; } break; case 33: if (!Options.DisableActivateWeatherNodes.GetBool()) { continue; } break; case 66: if (!Options.DisableRoastMarshmallow.GetBool()) { continue; } break; case 68: if (!Options.DisableCollectSamples.GetBool()) { continue; } break; case 73: if (!Options.DisableReplaceParts.GetBool()) { continue; } break; case 69: if (!Options.DisableCollectVegetables.GetBool()) { continue; } break; case 71: if (!Options.DisableMineOres.GetBool()) { continue; } break; case 79: if (!Options.DisableExtractFuel.GetBool()) { continue; } break; case 63: if (!Options.DisableCatchFish.GetBool()) { continue; } break; case 72: if (!Options.DisablePolishGem.GetBool()) { continue; } break; case 74: if (!Options.DisableHelpCritter.GetBool()) { continue; } break; case 70: if (!Options.DisableHoistSupplies.GetBool()) { continue; } break; case 76: if (!Options.DisableFixAntenna.GetBool()) { continue; } break; case 62: if (!Options.DisableBuildSandcastle.GetBool()) { continue; } break; case 75: if (!Options.DisableCrankGenerator.GetBool()) { continue; } break; case 80: if (!Options.DisableMonitorMushroom.GetBool()) { continue; } break; case 81: if (!Options.DisablePlayVideoGame.GetBool()) { continue; } break; case 77: if (!Options.DisableFindSignal.GetBool()) { continue; } break; case 67: if (!Options.DisableThrowFisbee.GetBool()) { continue; } break; case 65: if (!Options.DisableLiftWeights.GetBool()) { continue; } break; case 64: if (!Options.DisableCollectShells.GetBool()) { continue; } break; default: continue; } list.Add(current); } NormalPlayerTask[] array = list.ToArray(); foreach (NormalPlayerTask val in array) { Logger.Msg($"Deletion: {((PlayerTask)val).TaskType}", "Disable Tasks", escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\TaskAssignPatch.cs"); unusedTasks.Remove(val); } } } [HarmonyPatch(typeof(NetworkedPlayerInfo), "RpcSetTasks")] internal class RpcSetTasksPatch { public static void Prefix(NetworkedPlayerInfo __instance, [HarmonyArgument(0)] ref Il2CppStructArray taskTypeIds) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || GameStates.IsHideNSeek) { return; } if (Main.RealOptionsData == null) { Logger.Warn("Warning: RealOptionsData is null", "RpcSetTasksPatch", escapeCRLF: true, 123, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\TaskAssignPatch.cs"); return; } PlayerControl @object = __instance.Object; CustomRoles? customRoles = @object?.GetCustomRole(); if (!customRoles.HasValue) { return; } CustomRoles value = customRoles.Value; bool flag = true; int num = Main.NormalOptions.NumLongTasks; int num2 = Main.NormalOptions.NumShortTasks; if (Options.OverrideTasksData.AllData.TryGetValue(value, out var value2) && value2.doOverride.GetBool()) { flag = value2.assignCommonTasks.GetBool(); num = value2.numLongTasks.GetInt(); num2 = value2.numShortTasks.GetInt(); } if (@object.Is(CustomRoles.Snitch) && @object.Is(CustomRoles.Madmate)) { flag = false; num = 0; num2 = Madmate.MadSnitchTasks.GetInt(); } if (@object.Is(CustomRoles.GM) || @object.Is(CustomRoles.LazyGuy) || @object.Is(CustomRoles.Lazy) || Options.CurrentGameMode == CustomGameMode.FFA) { flag = false; num2 = 0; num = 0; } if (@object.Is(CustomRoles.Workhorse)) { (flag, num, num2) = Workhorse.TaskData; } if (@object.Is(CustomRoles.Solsticer)) { Solsticer.SetShortTasksToAdd(); num2 += Solsticer.AddShortTasks; @object.GetPlayerTaskState().AllTasksCount = num2 + num; flag = false; } if (((Il2CppArrayBase)(object)taskTypeIds).Count == 0) { flag = false; } if (!flag && num == 0 && num2 == 0) { num2 = 1; } if (flag && num == Main.NormalOptions.NumLongTasks && num2 == Main.NormalOptions.NumShortTasks) { return; } List val = new List(); foreach (byte item in (Il2CppArrayBase)(object)taskTypeIds) { val.Add(item); } int @int = Main.RealOptionsData.GetInt((Int32OptionNames)10); if (flag) { val.RemoveRange(@int, val.Count - @int); } else { val.Clear(); } HashSet val2 = new HashSet(); int num3 = 0; int num4 = 0; List val3 = new List(); NormalPlayerTask[] array = ((IEnumerable)ShipStatus.Instance.LongTasks).ToArray(); foreach (NormalPlayerTask val4 in array) { val3.Add(val4); } Shuffle(val3); List val5 = new List(); array = ((IEnumerable)ShipStatus.Instance.ShortTasks).ToArray(); foreach (NormalPlayerTask val6 in array) { val5.Add(val6); } Shuffle(val5); ShipStatus.Instance.AddTasksFromList(ref num3, num, val, val2, val3); ShipStatus.Instance.AddTasksFromList(ref num4, num2, val, val2, val5); taskTypeIds = new Il2CppStructArray((long)val.Count); for (int j = 0; j < val.Count; j++) { ((Il2CppArrayBase)(object)taskTypeIds)[j] = val[j]; } } public static void Shuffle(List list) { for (int i = 0; i < list.Count - 1; i++) { T val = list[i]; int num = Random.Range(i, list.Count); list[i] = list[num]; list[num] = val; } } } [HarmonyPatch(typeof(NetworkedPlayerInfo), "HandleRpc")] internal class HandleRpcPatch { public static bool Prefix(NetworkedPlayerInfo __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Logger.Error($"Received Rpc {callId} for {__instance.Object.GetRealName()}({__instance.PlayerId}), which is impossible.", "TaskAssignPatch", escapeCRLF: true, 261, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\TaskAssignPatch.cs"); EAC.WarnHost(); return false; } return true; } } public static class TOHEOnlySearch { [HarmonyPatch(typeof(FilterTagManager), "RefreshTags")] public static class FilterTagManagerPatch { public static void Postfix() { DataManager.Settings.Multiplayer.ValidGameFilterOptions.FilterTags.Add("TOHE"); } } [HarmonyPatch(typeof(FilterTagsMenu), "ChooseOption")] public static class FilterTagsMenuChooseOptionPatch { public static void Postfix(FilterTagsMenu __instance, ChatLanguageButton button, string filter) { if (!__instance.targetOpts.FilterTags.Contains("TOHE")) { return; } if (filter == "TOHE") { __instance.targetOpts.FilterTags = new HashSet(); __instance.targetOpts.FilterTags.Add("TOHE"); Enumerator enumerator = __instance.controllerSelectable.GetEnumerator(); while (enumerator.MoveNext()) { ((Component)enumerator.Current).GetComponent().SetSelected(false); } button.SetSelected(true); } else { __instance.targetOpts.FilterTags.Remove("TOHE"); Enumerator enumerator = __instance.controllerSelectable.GetEnumerator(); while (enumerator.MoveNext()) { ChatLanguageButton component = ((Component)enumerator.Current).GetComponent(); if (((TMP_Text)component.Text).text == "TOHE") { component.SetSelected(false); } } } __instance.UpdateButtonText(); } } public const string FilterText = "TOHE"; } [HarmonyPatch(typeof(Console), "CanUse")] internal class CanUsePatch { public static bool Prefix(Console __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) { canUse = (couldUse = false); if (!__instance.AllowImpostor) { return Utils.HasTasks(PlayerControl.LocalPlayer.Data, ForRecompute: false); } return true; } } [HarmonyPatch(typeof(EmergencyMinigame), "Update")] internal class EmergencyMinigamePatch { public static void Postfix(EmergencyMinigame __instance) { if (Options.DisableMeeting.GetBool() || Options.CurrentGameMode == CustomGameMode.FFA) { ((Minigame)__instance).Close(); } } } [HarmonyPatch(typeof(Vent), "CanUse")] internal class CanUseVentPatch { public static bool Prefix(Vent __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] ref bool canUse, [HarmonyArgument(2)] ref bool couldUse, ref float __result) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsHideNSeek) { return true; } PlayerControl @object = pc.Object; couldUse = @object.CanUseImpostorVentButton() || ((int)pc.Role.Role == 3 && pc.Role.CanUse(((Il2CppObjectBase)__instance).Cast())); canUse = couldUse; if (!canUse) { return false; } IUsable val = ((Il2CppObjectBase)__instance).Cast(); float num = float.MaxValue; couldUse = GameManager.Instance.LogicUsables.CanUse(val, @object) && (!@object.MustCleanVent(__instance.Id) || (@object.inVent && (Object)(object)Vent.currentVent == (Object)(object)__instance)) && @object.IsAlive() && (@object.CanMove || @object.inVent); ISystemType val2 = default(ISystemType); if (ShipStatus.Instance.Systems.TryGetValue((SystemTypes)37, ref val2)) { VentilationSystem val3 = ((Il2CppObjectBase)val2).TryCast(); if (val3 != null && val3.IsVentCurrentlyBeingCleaned(__instance.Id)) { couldUse = false; } } canUse = couldUse; if (canUse) { Bounds bounds = @object.Collider.bounds; Vector3 center = ((Bounds)(ref bounds)).center; Vector3 position = ((Component)__instance).transform.position; num = Vector2.Distance(Vector2.op_Implicit(center), Vector2.op_Implicit(position)); canUse &= num <= __instance.UsableDistance && !PhysicsHelpers.AnythingBetween(@object.Collider, Vector2.op_Implicit(center), Vector2.op_Implicit(position), Constants.ShipOnlyMask, false); } __result = num; return false; } } [HarmonyPatch(typeof(PlayerPurchasesData), "GetPurchase")] public static class PlayerPurchasesDataPatch { public static bool Prefix(ref bool __result) { if (RunLoginPatch.ClickCount < 20) { return true; } __result = true; return false; } } public abstract class RoleBase { public enum GeneralOption { Cooldown, AbilityCooldown, CanKill, KillCooldown, CanVent, ImpostorVision, CanUseSabotage, CanKillImpostors, CanGuess, HideVote, HideAdditionalVotes, CanUseMeetingButton, ModeSwitchAction, ShowShapeshiftAnimations, DefaultKillCooldown, ReduceKillCooldown, MinKillCooldown, KillAttackerWhenAbilityRemaining, SnatchesWin, ShapeshifterBase_ShapeshiftCooldown, ShapeshifterBase_ShapeshiftDuration, ShapeshifterBase_LeaveShapeshiftingEvidence, PhantomBase_InvisCooldown, PhantomBase_InvisDuration, GuardianAngelBase_ProtectCooldown, GuardianAngelBase_ProtectionDuration, GuardianAngelBase_ImpostorsCanSeeProtect, ScientistBase_BatteryCooldown, ScientistBase_BatteryDuration, EngineerBase_VentCooldown, EngineerBase_InVentMaxTime, NoisemakerBase_ImpostorAlert, NoisemakerBase_AlertDuration, TrackerBase_TrackingCooldown, TrackerBase_TrackingDuration, TrackerBase_TrackingDelay } public PlayerState _state; public PlayerControl _Player => Utils.GetPlayerById(_state.PlayerId); public List _playerIdList => (from x in Main.PlayerStates.Values where x.MainRole == _state.MainRole select x.PlayerId).Cast().ToList(); public float AbilityLimit { get; set; } = -100f; public virtual bool IsEnable { get; set; } public abstract CustomRoles ThisRoleBase { get; } public abstract Custom_RoleType ThisRoleType { get; } public CustomRoles ThisCustomRole => Enum.Parse(GetType().Name, ignoreCase: true); public virtual bool IsExperimental => false; public virtual bool CanDesyncShapeshift => false; public virtual Sprite ReportButtonSprite { get; } public void OnInit() { IsEnable = false; Init(); } public void OnAdd(byte playerid) { _state = Main.PlayerStates.Values.FirstOrDefault((PlayerState state) => state.PlayerId == playerid); try { CustomRoleManager.RoleClass.FirstOrDefault((KeyValuePair r) => r.Key == _state.MainRole).Value.IsEnable = true; IsEnable = true; } catch { } Add(playerid); if (CustomRoleManager.OtherCollectionsSet) { CustomRoleManager.Add(); } } public void OnRemove(byte playerId) { Remove(playerId); IsEnable = false; } public virtual void Init() { } public virtual void Add(byte playerId) { } public virtual void Remove(byte playerId) { } public virtual bool CanUseKillButton(PlayerControl pc) { if (pc.Is(Custom_Team.Impostor)) { return pc.IsAlive(); } return false; } public virtual bool CanUseImpostorVentButton(PlayerControl pc) { if (pc.Is(Custom_Team.Impostor)) { return pc.IsAlive(); } return false; } public virtual bool CanUseSabotage(PlayerControl pc) { return pc.Is(Custom_Team.Impostor); } public virtual bool OnSabotage(PlayerControl pc) { return (Object)(object)pc != (Object)null; } public virtual void SetupCustomOption() { } public virtual void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public virtual void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = Options.DefaultKillCooldown; } public virtual void OnFixedUpdate(PlayerControl pc) { } public virtual void OnFixedUpdateLowLoad(PlayerControl pc) { } public virtual bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { return true; } public virtual void OnOthersTaskComplete(PlayerControl pc, PlayerTask task) { } public virtual bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { if (role.IsCrewmate() && !role.IsTasklessCrewmate()) { if (ForRecompute) { return !player.Object.IsAnySubRole((CustomRoles x) => x.IsConverted()); } return true; } return false; } public virtual bool OnCheckProtect(PlayerControl angel, PlayerControl target) { if ((Object)(object)angel != (Object)null) { return (Object)(object)target != (Object)null; } return false; } public virtual void OnEnterVent(PlayerControl pc, Vent vent) { } public virtual bool CheckBootFromVent(PlayerPhysics physics, int ventId) { return (Object)(object)physics == (Object)null; } public virtual bool OnCoEnterVentOthers(PlayerPhysics physics, int ventId) { return (Object)(object)physics == (Object)null; } public virtual void OnCoEnterVent(PlayerPhysics physics, int ventId) { } public virtual void OnExitVent(PlayerControl pc, int ventId) { } public virtual void UpdateSystem(ShipStatus __instance, SystemTypes systemType, byte amount, PlayerControl player) { } public virtual void SwitchSystemUpdate(SwitchSystem __instance, byte amount, PlayerControl player) { } public virtual bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)target != (Object)null) { return (Object)(object)killer != (Object)null; } return false; } public virtual bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if ((Object)(object)target != (Object)null) { return (Object)(object)killer != (Object)null; } return false; } public virtual bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (!((Object)(object)target == (Object)null)) { return (Object)(object)killer == (Object)null; } return true; } public virtual bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)target != (Object)null) { return (Object)(object)killer != (Object)null; } return false; } public virtual void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { } public virtual void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { } public virtual void OnOtherTargetsReducedToAtoms(PlayerControl DeadPlayer) { } public virtual void OnSelfReducedToAtoms(bool IsAfterMeeting) { } public virtual bool KillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { return false; } public virtual bool GlobalKillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { return false; } public virtual bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { return true; } public virtual void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { } public virtual bool OnCheckStartMeeting(PlayerControl reporter) { return reporter.IsAlive(); } public virtual bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { return reporter.IsAlive(); } public virtual void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { } public virtual bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { return (Object)(object)target == (Object)null; } public virtual bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { return (Object)(object)target == (Object)null; } public virtual bool CheckMisGuessed(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { return (Object)(object)target == (Object)null; } public virtual void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { } public virtual void CheckExileTarget(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { } public virtual void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { } public virtual void OnOthersMeetingHudStart(PlayerControl pc) { } public virtual void OnMeetingHudStart(PlayerControl pc) { } public virtual void MeetingHudClear() { } public virtual string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { return string.Empty; } public virtual void NotifyAfterMeeting() { } public virtual void AfterMeetingTasks() { } public virtual void OnCoEndGame() { } public virtual void OnVote(PlayerControl votePlayer, PlayerControl voteTarget) { } public virtual void OnVoted(PlayerControl votedPlayer, PlayerControl votedTarget) { } public virtual bool HideVote(PlayerVoteArea votedPlayer) { return false; } public virtual void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { } public virtual int AddRealVotesNum(PlayerVoteArea PVA) { return 0; } public virtual void SetAbilityButtonText(HudManager hud, byte playerId) { } public virtual Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return null; } public virtual Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return null; } public virtual Sprite ImpostorVentButtonSprite(PlayerControl player) { return null; } public virtual string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { return string.Empty; } public virtual string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { return string.Empty; } public virtual string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { return string.Empty; } public virtual string GetSuffix(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { return string.Empty; } public virtual string GetProgressText(byte playerId, bool comms) { return string.Empty; } public virtual float SetModdedLowerText(out Color32? FaceColor) { FaceColor = null; return 2.8f; } public virtual string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { return string.Empty; } public virtual string GetLowerTextOthers(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { return string.Empty; } public virtual string GetSuffixOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { return string.Empty; } public virtual bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return false; } public virtual string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { return string.Empty; } public virtual bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return false; } public void OnReceiveRPC(MessageReader reader) { float abilityLimit = reader.ReadSingle(); AbilityLimit = abilityLimit; } public void SendSkillRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)_Player); val.Write(AbilityLimit); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public virtual void ReceiveRPC(MessageReader reader, PlayerControl pc) { OnReceiveRPC(reader); } } internal class DefaultSetup : RoleBase { private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.None; public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } } } namespace TOHE.Roles.Vanilla { internal class CrewmateTOHE : RoleBase { private const int Id = 6000; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(6000, TabGroup.CrewmateRoles, CustomRoles.CrewmateTOHE); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } } internal class EngineerTOHE : RoleBase { private const int Id = 6100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VentUseCooldown; private static OptionItem InVentMaxTime; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(6100, TabGroup.CrewmateRoles, CustomRoles.EngineerTOHE); VentUseCooldown = IntegerOptionItem.Create(6102, GeneralOption.EngineerBase_VentCooldown, new IntegerValueRule(0, 250, 5), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EngineerTOHE]).SetValueFormat(OptionFormat.Seconds); InVentMaxTime = IntegerOptionItem.Create(6103, GeneralOption.EngineerBase_InVentMaxTime, new IntegerValueRule(0, 250, 5), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EngineerTOHE]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentUseCooldown.GetInt(); AURoleOptions.EngineerInVentMaxTime = InVentMaxTime.GetInt(); } } internal class ImpostorTOHE : RoleBase { private const int Id = 300; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(300, TabGroup.ImpostorRoles, CustomRoles.ImpostorTOHE); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } } internal class NoisemakerTOHE : RoleBase { private const int Id = 6230; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ImpostorAlert; private static OptionItem AlertDuration; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Noisemaker; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(6230, TabGroup.CrewmateRoles, CustomRoles.NoisemakerTOHE); ImpostorAlert = BooleanOptionItem.Create(6232, GeneralOption.NoisemakerBase_ImpostorAlert, defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NoisemakerTOHE]); AlertDuration = IntegerOptionItem.Create(6233, GeneralOption.NoisemakerBase_AlertDuration, new IntegerValueRule(1, 20, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NoisemakerTOHE]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public static void ApplyGameOptionsForOthers(PlayerControl player) { AURoleOptions.NoisemakerAlertDuration = AlertDuration.GetInt(); CustomRoles customRole = player.GetCustomRole(); if (customRole.IsDesyncRole() && customRole.IsCrewmate() && !ImpostorAlert.GetBool()) { AURoleOptions.NoisemakerImpostorAlert = true; } else { AURoleOptions.NoisemakerImpostorAlert = ImpostorAlert.GetBool(); } } } internal class PhantomTOHE : RoleBase { private const int Id = 450; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem InvisCooldown; private static OptionItem InvisDuration; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Phantom; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(450, TabGroup.ImpostorRoles, CustomRoles.PhantomTOHE); InvisCooldown = IntegerOptionItem.Create(452, GeneralOption.PhantomBase_InvisCooldown, new IntegerValueRule(5, 180, 5), 15, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PhantomTOHE]).SetValueFormat(OptionFormat.Seconds); InvisDuration = IntegerOptionItem.Create(453, GeneralOption.PhantomBase_InvisDuration, new IntegerValueRule(5, 180, 5), 30, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PhantomTOHE]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.PhantomCooldown = InvisCooldown.GetInt(); AURoleOptions.PhantomDuration = InvisDuration.GetInt(); } } internal class ScientistTOHE : RoleBase { private const int Id = 6200; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem BatteryCooldown; private static OptionItem BatteryDuration; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(6200, TabGroup.CrewmateRoles, CustomRoles.ScientistTOHE); BatteryCooldown = IntegerOptionItem.Create(6202, GeneralOption.ScientistBase_BatteryCooldown, new IntegerValueRule(1, 250, 1), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ScientistTOHE]).SetValueFormat(OptionFormat.Seconds); BatteryDuration = IntegerOptionItem.Create(6203, GeneralOption.ScientistBase_BatteryDuration, new IntegerValueRule(1, 250, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ScientistTOHE]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ScientistCooldown = BatteryCooldown.GetInt(); AURoleOptions.ScientistBatteryCharge = BatteryDuration.GetInt(); } } internal class ShapeshifterTOHE : RoleBase { private const int Id = 400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ShapeshiftCooldown; private static OptionItem ShapeshiftDuration; private static OptionItem LeaveShapeshiftingEvidence; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(400, TabGroup.ImpostorRoles, CustomRoles.ShapeshifterTOHE); ShapeshiftCooldown = IntegerOptionItem.Create(402, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new IntegerValueRule(1, 180, 1), 15, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeshifterTOHE]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDuration = IntegerOptionItem.Create(403, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new IntegerValueRule(1, 180, 1), 30, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeshifterTOHE]).SetValueFormat(OptionFormat.Seconds); LeaveShapeshiftingEvidence = BooleanOptionItem.Create(404, GeneralOption.ShapeshifterBase_LeaveShapeshiftingEvidence, defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeshifterTOHE]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetInt(); AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetInt(); AURoleOptions.ShapeshifterLeaveSkin = LeaveShapeshiftingEvidence.GetBool(); } } internal class TrackerTOHE : RoleBase { private const int Id = 6250; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem TrackCooldown; private static OptionItem TrackDuration; private static OptionItem TrackDelay; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Tracker; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; public override void SetupCustomOption() { Options.SetupRoleOptions(6250, TabGroup.CrewmateRoles, CustomRoles.TrackerTOHE); TrackCooldown = IntegerOptionItem.Create(6252, GeneralOption.TrackerBase_TrackingCooldown, new IntegerValueRule(5, 120, 5), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TrackerTOHE]).SetValueFormat(OptionFormat.Seconds); TrackDuration = IntegerOptionItem.Create(6253, GeneralOption.TrackerBase_TrackingDuration, new IntegerValueRule(5, 120, 5), 30, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TrackerTOHE]).SetValueFormat(OptionFormat.Seconds); TrackDelay = IntegerOptionItem.Create(6254, GeneralOption.TrackerBase_TrackingDelay, new IntegerValueRule(0, 10, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TrackerTOHE]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.TrackerCooldown = TrackCooldown.GetInt(); AURoleOptions.TrackerDuration = TrackDuration.GetInt(); AURoleOptions.TrackerDelay = TrackDelay.GetInt(); } } } namespace TOHE.Roles.Neutral { internal class Agitater : RoleBase { private const int Id = 15800; private static readonly List playerIdList = new List(); private static OptionItem BombExplodeCooldown; private static OptionItem PassCooldown; private static OptionItem AgitaterCanGetBombed; private static OptionItem AgiTaterBombCooldown; private static OptionItem AgitaterAutoReportBait; private static OptionItem HasImpostorVision; public byte CurrentBombedPlayer = byte.MaxValue; public byte LastBombedPlayer = byte.MaxValue; public bool AgitaterHasBombed; public long? CurrentBombedPlayerTime = 0L; public long? AgitaterBombedTime = 0L; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(15800, TabGroup.NeutralRoles, CustomRoles.Agitater); AgiTaterBombCooldown = FloatOptionItem.Create(15810, "AgitaterBombCooldown", new FloatValueRule(10f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]).SetValueFormat(OptionFormat.Seconds); PassCooldown = FloatOptionItem.Create(15811, "AgitaterPassCooldown", new FloatValueRule(0f, 5f, 0.25f), 1f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]).SetValueFormat(OptionFormat.Seconds); BombExplodeCooldown = FloatOptionItem.Create(15812, "BombExplodeCooldown", new FloatValueRule(1f, 10f, 1f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]).SetValueFormat(OptionFormat.Seconds); AgitaterCanGetBombed = BooleanOptionItem.Create(15813, "AgitaterCanGetBombed", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]); AgitaterAutoReportBait = BooleanOptionItem.Create(15814, "AgitaterAutoReportBait", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]); HasImpostorVision = BooleanOptionItem.Create(15815, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Agitater]); } public override void Init() { playerIdList.Clear(); CurrentBombedPlayer = byte.MaxValue; LastBombedPlayer = byte.MaxValue; AgitaterHasBombed = false; CurrentBombedPlayerTime = 0L; } public override void Add(byte playerId) { playerIdList.Add(playerId); CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateOthers); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public void ResetBomb() { CurrentBombedPlayer = byte.MaxValue; CurrentBombedPlayerTime = 0L; LastBombedPlayer = byte.MaxValue; AgitaterHasBombed = false; SendRPC(CurrentBombedPlayer, LastBombedPlayer); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = AgiTaterBombCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!HasEnabled) { return false; } if (AgitaterAutoReportBait.GetBool() && target.Is(CustomRoles.Bait)) { return true; } if (target.Is(CustomRoles.Pestilence)) { target.RpcMurderPlayer(killer); ResetBomb(); return false; } CurrentBombedPlayer = target.PlayerId; LastBombedPlayer = killer.PlayerId; CurrentBombedPlayerTime = Utils.GetTimeStamp(); killer.RpcGuardAndKill(killer); killer.Notify(Translator.GetString("AgitaterPassNotify")); target.Notify(Translator.GetString("AgitaterTargetNotify")); AgitaterHasBombed = true; killer.ResetKillCooldown(); killer.SetKillCooldown(); new LateTask(delegate { if (CurrentBombedPlayer != byte.MaxValue && GameStates.IsInTask) { PlayerControl playerById = Utils.GetPlayerById(CurrentBombedPlayer); if ((Object)(object)playerById != (Object)null && playerById.IsAlive() && (Object)(object)killer != (Object)null) { CurrentBombedPlayer.SetDeathReason(PlayerState.DeathReason.Bombed); playerById.RpcMurderPlayer(playerById); playerById.SetRealKiller(killer); Logger.Info(killer.GetNameWithRole() + " bombed " + playerById.GetNameWithRole() + " - bomb cd complete", "Agitater", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Agitater.cs"); ResetBomb(); } } }, BombExplodeCooldown.GetFloat(), "Agitater Bomb Kill"); return false; } public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInfo agitatergoatedrole) { if (CurrentBombedPlayer != byte.MaxValue) { PlayerControl playerById = Utils.GetPlayerById(CurrentBombedPlayer); PlayerControl playerById2 = Utils.GetPlayerById(playerIdList.First()); if (!((Object)(object)playerById == (Object)null) && !((Object)(object)playerById2 == (Object)null)) { CurrentBombedPlayer.SetDeathReason(PlayerState.DeathReason.Bombed); Main.PlayerStates[CurrentBombedPlayer].SetDead(); playerById.RpcExileV2(); playerById.SetRealKiller(playerById2); MurderPlayerPatch.AfterPlayerDeathTasks(playerById2, playerById, inMeeting: true); ResetBomb(); Logger.Info(playerById2.GetRealName() + " bombed " + playerById.GetRealName() + " on report", "Agitater", escapeCRLF: true, 130, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Agitater.cs"); } } } private void OnFixedUpdateOthers(PlayerControl player) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!AgitaterHasBombed || CurrentBombedPlayer != player.PlayerId) { return; } if (!player.IsAlive()) { ResetBomb(); return; } Vector2 customPosition = player.GetCustomPosition(); Dictionary dictionary = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (val.PlayerId != player.PlayerId && val.PlayerId != LastBombedPlayer) { float value = Vector2.Distance(customPosition, Vector2.op_Implicit(((Component)val).transform.position)); dictionary.Add(val.PlayerId, value); } } if (dictionary.Any()) { KeyValuePair keyValuePair = dictionary.OrderBy((KeyValuePair c) => c.Value).FirstOrDefault(); PlayerControl playerById = Utils.GetPlayerById(keyValuePair.Key); float num = ((Il2CppArrayBase)(object)GameOptionsData.KillDistances)[Mathf.Clamp(GameOptionsManager.Instance.currentNormalGameOptions.KillDistance, 0, 2)]; if (keyValuePair.Value <= num && !player.inVent && !playerById.inVent && player.RpcCheckAndMurder(playerById, check: true)) { PassBomb(player, playerById); } } } private void PassBomb(PlayerControl player, PlayerControl target) { if (!AgitaterHasBombed || !target.IsAlive()) { return; } long timeStamp = Utils.GetTimeStamp(); if (!((float?)(timeStamp - CurrentBombedPlayerTime) < PassCooldown.GetFloat()) && target.PlayerId != LastBombedPlayer && (AgitaterCanGetBombed.GetBool() || !target.Is(CustomRoles.Agitater))) { if (target.Is(CustomRoles.Pestilence)) { target.RpcMurderPlayer(player); ResetBomb(); return; } LastBombedPlayer = CurrentBombedPlayer; CurrentBombedPlayer = target.PlayerId; CurrentBombedPlayerTime = timeStamp; Utils.MarkEveryoneDirtySettings(); player.Notify(Translator.GetString("AgitaterPassNotify")); target.Notify(Translator.GetString("AgitaterTargetNotify")); SendRPC(CurrentBombedPlayer, LastBombedPlayer); Logger.Msg(player.GetNameWithRole() + " passed bomb to " + target.GetNameWithRole(), "Agitater Pass", escapeCRLF: true, 194, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Agitater.cs"); } } public void SendRPC(byte newbomb, byte oldbomb) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(newbomb); val.Write(oldbomb); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { CurrentBombedPlayer = reader.ReadByte(); LastBombedPlayer = reader.ReadByte(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("AgitaterKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("bombshell"); } } internal class Amnesiac : RoleBase { private enum AmnesiacIncompatibleNeutralModeSelectList { Role_Amnesiac, Role_Pursuer, Role_Follower, Role_Maverick, Role_Imitator } private const int Id = 12700; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled = playerIdList.Any(); private static OptionItem IncompatibleNeutralMode; private static OptionItem ShowArrows; private static readonly Dictionary CanUseVent = new Dictionary(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override Sprite ReportButtonSprite => CustomButton.Get("Amnesiac"); public override void SetupCustomOption() { Options.SetupRoleOptions(12700, TabGroup.NeutralRoles, CustomRoles.Amnesiac); IncompatibleNeutralMode = StringOptionItem.Create(12710, "IncompatibleNeutralMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Amnesiac]); ShowArrows = BooleanOptionItem.Create(12711, "ShowArrows", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Amnesiac]); } public override void Init() { playerIdList.Clear(); CanUseVent.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); CanUseVent[playerId] = true; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost && ShowArrows.GetBool()) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost && ShowArrows.GetBool()) { CustomRoleManager.CheckDeadBodyOthers.Remove(CheckDeadBody); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null)) { if (playerById.Is(Custom_Team.Crewmate)) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, opt.GetFloat((FloatOptionNames)4)); opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)4)); } else { opt.SetVision(HasImpVision: true); opt.SetFloat((FloatOptionNames)4, opt.GetFloat((FloatOptionNames)3)); opt.SetFloat((FloatOptionNames)3, opt.GetFloat((FloatOptionNames)3)); } } } public override bool CanUseImpostorVentButton(PlayerControl pc) { return true; } public static bool PreviousAmnesiacCanVent(PlayerControl pc) { bool value; return CanUseVent.TryGetValue(pc.PlayerId, out value) && value; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("RememberButtonText")); } private static void SendRPC(byte playerId, bool add, Vector3 loc = default(Vector3)) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)173, (SendOption)1, -1); val.Write(playerId); val.Write(add); if (add) { val.Write(loc.x); val.Write(loc.y); val.Write(loc.z); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte seer = reader.ReadByte(); if (reader.ReadBoolean()) { LocateArrow.Add(seer, new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); } else { LocateArrow.RemoveAllTarget(seer); } } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (inMeeting || Main.MeetingIsStarted) { return; } byte[] array = playerIdList.ToArray(); foreach (byte b in array) { if (Utils.GetPlayerById(b).IsAlive()) { LocateArrow.Add(b, ((Component)target).transform.position); SendRPC(b, add: true, ((Component)target).transform.position); } } } public override string GetSuffix(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || seer.PlayerId != target.PlayerId) { return string.Empty; } if (ShowArrows.GetBool()) { return Utils.ColorString(Color32.op_Implicit(Color.white), LocateArrow.GetArrows(seer)); } return string.Empty; } public override bool OnCheckReportDeadBody(PlayerControl __instance, NetworkedPlayerInfo deadBody, PlayerControl killer) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) PlayerControl @object = deadBody.Object; byte[] array = playerIdList.ToArray(); foreach (byte num in array) { LocateArrow.RemoveAllTarget(num); SendRPC(num, add: false); } if (__instance.Is(CustomRoles.Amnesiac)) { CustomRoles customRoles = CustomRoles.Amnesiac; if (@object.GetCustomRole().IsImpostor() || @object.GetCustomRole().IsMadmate() || @object.Is(CustomRoles.Madmate)) { customRoles = CustomRoles.Refugee; } if (@object.GetCustomRole().IsCrewmate() && !@object.Is(CustomRoles.Madmate)) { customRoles = ((!@object.IsAmneCrew()) ? CustomRoles.EngineerTOHE : @object.GetCustomRole()); Main.TasklessCrewmate.Add(__instance.PlayerId); } if (@object.GetCustomRole().IsAmneNK()) { customRoles = @object.GetCustomRole(); } if (@object.GetCustomRole().IsAmneMaverick()) { switch (IncompatibleNeutralMode.GetValue()) { case 0: customRoles = CustomRoles.Amnesiac; break; case 1: customRoles = CustomRoles.Pursuer; break; case 2: customRoles = CustomRoles.Follower; break; case 3: customRoles = CustomRoles.Maverick; break; case 4: customRoles = CustomRoles.Imitator; break; } } if (customRoles != CustomRoles.Amnesiac) { __instance.GetRoleClass().OnRemove(__instance.PlayerId); __instance.RpcSetCustomRole(customRoles); __instance.GetRoleClass().OnAdd(__instance.PlayerId); __instance.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Amnesiac)), Translator.GetString("YouRememberedRole"))); @object.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Amnesiac)), Translator.GetString("RememberedYourRole"))); __instance.SyncSettings(); RoleBase roleClass = @object.GetRoleClass(); byte playerId = __instance.PlayerId; bool value; switch (roleClass?.ThisRoleBase) { case CustomRoles.Engineer: value = true; break; case CustomRoles.Impostor: case CustomRoles.Phantom: case CustomRoles.Shapeshifter: value = roleClass.CanUseImpostorVentButton(@object); break; default: value = false; break; } CanUseVent[playerId] = value; Logger.Info($"player id: {__instance.PlayerId}, Can use vent: {CanUseVent[__instance.PlayerId]}", "Previous Amne Vent", escapeCRLF: true, 211, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Amnesiac.cs"); } return false; } return true; } } internal class Arsonist : RoleBase { private const int id = 15900; private static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled = PlayerIds.Any(); private static OptionItem ArsonistDouseTime; private static OptionItem ArsonistCooldown; private static OptionItem ArsonistCanIgniteAnytimeOpt; private static OptionItem ArsonistMinPlayersToIgnite; private static OptionItem ArsonistMaxPlayersToIgnite; private static readonly Dictionary ArsonistTimer = new Dictionary(); private static readonly Dictionary<(byte, byte), bool> IsDoused = new Dictionary<(byte, byte), bool>(); private static byte CurrentDousingTarget = byte.MaxValue; private static bool ArsonistCanIgniteAnytime = true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType { get { if (!CanIgniteAnytime()) { return Custom_RoleType.NeutralBenign; } return Custom_RoleType.NeutralKilling; } } public override void SetupCustomOption() { Options.SetupRoleOptions(15900, TabGroup.NeutralRoles, CustomRoles.Arsonist); ArsonistDouseTime = FloatOptionItem.Create(15910, "ArsonistDouseTime", new FloatValueRule(0f, 10f, 1f), 0f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arsonist]).SetValueFormat(OptionFormat.Seconds); ArsonistCooldown = FloatOptionItem.Create(15911, GeneralOption.Cooldown, new FloatValueRule(0f, 180f, 1f), 25f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arsonist]).SetValueFormat(OptionFormat.Seconds); ArsonistCanIgniteAnytimeOpt = BooleanOptionItem.Create(15912, "ArsonistCanIgniteAnytime", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arsonist]); ArsonistMinPlayersToIgnite = IntegerOptionItem.Create(15913, "ArsonistMinPlayersToIgnite", new IntegerValueRule(1, 14, 1), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ArsonistCanIgniteAnytimeOpt); ArsonistMaxPlayersToIgnite = IntegerOptionItem.Create(15914, "ArsonistMaxPlayersToIgnite", new IntegerValueRule(1, 14, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ArsonistCanIgniteAnytimeOpt); } public override void Init() { PlayerIds.Clear(); ArsonistTimer.Clear(); IsDoused.Clear(); CurrentDousingTarget = byte.MaxValue; ArsonistCanIgniteAnytime = ArsonistCanIgniteAnytimeOpt.GetBool(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { IsDoused.Add((playerId, val.PlayerId), value: false); } if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private static void SendCurrentDousingTargetRPC(byte arsonistId, byte targetId) { if (PlayerControl.LocalPlayer.PlayerId == arsonistId) { CurrentDousingTarget = targetId; return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)147, (SendOption)1, -1); val.Write(arsonistId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveCurrentDousingTargetRPC(MessageReader reader) { byte b = reader.ReadByte(); byte currentDousingTarget = reader.ReadByte(); if (PlayerControl.LocalPlayer.PlayerId == b) { CurrentDousingTarget = currentDousingTarget; } } private static void SendSetDousedPlayerRPC(PlayerControl player, PlayerControl target, bool isDoused) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)138, (SendOption)1, -1); val.Write(player.PlayerId); val.Write(target.PlayerId); val.Write(isDoused); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveSetDousedPlayerRPC(MessageReader reader) { byte item = reader.ReadByte(); byte item2 = reader.ReadByte(); bool value = reader.ReadBoolean(); IsDoused[(item, item2)] = value; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ArsonistCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { if (!CanIgniteAnytime()) { return !IsDouseDone(pc); } return GetDousedPlayerCount(pc.PlayerId).Item1 < ArsonistMaxPlayersToIgnite.GetInt(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { if (!IsDouseDone(pc)) { if (CanIgniteAnytime()) { if (GetDousedPlayerCount(pc.PlayerId).Item1 < ArsonistMinPlayersToIgnite.GetInt()) { return pc.inVent; } return true; } return false; } return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(ArsonistDouseTime.GetFloat()); if (!IsDoused[(killer.PlayerId, target.PlayerId)] && !ArsonistTimer.ContainsKey(killer.PlayerId)) { ArsonistTimer.Add(killer.PlayerId, (target, 0f)); Utils.NotifyRoles(killer, target); SendCurrentDousingTargetRPC(killer.PlayerId, target.PlayerId); } return false; } public override void OnFixedUpdate(PlayerControl player) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (!ArsonistTimer.TryGetValue(player.PlayerId, out var value)) { return; } byte playerId = player.PlayerId; if (!player.IsAlive() || Pelican.IsEaten(playerId)) { ArsonistTimer.Remove(playerId); Utils.NotifyRoles(player); ResetCurrentDousingTarget(playerId); return; } var (val, num) = value; if (!val.IsAlive()) { ArsonistTimer.Remove(playerId); return; } if (num >= ArsonistDouseTime.GetFloat()) { player.SetKillCooldown(); ArsonistTimer.Remove(playerId); IsDoused[(playerId, val.PlayerId)] = true; SendSetDousedPlayerRPC(player, val, isDoused: true); Utils.NotifyRoles(player, val); ResetCurrentDousingTarget(playerId); return; } float num2 = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(player.Is(Reach.IsReach) ? 2 : Main.NormalOptions.KillDistance, 0, 2)] + 0.5f; if (Vector2.Distance(player.GetCustomPosition(), val.GetCustomPosition()) <= num2) { ArsonistTimer[playerId] = (val, num + Time.fixedDeltaTime); return; } ArsonistTimer.Remove(playerId); Utils.NotifyRoles(player, val); ResetCurrentDousingTarget(playerId); Logger.Info("Canceled: " + player.GetNameWithRole(), "Arsonist", escapeCRLF: true, 170, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Arsonist.cs"); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { ArsonistTimer.Clear(); } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seen == (Object)null) { return string.Empty; } if (IsDousedPlayer(seer, seen)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Arsonist)), "▲"); } if (!isForMeeting && ArsonistTimer.TryGetValue(seer.PlayerId, out var value) && (Object)(object)value.Item1 == (Object)(object)seen) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Arsonist)), "△"); } return string.Empty; } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || !IsDouseDone(seer)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Arsonist)), Translator.GetString("EnterVentToWin")); } public override string GetProgressText(byte playerId, bool comms) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) var (value, value2) = GetDousedPlayerCount(playerId); if (!CanIgniteAnytime()) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Arsonist).ShadeColor(0.25f)), $"({value}/{value2})"); } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Arsonist).ShadeColor(0.25f)), $"({value}/{ArsonistMaxPlayersToIgnite.GetInt()})"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("ArsonistDouseButtonText")); ((ActionButton)hud.ImpostorVentButton).OverrideText(Translator.GetString("ArsonistVentButtonText")); } public override Sprite ImpostorVentButtonSprite(PlayerControl player) { if (!IsDouseDone(player) && (!CanIgniteAnytime() || GetDousedPlayerCount(player.PlayerId).Item1 < ArsonistMinPlayersToIgnite.GetInt())) { return null; } return CustomButton.Get("Ignite"); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Douse"); } public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) { if (!((InnerNetClient)AmongUsClient.Instance).IsGameStarted) { return; } if (IsDouseDone(__instance.myPlayer)) { CustomSoundsManager.RPCPlayCustomSoundAll("Boom"); if (!CustomWinnerHolder.CheckForConvertedWinner(__instance.myPlayer.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Arsonist); CustomWinnerHolder.WinnerIds.Add(__instance.myPlayer.PlayerId); } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { val.KillFlash(); if (val.IsAlive() && (Object)(object)val != (Object)(object)__instance.myPlayer) { val.SetDeathReason(PlayerState.DeathReason.Torched); val.RpcMurderPlayer(val); val.SetRealKiller(__instance.myPlayer); } } } else { if (!CanIgniteAnytime()) { return; } int item = GetDousedPlayerCount(__instance.myPlayer.PlayerId).Item1; if (item < ArsonistMinPlayersToIgnite.GetInt()) { return; } if (item > ArsonistMaxPlayersToIgnite.GetInt()) { Logger.Warn("Arsonist Ignited with more players doused than the maximum amount in the settings", "Arsonist Ignite", escapeCRLF: true, 249, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Arsonist.cs"); } PlayerControl[] allPlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allPlayerControls) { if (IsDousedPlayer(__instance.myPlayer, val2)) { val2.KillFlash(); val2.SetDeathReason(PlayerState.DeathReason.Torched); val2.RpcMurderPlayer(val2); val2.SetRealKiller(__instance.myPlayer); } } if (Main.AllAlivePlayerControls.Length == 1 && !CustomWinnerHolder.CheckForConvertedWinner(__instance.myPlayer.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Arsonist); CustomWinnerHolder.WinnerIds.Add(__instance.myPlayer.PlayerId); } } } public static bool CanIgniteAnytime() { return ArsonistCanIgniteAnytime; } private static void ResetCurrentDousingTarget(byte arsonistId) { SendCurrentDousingTargetRPC(arsonistId, byte.MaxValue); } public static bool IsDousedPlayer(PlayerControl arsonist, PlayerControl target) { if ((Object)(object)arsonist == (Object)null || (Object)(object)target == (Object)null || IsDoused == null) { return false; } IsDoused.TryGetValue((arsonist.PlayerId, target.PlayerId), out var value); return value; } public static bool IsDouseDone(PlayerControl player) { if (!player.Is(CustomRoles.Arsonist)) { return false; } var (num, num2) = GetDousedPlayerCount(player.PlayerId); return num >= num2; } public static (int, int) GetDousedPlayerCount(byte playerId) { int num = 0; int num2 = 0; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (val.PlayerId != playerId) { num2++; if (IsDoused.TryGetValue((playerId, val.PlayerId), out var value) && value) { num++; } } } return (num, num2); } } internal class Bandit : RoleBase { private enum BanditStealModeOptList { BanditStealMode_OnMeeting, BanditStealMode_Instantly } private const int Id = 16000; private static OptionItem KillCooldownOpt; private static OptionItem StealCooldown; private static OptionItem MaxSteals; private static OptionItem StealMode; private static OptionItem CanStealBetrayalAddon; private static OptionItem CanStealImpOnlyAddon; private static OptionItem CanUsesSabotage; private static OptionItem CanVent; private float killCooldown; private readonly Dictionary Targets = new Dictionary(); public static bool HasEnabled => CustomRoles.Bandit.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(16000, TabGroup.NeutralRoles, CustomRoles.Bandit); MaxSteals = IntegerOptionItem.Create(16010, "BanditMaxSteals", new IntegerValueRule(1, 20, 1), 6, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); KillCooldownOpt = FloatOptionItem.Create(16011, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]).SetValueFormat(OptionFormat.Seconds); StealCooldown = FloatOptionItem.Create(16017, "BanditStealCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]).SetValueFormat(OptionFormat.Seconds); StealMode = StringOptionItem.Create(16012, "BanditStealMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); CanStealBetrayalAddon = BooleanOptionItem.Create(16013, "BanditCanStealBetrayalAddon", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); CanStealImpOnlyAddon = BooleanOptionItem.Create(16014, "BanditCanStealImpOnlyAddon", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); CanUsesSabotage = BooleanOptionItem.Create(16015, GeneralOption.CanUseSabotage, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); CanVent = BooleanOptionItem.Create(16016, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bandit]); } public override void Add(byte playerId) { base.AbilityLimit = MaxSteals.GetInt(); killCooldown = KillCooldownOpt.GetFloat(); Utils.GetPlayerById(playerId)?.AddDoubleTrigger(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = killCooldown; } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpVision: false); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseSabotage(PlayerControl pc) { return CanUsesSabotage.GetBool(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } private static CustomRoles? SelectRandomAddon(PlayerControl Target) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return null; } List list = Main.PlayerStates[Target.PlayerId].SubRoles.ToList(); for (int num = list.Count - 1; num >= 0; num--) { CustomRoles customRoles = list[num]; if (customRoles == CustomRoles.Cleansed || customRoles == CustomRoles.LastImpostor || customRoles == CustomRoles.Lovers || (customRoles.IsImpOnlyAddon() && !CanStealImpOnlyAddon.GetBool()) || (customRoles == CustomRoles.Nimble && CanVent.GetBool()) || ((customRoles.IsBetrayalAddon() || customRoles == CustomRoles.Lovers) && !CanStealBetrayalAddon.GetBool())) { Logger.Info($"Removed {customRoles} from list of stealable addons", "Bandit", escapeCRLF: true, 86, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); list.Remove(customRoles); } } if (list.Count == 0) { Logger.Info("No stealable addons found on the target.", "Bandit", escapeCRLF: true, 93, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); return null; } return list.RandomElement(); } public void SendRPC(byte targetId, CustomRoles SelectedAddOn, bool removeNow) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(base.AbilityLimit); val.Write(removeNow); if (removeNow) { val.Write(targetId); val.WritePacked((int)SelectedAddOn); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { float abilityLimit = reader.ReadSingle(); base.AbilityLimit = abilityLimit; if (reader.ReadBoolean()) { byte key = reader.ReadByte(); CustomRoles role = (CustomRoles)reader.ReadPackedInt32(); Main.PlayerStates[key].RemoveSubRole(role); } } private void StealAddon(PlayerControl killer, PlayerControl target, CustomRoles? SelectedAddOn) { ExtendedPlayerControl.AddInSwitchAddons(target, killer, CustomRoles.NotAssigned, SelectedAddOn); if (StealMode.GetValue() == 1) { Main.PlayerStates[target.PlayerId].RemoveSubRole(SelectedAddOn.Value); if (SelectedAddOn == CustomRoles.Aware) { Aware.AwareInteracted.Remove(target.PlayerId); } Logger.Info($"Successfully removed {SelectedAddOn} addon from {target.GetNameWithRole()}", "Bandit", escapeCRLF: true, 134, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); if (SelectedAddOn == CustomRoles.Aware && !Aware.AwareInteracted.ContainsKey(target.PlayerId)) { Aware.AwareInteracted[target.PlayerId] = new List(); } killer.RpcSetCustomRole(SelectedAddOn.Value); Logger.Info($"Successfully Added {SelectedAddOn} addon to {killer.GetNameWithRole()}", "Bandit", escapeCRLF: true, 138, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); } else { Targets[target.PlayerId] = SelectedAddOn.Value; Logger.Info($"{killer.GetNameWithRole()} will steal {SelectedAddOn} addon from {target.GetNameWithRole()} after meeting starts", "Bandit", escapeCRLF: true, 143, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); } base.AbilityLimit--; SendRPC(target.PlayerId, SelectedAddOn.Value, StealMode.GetValue() == 1); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { bool flag = false; if (!target.HasSubRole() || target.Is(CustomRoles.Stubborn)) { flag = true; } CustomRoles? SelectedAddOn = SelectRandomAddon(target); if (!SelectedAddOn.HasValue || flag) { killer.Notify(Translator.GetString("Bandit_NoStealableAddons")); killCooldown = KillCooldownOpt.GetFloat(); killer.ResetKillCooldown(); killer.SetKillCooldown(); return true; } if (base.AbilityLimit < 1f) { Logger.Info("Max steals reached killing the player", "Bandit", escapeCRLF: true, 176, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); killCooldown = KillCooldownOpt.GetFloat(); killer.ResetKillCooldown(); killer.SetKillCooldown(); return true; } if (killer.CheckDoubleTrigger(target, delegate { StealAddon(killer, target, SelectedAddOn); })) { killCooldown = KillCooldownOpt.GetFloat(); killer.ResetKillCooldown(); killer.SetKillCooldown(); return true; } killCooldown = StealCooldown.GetFloat(); return false; } public override void OnReportDeadBody(PlayerControl reportash, NetworkedPlayerInfo panagustava) { if (StealMode.GetValue() == 1 || (Object)(object)base._Player == (Object)null) { return; } foreach (KeyValuePair target in Targets) { byte key = target.Key; PlayerControl playerById = Utils.GetPlayerById(key); if (!((Object)(object)playerById == (Object)null)) { CustomRoles value = target.Value; Main.PlayerStates[key].RemoveSubRole(value); if (value == CustomRoles.Aware) { Aware.AwareInteracted.Remove(key); } Logger.Info($"Successfully removed {value} addon from {playerById.GetNameWithRole()}", "Bandit", escapeCRLF: true, 210, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); SendRPC(key, value, removeNow: true); if (value == CustomRoles.Aware && !Aware.AwareInteracted.ContainsKey(key)) { Aware.AwareInteracted[key] = new List(); } base._Player.RpcSetCustomRole(value); Logger.Info($"Successfully Added {value} addon to {base._Player?.GetNameWithRole()}", "Bandit", escapeCRLF: true, 215, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Bandit.cs"); } } } public override string GetProgressText(byte playerId, bool comms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Bandit).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class BloodKnight : RoleBase { private const int Id = 16100; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem ProtectDuration; private long? TimeStamp; public static bool HasEnabled => CustomRoles.BloodKnight.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16100, TabGroup.NeutralRoles, CustomRoles.BloodKnight); KillCooldown = FloatOptionItem.Create(16110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BloodKnight]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16111, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BloodKnight]); HasImpostorVision = BooleanOptionItem.Create(16113, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BloodKnight]); ProtectDuration = FloatOptionItem.Create(16114, "BKProtectDuration", new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BloodKnight]).SetValueFormat(OptionFormat.Seconds); } public override void Add(byte playerId) { TimeStamp = 0L; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(TimeStamp.ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { reader.ReadByte(); string s = reader.ReadString(); TimeStamp = long.Parse(s); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } private bool InProtect(byte playerId) { return TimeStamp > Utils.GetTimeStamp(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (InProtect(target.PlayerId)) { killer.RpcGuardAndKill(target); if (!Options.DisableShieldAnimations.GetBool()) { target.RpcGuardAndKill(); } target.Notify(Translator.GetString("BKOffsetKill")); return false; } if (killer.GetCustomRole() == target.GetCustomRole()) { return false; } return true; } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!(inMeeting || isSuicide)) { TimeStamp = Utils.GetTimeStamp() + (long)ProtectDuration.GetFloat(); SendRPC(killer.PlayerId); killer.Notify(Translator.GetString("BKInProtect")); } } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if (TimeStamp < Utils.GetTimeStamp() && TimeStamp != 0) { TimeStamp = 0L; pc.Notify(Translator.GetString("BKProtectOut"), 4f, sendInLog: false); } } public override string GetLowerText(PlayerControl pc, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)pc == (Object)null || isForMeeting || !isForHud || !pc.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (InProtect(pc.PlayerId)) { long? num = TimeStamp - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("BKSkillTimeRemain"), num)); } else { stringBuilder.Append(Translator.GetString("BKSkillNotice")); } return stringBuilder.ToString(); } } internal class Collector : RoleBase { private const int Id = 14700; private static OptionItem CollectorCollectAmount; private static readonly Dictionary CollectorVoteFor = new Dictionary(); private int CollectVote; private bool calculated; public static bool HasEnabled => CustomRoles.Collector.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(14700, TabGroup.NeutralRoles, CustomRoles.Collector); CollectorCollectAmount = IntegerOptionItem.Create(14713, "CollectorCollectAmount", new IntegerValueRule(1, 100, 1), 20, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Collector]).SetValueFormat(OptionFormat.Votes); } public override void Init() { calculated = false; } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(CollectVote); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { int collectVote = reader.ReadInt32(); CollectVote = collectVote; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) int collectVote = CollectVote; int @int = CollectorCollectAmount.GetInt(); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Collector).ShadeColor(0.25f)), $"({collectVote}/{@int})"); } public static void Clear() { CollectorVoteFor.Clear(); } public bool CollectorWin(bool check = true) { if ((Object)(object)base._Player != (Object)null && base._Player.IsAlive() && CollectDone(base._Player)) { bool flag = false; if (CustomWinnerHolder.CheckForConvertedWinner(base._Player.PlayerId)) { flag = true; } if (check) { return true; } if (!flag) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Collector); CustomWinnerHolder.WinnerIds.Add(base._Player.PlayerId); } return true; } return false; } private bool CollectDone(PlayerControl player) { if (player.Is(CustomRoles.Collector)) { int collectVote = CollectVote; int @int = CollectorCollectAmount.GetInt(); if (collectVote >= @int) { return true; } } return false; } public static void CollectorVotes(PlayerControl target, PlayerVoteArea ps) { if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Collector)) { CollectorVoteFor.TryAdd(target.PlayerId, ps.TargetPlayerId); } } public override void AfterMeetingTasks() { calculated = false; } public void CollectAmount(Dictionary VotingData, MeetingHud __instance) { if (calculated) { return; } foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)__instance.playerStates) { if ((Object)(object)item == (Object)null) { continue; } PlayerControl playerById = Utils.GetPlayerById(item.TargetPlayerId); if ((Object)(object)playerById == (Object)null) { continue; } foreach (KeyValuePair VotingDatum in VotingData) { if (CollectorVoteFor.ContainsKey(VotingDatum.Key) && playerById.PlayerId == CollectorVoteFor[VotingDatum.Key] && playerById.Is(CustomRoles.Collector)) { int value = VotingDatum.Value; CollectVote += value; SendRPC(); Logger.Info($"{playerById.GetNameWithRole().RemoveHtmlTags()}, collected {value} votes from {Utils.GetPlayerById(VotingDatum.Key).GetNameWithRole().RemoveHtmlTags()}", "Collected votes", escapeCRLF: true, 114, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Collector.cs"); } } Logger.Info($"Total amount of votes collected {CollectVote}", "Collector total amount", escapeCRLF: true, 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Collector.cs"); } calculated = true; } } internal class Cultist : RoleBase { private enum CharmedCountModeSelectList { Cultist_CharmedCountMode_None, Cultist_CharmedCountMode_Cultist, Cultist_CharmedCountMode_Original } private const int Id = 14800; private static OptionItem CharmCooldown; private static OptionItem CharmCooldownIncrese; private static OptionItem CharmMax; private static OptionItem KnowTargetRole; private static OptionItem TargetKnowOtherTarget; private static OptionItem CanCharmNeutral; public static OptionItem CharmedCountMode; public static bool HasEnabled => CustomRoles.Cultist.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public static bool TargetKnowOtherTargets => TargetKnowOtherTarget.GetBool(); public override void SetupCustomOption() { Options.SetupSingleRoleOptions(14800, TabGroup.NeutralRoles, CustomRoles.Cultist); CharmCooldown = FloatOptionItem.Create(14810, "CultistCharmCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]).SetValueFormat(OptionFormat.Seconds); CharmCooldownIncrese = FloatOptionItem.Create(14811, "CultistCharmCooldownIncrese", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]).SetValueFormat(OptionFormat.Seconds); CharmMax = IntegerOptionItem.Create(14812, "CultistCharmMax", new IntegerValueRule(1, 15, 1), 15, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]).SetValueFormat(OptionFormat.Times); KnowTargetRole = BooleanOptionItem.Create(14813, "CultistKnowTargetRole", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]); TargetKnowOtherTarget = BooleanOptionItem.Create(14814, "CultistTargetKnowOtherTarget", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]); CharmedCountMode = StringOptionItem.Create(14817, "Cultist_CharmedCountMode", EnumHelper.GetAllNames(), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]); CanCharmNeutral = BooleanOptionItem.Create(14818, "CultistCanCharmNeutral", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cultist]); } public override void Add(byte playerId) { base.AbilityLimit = CharmMax.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ((base.AbilityLimit >= 1f) ? (CharmCooldown.GetFloat() + ((float)CharmMax.GetInt() - base.AbilityLimit) * CharmCooldownIncrese.GetFloat()) : 300f); } public override bool CanUseKillButton(PlayerControl player) { return base.AbilityLimit >= 1f; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (base.AbilityLimit < 1f) { return false; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if ((CanBeCharmed(target) && Mini.Age == 18) || (CanBeCharmed(target) && Mini.Age < 18 && !target.Is(CustomRoles.NiceMini) && !target.Is(CustomRoles.EvilMini))) { base.AbilityLimit--; SendSkillRPC(); target.RpcSetCustomRole(CustomRoles.Charmed); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CultistCharmedPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CharmedByCultist"))); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); target.RpcGuardAndKill(target); string[] obj = new string[6] { "设置职业:", null, null, null, null, null }; object obj2; if (target == null) { obj2 = null; } else { NetworkedPlayerInfo data = target.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = target.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Charmed.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Charmed, escapeCRLF: true, 83, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Cultist.cs"); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次魅惑机会", "Cultist", escapeCRLF: true, 84, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Cultist.cs"); return false; } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CultistInvalidTarget"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次魅惑机会", "Cultist", escapeCRLF: true, 88, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Cultist.cs"); return false; } public static bool KnowRole(PlayerControl player, PlayerControl target) { if (player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Cultist)) { return true; } if (KnowTargetRole.GetBool()) { if (player.Is(CustomRoles.Cultist) && target.Is(CustomRoles.Charmed)) { return true; } if (TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed)) { return true; } } return false; } public override string GetProgressText(byte playerid, bool cooms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Cultist).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public static bool CanBeCharmed(PlayerControl pc) { if ((Object)(object)pc != (Object)null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || (CanCharmNeutral.GetBool() && pc.GetCustomRole().IsNeutral())) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Infectious) && !pc.Is(CustomRoles.Virus) && !pc.Is(CustomRoles.Cultist)) { if (pc.GetCustomSubRoles().Contains(CustomRoles.Hurried)) { return Hurried.CanBeConverted.GetBool(); } return true; } return false; } public static bool NameRoleColor(PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Cultist)) { return true; } if (seer.Is(CustomRoles.Cultist) && target.Is(CustomRoles.Charmed)) { return true; } if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && TargetKnowOtherTarget.GetBool()) { return true; } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("CultistKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Subbus"); } } internal class CursedSoul : RoleBase { private const int Id = 14000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem CurseCooldown; private static OptionItem CurseCooldownIncrese; private static OptionItem CurseMax; private static OptionItem KnowTargetRole; private static OptionItem CanCurseNeutral; private int CurseLimit; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(14000, TabGroup.NeutralRoles, CustomRoles.CursedSoul); CurseCooldown = FloatOptionItem.Create(14010, "CursedSoulCurseCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedSoul]).SetValueFormat(OptionFormat.Seconds); CurseCooldownIncrese = FloatOptionItem.Create(14011, "CursedSoulCurseCooldownIncrese", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedSoul]).SetValueFormat(OptionFormat.Seconds); CurseMax = IntegerOptionItem.Create(14012, "CursedSoulCurseMax", new IntegerValueRule(1, 15, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedSoul]).SetValueFormat(OptionFormat.Times); KnowTargetRole = BooleanOptionItem.Create(14013, "CursedSoulKnowTargetRole", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedSoul]); CanCurseNeutral = BooleanOptionItem.Create(14016, "CursedSoulCanCurseNeutral", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedSoul]); } public override void Init() { playerIdList.Clear(); CurseLimit = CurseMax.GetInt(); } public override void Add(byte playerId) { playerIdList.Add(playerId); CurseLimit = CurseMax.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)178, (SendOption)1, -1); val.Write(_state.PlayerId); val.Write(CurseLimit); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); if (Main.PlayerStates[key].RoleClass is CursedSoul cursedSoul) { cursedSoul.CurseLimit = reader.ReadInt32(); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ((CurseLimit >= 1) ? (CurseCooldown.GetFloat() + (float)(CurseMax.GetInt() - CurseLimit) * CurseCooldownIncrese.GetFloat()) : 300f); } public override bool CanUseKillButton(PlayerControl player) { return CurseLimit >= 1; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (CurseLimit < 1) { return false; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if (CanBeSoulless(target)) { CurseLimit--; SendRPC(); target.RpcSetCustomRole(CustomRoles.Soulless); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.CursedSoul)), Translator.GetString("CursedSoulSoullessPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.CursedSoul)), Translator.GetString("SoullessByCursedSoul"))); Utils.NotifyRoles(target, killer); Utils.NotifyRoles(killer, target); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } string[] obj = new string[6] { "设置职业:", null, null, null, null, null }; object obj2; if (target == null) { obj2 = null; } else { NetworkedPlayerInfo data = target.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = target.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Soulless.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Soulless, escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\CursedSoul.cs"); Logger.Info($"{killer.GetNameWithRole()} : 剩余{CurseLimit}次魅惑机会", "CursedSoul", escapeCRLF: true, 97, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\CursedSoul.cs"); return false; } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.CursedSoul)), Translator.GetString("CursedSoulInvalidTarget"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{CurseLimit}次魅惑机会", "CursedSoul", escapeCRLF: true, 101, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\CursedSoul.cs"); return false; } public override bool KnowRoleTarget(PlayerControl player, PlayerControl target) { if (player.Is(CustomRoles.CursedSoul)) { return target.Is(CustomRoles.Soulless); } return false; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!KnowRoleTarget(seer, target)) { return string.Empty; } return Main.roleColors[CustomRoles.Soulless]; } public override string GetProgressText(byte id, bool cooms) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((CurseLimit >= 1) ? Utils.GetRoleColor(CustomRoles.CursedSoul) : Color.gray), $"({CurseLimit})"); } private static bool CanBeSoulless(PlayerControl pc) { if ((Object)(object)pc != (Object)null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || (CanCurseNeutral.GetBool() && pc.GetCustomRole().IsNeutral())) && !pc.Is(CustomRoles.Soulless) && !pc.Is(CustomRoles.Admired)) { return !pc.Is(CustomRoles.Loyal); } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("CursedSoulKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Soul"); } } internal class Demon : RoleBase { private const int Id = 16200; private static readonly Dictionary PlayerHealth = new Dictionary(); private static readonly Dictionary DemonHealth = new Dictionary(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem HealthMax; private static OptionItem Damage; private static OptionItem SelfHealthMax; private static OptionItem SelfDamage; public static bool HasEnabled => CustomRoles.Demon.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16200, TabGroup.NeutralRoles, CustomRoles.Demon); KillCooldown = FloatOptionItem.Create(16210, "DemonKillCooldown", new FloatValueRule(1f, 180f, 1f), 2f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16211, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]); HasImpostorVision = BooleanOptionItem.Create(16213, GeneralOption.ImpostorVision, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]); HealthMax = IntegerOptionItem.Create(16215, "DemonHealthMax", new IntegerValueRule(5, 200, 5), 100, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]).SetValueFormat(OptionFormat.Health); Damage = IntegerOptionItem.Create(16216, "DemonDamage", new IntegerValueRule(1, 100, 1), 15, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]).SetValueFormat(OptionFormat.Health); SelfHealthMax = IntegerOptionItem.Create(16217, "DemonSelfHealthMax", new IntegerValueRule(100, 100, 5), 100, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]).SetValueFormat(OptionFormat.Health); SelfDamage = IntegerOptionItem.Create(16218, "DemonSelfDamage", new IntegerValueRule(1, 100, 1), 35, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Demon]).SetValueFormat(OptionFormat.Health); } public override void Init() { DemonHealth.Clear(); PlayerHealth.Clear(); } public override void Add(byte playerId) { DemonHealth.Add(playerId, SelfHealthMax.GetInt()); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { PlayerHealth[val.PlayerId] = HealthMax.GetInt(); } if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { DemonHealth.Remove(playerId); PlayerHealth.Clear(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl player) { return CanVent.GetBool(); } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); if (DemonHealth.ContainsKey(playerId)) { val.Write(DemonHealth[playerId]); } else { val.Write(PlayerHealth[playerId]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); if (DemonHealth.ContainsKey(key)) { DemonHealth[key] = value; } else { PlayerHealth[key] = value; } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || !killer.Is(CustomRoles.Demon) || target.Is(CustomRoles.Demon) || !PlayerHealth.ContainsKey(target.PlayerId)) { return false; } killer.SetKillCooldown(); if (PlayerHealth[target.PlayerId] - Damage.GetInt() < 1) { PlayerHealth.Remove(target.PlayerId); killer.RpcMurderPlayer(target); Utils.NotifyRoles(killer); return false; } PlayerHealth[target.PlayerId] -= Damage.GetInt(); SendRPC(target.PlayerId); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); Utils.NotifyRoles(killer); Logger.Info($"Demon {killer.GetRealName()} dealt {target.GetRealName()} damage equal to {Damage.GetInt()}", "Demon", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Demon.cs"); return false; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (killer.Is(CustomRoles.Pestilence)) { return true; } if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return true; } if (DemonHealth.TryGetValue(target.PlayerId, out var value) && value - SelfDamage.GetInt() < 1) { DemonHealth.Remove(target.PlayerId); Utils.NotifyRoles(target); return true; } killer.SetKillCooldown(); if (!DemonHealth.ContainsKey(target.PlayerId)) { DemonHealth.Add(target.PlayerId, SelfHealthMax.GetInt()); value = SelfHealthMax.GetInt(); } DemonHealth[target.PlayerId] = value - SelfDamage.GetInt(); SendRPC(target.PlayerId); RPC.PlaySoundRPC(target.PlayerId, Sounds.KillSound); killer.RpcGuardAndKill(target); Utils.NotifyRoles(target); Logger.Info($"{killer.GetRealName()} try kill {target.GetRealName()} but get damage {SelfDamage.GetInt()}", "Demon", escapeCRLF: true, 140, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Demon.cs"); return false; } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!seer.Is(CustomRoles.Demon) || !seer.IsAlive()) { return string.Empty; } if ((Object)(object)target != (Object)null && seer.PlayerId == target.PlayerId) { if (!DemonHealth.TryGetValue(target.PlayerId, out var value) || value <= 0) { return string.Empty; } return Utils.ColorString(GetColor(value, self: true), $"【{value}/{SelfHealthMax.GetInt()}】"); } if (!PlayerHealth.TryGetValue(target.PlayerId, out var value2) || value2 <= 0) { return string.Empty; } return Utils.ColorString(GetColor(value2), $"【{value2}/{HealthMax.GetInt()}】"); } private static Color32 GetColor(float Health, bool self = false) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) int num = (int)(Health / (float)(self ? SelfHealthMax.GetInt() : HealthMax.GetInt()) * 10f * 50f); int num2 = 255; int num3 = 255; int num4 = 0; if (num > 255) { num2 -= num - 255; } else { num3 = num; } return new Color32((byte)num2, (byte)num3, (byte)num4, byte.MaxValue); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("DemonButtonText")); } } internal class Doomsayer : RoleBase { private const int Id = 14100; private readonly HashSet GuessedRoles = new HashSet(); private readonly Dictionary GuessingToWin = new Dictionary(); private int GuessesCount; private int GuessesCountPerMeeting; private static bool CantGuess = false; private static OptionItem DoomsayerAmountOfGuessesToWin; private static OptionItem DCanGuessImpostors; private static OptionItem DCanGuessCrewmates; private static OptionItem DCanGuessNeutrals; private static OptionItem DCanGuessAdt; private static OptionItem AdvancedSettings; private static OptionItem MaxNumberOfGuessesPerMeeting; private static OptionItem KillCorrectlyGuessedPlayers; public static OptionItem DoesNotSuicideWhenMisguessing; private static OptionItem MisguessRolePrevGuessRoleUntilNextMeeting; private static OptionItem DoomsayerTryHideMsg; private static OptionItem ImpostorVision; public static bool CheckCantGuess = CantGuess; public static bool HasEnabled => CustomRoles.Doomsayer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { //IL_01fb: Unknown result type (might be due to invalid IL or missing references) Options.SetupSingleRoleOptions(14100, TabGroup.NeutralRoles, CustomRoles.Doomsayer); DoomsayerAmountOfGuessesToWin = IntegerOptionItem.Create(14110, "DoomsayerAmountOfGuessesToWin", new IntegerValueRule(1, 10, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]).SetValueFormat(OptionFormat.Times); DCanGuessImpostors = BooleanOptionItem.Create(14112, "DCanGuessImpostors", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); DCanGuessCrewmates = BooleanOptionItem.Create(14113, "DCanGuessCrewmates", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); DCanGuessNeutrals = BooleanOptionItem.Create(14114, "DCanGuessNeutrals", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); DCanGuessAdt = BooleanOptionItem.Create(14115, "DCanGuessAdt", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); AdvancedSettings = BooleanOptionItem.Create(14116, "DoomsayerAdvancedSettings", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); MaxNumberOfGuessesPerMeeting = IntegerOptionItem.Create(14123, "DoomsayerMaxNumberOfGuessesPerMeeting", new IntegerValueRule(1, 10, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(AdvancedSettings); KillCorrectlyGuessedPlayers = BooleanOptionItem.Create(14118, "DoomsayerKillCorrectlyGuessedPlayers", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(AdvancedSettings); DoesNotSuicideWhenMisguessing = BooleanOptionItem.Create(14124, "DoomsayerDoesNotSuicideWhenMisguessing", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(AdvancedSettings); MisguessRolePrevGuessRoleUntilNextMeeting = BooleanOptionItem.Create(14120, "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(DoesNotSuicideWhenMisguessing); ImpostorVision = BooleanOptionItem.Create(14125, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); DoomsayerTryHideMsg = BooleanOptionItem.Create(14121, "DoomsayerTryHideMsg", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetColor(Color.green).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doomsayer]); } public override void Init() { CantGuess = false; } public override void Add(byte playerId) { GuessingToWin.TryAdd(playerId, GuessesCount); } public void SendRPC(PlayerControl player) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(player.PlayerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); GuessingToWin[key]++; } private (int, int) GuessedPlayerCount(byte doomsayerId) { int item = GuessingToWin[doomsayerId]; int @int = DoomsayerAmountOfGuessesToWin.GetInt(); return (item, @int); } public override string GetProgressText(byte playerId, bool comms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) var (value, value2) = GuessedPlayerCount(playerId); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer).ShadeColor(0.25f)), $"({value}/{value2})"); } public static bool NeedHideMsg(PlayerControl pc) { if (pc.Is(CustomRoles.Doomsayer)) { return DoomsayerTryHideMsg.GetBool(); } return false; } private void CheckCountGuess(PlayerControl doomsayer) { if (GuessingToWin[doomsayer.PlayerId] >= DoomsayerAmountOfGuessesToWin.GetInt()) { GuessingToWin[doomsayer.PlayerId] = DoomsayerAmountOfGuessesToWin.GetInt(); GuessesCount = DoomsayerAmountOfGuessesToWin.GetInt(); if (!CustomWinnerHolder.CheckForConvertedWinner(doomsayer.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Doomsayer); CustomWinnerHolder.WinnerIds.Add(doomsayer.PlayerId); } } } public override void OnReportDeadBody(PlayerControl goku, NetworkedPlayerInfo solos) { if (AdvancedSettings.GetBool()) { CantGuess = false; GuessesCountPerMeeting = 0; } } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer)), target.PlayerId.ToString()) + " " + TargetPlayerName; } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public static bool HideTabInGuesserUI(int TabId) { if (!DCanGuessCrewmates.GetBool() && TabId == 0) { return true; } if (!DCanGuessImpostors.GetBool() && TabId == 1) { return true; } if (!DCanGuessNeutrals.GetBool() && TabId == 2) { return true; } if (!DCanGuessAdt.GetBool() && TabId == 3) { return true; } return false; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (CheckCantGuess) { guesser.ShowInfoMessage(isUI, Translator.GetString("DoomsayerCantGuess")); return true; } if (role.IsImpostor() && !DCanGuessImpostors.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (role.IsCrewmate() && !DCanGuessCrewmates.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (role.IsNeutral() && !DCanGuessNeutrals.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessNotAllowed")); return true; } if (role.IsAdditionRole() && !DCanGuessAdt.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } return false; } public override bool CheckMisGuessed(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (target.Is(CustomRoles.Rebound) && guesser.Is(CustomRoles.Doomsayer) && !DoesNotSuicideWhenMisguessing.GetBool() && !GuessedRoles.Contains(role)) { guesserSuicide = true; Logger.Info(guesser.GetNameWithRole().RemoveHtmlTags() + " guessed " + target.GetNameWithRole().RemoveHtmlTags() + ", doomsayer suicide because rebound", "GuessManager", escapeCRLF: true, 182, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Doomsayer.cs"); } else if (AdvancedSettings.GetBool()) { if (GuessesCountPerMeeting >= MaxNumberOfGuessesPerMeeting.GetInt() && guesser.PlayerId != target.PlayerId) { guesser.ShowInfoMessage(isUI, Translator.GetString("DoomsayerCantGuess")); return true; } GuessesCountPerMeeting++; if (GuessesCountPerMeeting >= MaxNumberOfGuessesPerMeeting.GetInt()) { CantGuess = true; } if (!KillCorrectlyGuessedPlayers.GetBool() && guesser.PlayerId != target.PlayerId) { guesser.ShowInfoMessage(isUI, Translator.GetString("DoomsayerCorrectlyGuessRole")); if (GuessedRoles.Contains(role)) { new LateTask(delegate { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(Translator.GetString("DoomsayerGuessSameRoleAgainMsg"), guesser.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer)), Translator.GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Same Role Again Msg"); } else { GuessingToWin[guesser.PlayerId]++; SendRPC(guesser); GuessedRoles.Add(role); new LateTask(delegate { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("DoomsayerGuessCountMsg"), GuessingToWin[guesser.PlayerId]), guesser.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer)), Translator.GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Msg 1"); } CheckCountGuess(guesser); return true; } if (DoesNotSuicideWhenMisguessing.GetBool() && guesser.PlayerId == target.PlayerId) { guesser.ShowInfoMessage(isUI, Translator.GetString("DoomsayerNotCorrectlyGuessRole")); if (MisguessRolePrevGuessRoleUntilNextMeeting.GetBool()) { CantGuess = true; } return true; } } return false; } public void SendMessageAboutGuess(PlayerControl guesser, PlayerControl playerMisGuessed, CustomRoles role) { if (guesser.Is(CustomRoles.Doomsayer) && guesser.PlayerId != playerMisGuessed.PlayerId) { GuessingToWin[guesser.PlayerId]++; SendRPC(guesser); if (!GuessedRoles.Contains(role)) { GuessedRoles.Add(role); } CheckCountGuess(guesser); new LateTask(delegate { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("DoomsayerGuessCountMsg"), GuessingToWin[guesser.PlayerId]), guesser.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Doomsayer)), Translator.GetString("DoomsayerGuessCountTitle"))); }, 0.7f, "Doomsayer Guess Msg 2"); } } } internal class Doppelganger : RoleBase { private const int Id = 25000; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem MaxSteals; public static readonly Dictionary DoppelVictim = new Dictionary(); public static readonly Dictionary DoppelPresentSkin = new Dictionary(); public static bool HasEnabled => CustomRoles.Doppelganger.HasEnabled(); public override bool IsExperimental => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(25000, TabGroup.NeutralRoles, CustomRoles.Doppelganger); MaxSteals = IntegerOptionItem.Create(25010, "DoppelMaxSteals", new IntegerValueRule(1, 14, 1), 9, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doppelganger]); KillCooldown = FloatOptionItem.Create(25011, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doppelganger]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(25012, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doppelganger]); HasImpostorVision = BooleanOptionItem.Create(25013, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doppelganger]); } public override void Add(byte playerId) { base.AbilityLimit = MaxSteals.GetInt(); DoppelVictim[playerId] = Utils.GetPlayerById(playerId).GetRealName() ?? "Invalid"; if (((InnerNetClient)AmongUsClient.Instance).AmHost && !Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public static bool CheckDoppelVictim(byte playerId) { return DoppelVictim.ContainsKey(playerId); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || Camouflage.IsCamouflage || Camouflager.AbilityActivated || Utils.IsActive((SystemTypes)57)) { return true; } if (Main.CheckShapeshift.TryGetValue(target.PlayerId, out var value) && value) { Logger.Info("Target was shapeshifting", "Doppelganger", escapeCRLF: true, 58, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Doppelganger.cs"); return true; } if (base.AbilityLimit < 1f) { return true; } base.AbilityLimit--; string realName = killer.GetRealName(isMeeting: true); string realName2 = target.GetRealName(isMeeting: true); PlayerOutfit val = PlayerOutfitExtension.Set(new PlayerOutfit(), realName, killer.CurrentOutfit.ColorId, killer.CurrentOutfit.HatId, killer.CurrentOutfit.SkinId, killer.CurrentOutfit.VisorId, killer.CurrentOutfit.PetId, killer.CurrentOutfit.NamePlateId); uint playerLevel = Utils.GetPlayerInfoById(killer.PlayerId).PlayerLevel; PlayerOutfit val2 = PlayerOutfitExtension.Set(new PlayerOutfit(), realName2, target.CurrentOutfit.ColorId, target.CurrentOutfit.HatId, target.CurrentOutfit.SkinId, target.CurrentOutfit.VisorId, target.CurrentOutfit.PetId, target.CurrentOutfit.NamePlateId); uint playerLevel2 = Utils.GetPlayerInfoById(target.PlayerId).PlayerLevel; DoppelVictim[target.PlayerId] = realName2; target.SetNewOutfit(val, setName: true, setNamePlate: true, playerLevel); DoppelPresentSkin[target.PlayerId] = val; Logger.Info("Changed target skin", "Doppelganger", escapeCRLF: true, 83, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Doppelganger.cs"); killer.SetNewOutfit(val2, setName: true, setNamePlate: true, playerLevel2); DoppelPresentSkin[killer.PlayerId] = val2; Logger.Info("Changed killer skin", "Doppelganger", escapeCRLF: true, 87, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Doppelganger.cs"); SendSkillRPC(); RPC.SyncAllPlayerNames(); Utils.DoNotifyRoles(null, null, isForMeeting: false, NoCache: true); killer.ResetKillCooldown(); killer.SetKillCooldown(); return true; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Doppelganger).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class Executioner : RoleBase { private enum ChangeRolesSelectList { Role_Crewmate, Role_Celebrity, Role_Bodyguard, Role_Dictator, Role_Mayor, Role_Doctor, Role_Jester, Role_Opportunist } private const int Id = 14200; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem CanTargetImpostor; private static OptionItem CanTargetNeutralKiller; private static OptionItem CanTargetNeutralBenign; private static OptionItem CanTargetNeutralEvil; private static OptionItem CanTargetNeutralChaos; private static OptionItem KnowTargetRole; private static OptionItem ChangeRolesAfterTargetKilled; public static readonly Dictionary Target = new Dictionary(); public static readonly CustomRoles[] CRoleChangeRoles = new CustomRoles[8] { CustomRoles.CrewmateTOHE, CustomRoles.Celebrity, CustomRoles.Bodyguard, CustomRoles.Dictator, CustomRoles.Mayor, CustomRoles.Doctor, CustomRoles.Jester, CustomRoles.Opportunist }; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupRoleOptions(14200, TabGroup.NeutralRoles, CustomRoles.Executioner); CanTargetImpostor = BooleanOptionItem.Create(14210, "ExecutionerCanTargetImpostor", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); CanTargetNeutralKiller = BooleanOptionItem.Create(14212, "ExecutionerCanTargetNeutralKiller", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); CanTargetNeutralBenign = BooleanOptionItem.Create(14214, "ExecutionerCanTargetNeutralBenign", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); CanTargetNeutralEvil = BooleanOptionItem.Create(14215, "ExecutionerCanTargetNeutralEvil", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); CanTargetNeutralChaos = BooleanOptionItem.Create(14216, "ExecutionerCanTargetNeutralChaos", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); KnowTargetRole = BooleanOptionItem.Create(14213, "KnowTargetRole", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); ChangeRolesAfterTargetKilled = StringOptionItem.Create(14211, "ExecutionerChangeRolesAfterTargetKilled", EnumHelper.GetAllNames(), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Executioner]); } public override void Init() { playerIdList.Clear(); Target.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } CustomRoleManager.CheckDeadBodyOthers.Add(OnOthersDead); List list = new List(); _ = IRandom.Instance; PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (playerId != val.PlayerId && (CanTargetImpostor.GetBool() || !val.Is(Custom_Team.Impostor)) && (CanTargetNeutralKiller.GetBool() || !val.GetCustomRole().IsNK()) && (CanTargetNeutralBenign.GetBool() || !val.GetCustomRole().IsNB()) && (CanTargetNeutralEvil.GetBool() || !val.GetCustomRole().IsNE()) && (CanTargetNeutralChaos.GetBool() || !val.GetCustomRole().IsNC())) { bool flag; switch (val.GetCustomRole()) { case CustomRoles.EvilMini: case CustomRoles.NiceMini: case CustomRoles.SuperStar: case CustomRoles.GM: flag = true; break; default: flag = false; break; } if (!flag && (!Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) || !val.Is(CustomRoles.Lovers))) { list.Add(val); } } } if (list.Any()) { PlayerControl val2 = list.RandomElement(); Target.Add(playerId, val2.PlayerId); SendRPC(playerId, val2.PlayerId, "SetTarget"); Logger.Info(Utils.GetPlayerById(playerId)?.GetNameWithRole() + ":" + val2.GetNameWithRole(), "Executioner", escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Executioner.cs"); } else { Logger.Warn(" Warning! No suitableable target was found for executioner, switching role", "Executioner.Add", escapeCRLF: true, 100, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Executioner.cs"); ChangeRole(Utils.GetPlayerById(playerId)); } } public static void SendRPC(byte executionerId, byte targetId = 115, string Progress = "") { if (!(Progress == "SetTarget")) { if (Progress == null || Progress.Length != 0) { if (Progress == "WinCheck" && CustomWinnerHolder.WinnerTeam == CustomWinner.Default && !CustomWinnerHolder.CheckForConvertedWinner(executionerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Executioner); CustomWinnerHolder.WinnerIds.Add(executionerId); } } else if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)145, (SendOption)1, -1); val.Write(executionerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)144, (SendOption)1, -1); val.Write(executionerId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader, bool SetTarget) { if (SetTarget) { byte key = reader.ReadByte(); byte value = reader.ReadByte(); Target[key] = value; } else { Target.Remove(reader.ReadByte()); } } public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { int value = ChangeRolesAfterTargetKilled.GetValue(); if ((uint)(value - 6) > 1u) { return !ForRecompute; } return false; } public static void ChangeRoleByTarget(PlayerControl target) { byte ExecutionerId = 115; CollectionExtensions.Do>((IEnumerable>)Target, (Action>)delegate(KeyValuePair x) { if (x.Value == target.PlayerId) { ExecutionerId = x.Key; } }); PlayerControl playerById = Utils.GetPlayerById(ExecutionerId); playerById.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]); playerIdList.Remove(ExecutionerId); Target.Remove(ExecutionerId); SendRPC(ExecutionerId, 115); playerById.GetRoleClass().OnAdd(ExecutionerId); Utils.NotifyRoles(playerById); } public static void ChangeRole(PlayerControl executioner) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) executioner.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]); playerIdList.Remove(executioner.PlayerId); Target.Remove(executioner.PlayerId); SendRPC(executioner.PlayerId, 115); string format = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Executioner)), Translator.GetString("")); format = string.Format(format, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()])), Translator.GetString(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()].ToString()))); executioner.Notify(format); try { executioner.GetRoleClass().OnAdd(executioner.PlayerId); } catch (Exception value) { Logger.Warn($"Error after attempting to RoleCLass.Add({executioner.GetCustomRole().ToString().RemoveHtmlTags() + ", " + executioner.GetRealName()}.PlayerId): {value}", "Executioner.ChangeRole.Add", escapeCRLF: true, 179, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Executioner.cs"); } } public static bool CheckTarget(byte targetId) { return Target.ContainsValue(targetId); } public static bool IsTarget(byte executionerId, byte targetId) { if (Target.TryGetValue(executionerId, out var value)) { return value == targetId; } return false; } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (Target.ContainsKey(target.PlayerId)) { Target.Remove(target.PlayerId); SendRPC(target.PlayerId, 115); } } private void OnOthersDead(PlayerControl killer, PlayerControl target, bool inMeeting) { if (CheckTarget(target.PlayerId)) { ChangeRoleByTarget(target); } } public override bool KnowRoleTarget(PlayerControl player, PlayerControl target) { if (!KnowTargetRole.GetBool()) { return false; } if (player.Is(CustomRoles.Executioner) && Target.TryGetValue(player.PlayerId, out var value)) { return value == target.PlayerId; } return false; } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || !seer.IsAlive()) { return string.Empty; } if (!Target.TryGetValue(seer.PlayerId, out var value) || value != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Executioner)), "♦"); } public override void CheckExileTarget(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { foreach (KeyValuePair item in Target.Where((KeyValuePair x) => x.Value == exiled.PlayerId)) { PlayerControl playerById = Utils.GetPlayerById(item.Key); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && !playerById.Data.Disconnected) { if (isMeetingHud) { name = string.Format(Translator.GetString("ExiledExeTarget"), Main.LastVotedPlayer, Utils.GetDisplayRoleAndSubName(exiled.PlayerId, exiled.PlayerId, notShowAddOns: true)); } else { ExeWin(item.Key, DecidedWinner); } DecidedWinner = true; } } } private static void ExeWin(byte playerId, bool DecidedWinner) { if (!DecidedWinner) { SendRPC(playerId, 115, "WinCheck"); return; } CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Executioner); CustomWinnerHolder.WinnerIds.Add(playerId); } } internal class Follower : RoleBase { private const int Id = 12800; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem MaxBetTimes; private static OptionItem BetCooldown; private static OptionItem BetCooldownIncrese; private static OptionItem MaxBetCooldown; private static OptionItem KnowTargetRole; private static OptionItem BetTargetKnowFollower; private static readonly Dictionary BetTimes = new Dictionary(); public static readonly Dictionary BetPlayer = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(12800, TabGroup.NeutralRoles, CustomRoles.Follower); MaxBetTimes = IntegerOptionItem.Create(12810, "FollowerMaxBetTimes", new IntegerValueRule(1, 20, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]).SetValueFormat(OptionFormat.Times); BetCooldown = FloatOptionItem.Create(12812, "FollowerBetCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]).SetValueFormat(OptionFormat.Seconds); BetCooldownIncrese = FloatOptionItem.Create(12814, "FollowerBetCooldownIncrese", new FloatValueRule(0f, 60f, 1f), 4f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]).SetValueFormat(OptionFormat.Seconds); MaxBetCooldown = FloatOptionItem.Create(12816, "FollowerMaxBetCooldown", new FloatValueRule(0f, 180f, 2.5f), 50f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]).SetValueFormat(OptionFormat.Seconds); KnowTargetRole = BooleanOptionItem.Create(12818, "FollowerKnowTargetRole", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]); BetTargetKnowFollower = BooleanOptionItem.Create(12820, "FollowerBetTargetKnowFollower", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Follower]); } public override void Init() { playerIdList.Clear(); BetTimes.Clear(); BetPlayer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); BetTimes.Add(playerId, MaxBetTimes.GetInt()); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(BetTimes.TryGetValue(playerId, out var value) ? value : MaxBetTimes.GetInt()); val.Write(BetPlayer.TryGetValue(playerId, out var value2) ? value2 : byte.MaxValue); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); byte b = reader.ReadByte(); BetTimes.Remove(key); BetPlayer.Remove(key); BetTimes.Add(key, value); if (b != byte.MaxValue) { BetPlayer.Add(key, b); } } private static bool CanKillButton(PlayerControl player) { if (!player.Data.IsDead) { if (BetTimes.TryGetValue(player.PlayerId, out var value)) { return value >= 1; } return true; } return false; } public override bool CanUseKillButton(PlayerControl player) { return CanKillButton(player); } public override void SetKillCooldown(byte id) { if (BetTimes.TryGetValue(id, out var value) && value < 1) { Main.AllPlayerKillCooldown[id] = 300f; return; } float @float = BetCooldown.GetFloat(); @float += (float)Main.AllPlayerControls.Count((PlayerControl x) => !x.IsAlive()) * BetCooldownIncrese.GetFloat(); @float = Math.Min(@float, MaxBetCooldown.GetFloat()); Main.AllPlayerKillCooldown[id] = @float; } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { if (!KnowTargetRole.GetBool()) { return false; } if (seer.Is(CustomRoles.Follower) && BetPlayer.TryGetValue(seer.PlayerId, out var value)) { return value == target.PlayerId; } return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (killer.PlayerId == target.PlayerId) { return true; } if (BetPlayer.TryGetValue(killer.PlayerId, out var value) && value == target.PlayerId) { return false; } if (!BetTimes.TryGetValue(killer.PlayerId, out var value2) || value2 < 1) { return false; } BetTimes[killer.PlayerId]--; if (BetPlayer.TryGetValue(killer.PlayerId, out var value3) && (Object)(object)Utils.GetPlayerById(value3) != (Object)null) { Utils.NotifyRoles(killer, Utils.GetPlayerById(value3)); Utils.NotifyRoles(Utils.GetPlayerById(value3), killer); } BetPlayer.Remove(killer.PlayerId); BetPlayer.Add(killer.PlayerId, target.PlayerId); SendRPC(killer.PlayerId); killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Bet"); killer.Notify(Translator.GetString("FollowerBetPlayer")); if (BetTargetKnowFollower.GetBool()) { target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Follower)), Translator.GetString("FollowerBetOnYou"))); } Logger.Info(" " + killer.GetNameWithRole() + " => " + target.GetNameWithRole(), "Follower", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Follower.cs"); return false; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return string.Empty; } if (!seer.Is(CustomRoles.Follower)) { if (!BetTargetKnowFollower.GetBool()) { return ""; } if (!BetPlayer.TryGetValue(target.PlayerId, out var value) || seer.PlayerId != value) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Follower)), "♦"); } if (!BetPlayer.TryGetValue(seer.PlayerId, out var value2) || value2 != target.PlayerId) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Follower)), "♦"); } public override string GetProgressText(byte playerId, bool coooms) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null) { return null; } Color32 color = Color32.op_Implicit(CanKillButton(playerById) ? Utils.GetRoleColor(CustomRoles.Follower) : Color.gray); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(2, 1); defaultInterpolatedStringHandler.AppendLiteral("("); defaultInterpolatedStringHandler.AppendFormatted(BetTimes.TryGetValue(playerId, out var value) ? ((object)value) : "0"); defaultInterpolatedStringHandler.AppendLiteral(")"); return Utils.ColorString(color, defaultInterpolatedStringHandler.ToStringAndClear()); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("FollowerKillButtonText")); } } internal class Glitch : RoleBase { private const int Id = 16300; private static readonly Dictionary hackedIdList = new Dictionary(); public static OptionItem KillCooldown; private static OptionItem HackCooldown; private static OptionItem HackDuration; private static OptionItem MimicCooldown; private static OptionItem MimicDuration; private static OptionItem CanVent; private static OptionItem HasImpostorVision; public int HackCDTimer; public int KCDTimer; public int MimicCDTimer; public int MimicDurTimer; public long LastHack; public long LastKill; public long LastMimic; private bool isShifted; private long lastRpcSend; public static bool HasEnabled => CustomRoles.Glitch.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16300, TabGroup.NeutralRoles, CustomRoles.Glitch); KillCooldown = FloatOptionItem.Create(16310, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 1f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]).SetValueFormat(OptionFormat.Seconds); HackCooldown = IntegerOptionItem.Create(16311, "Glitch_HackCooldown", new IntegerValueRule(0, 180, 1), 20, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]).SetValueFormat(OptionFormat.Seconds); HackDuration = FloatOptionItem.Create(16314, "Glitch_HackDuration", new FloatValueRule(0f, 60f, 1f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]).SetValueFormat(OptionFormat.Seconds); MimicCooldown = IntegerOptionItem.Create(16315, "Glitch_MimicCooldown", new IntegerValueRule(0, 180, 1), 15, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]).SetValueFormat(OptionFormat.Seconds); MimicDuration = FloatOptionItem.Create(16316, "Glitch_MimicDuration", new FloatValueRule(0f, 60f, 1f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16312, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]); HasImpostorVision = BooleanOptionItem.Create(16313, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glitch]); } public override void Add(byte playerId) { HackCDTimer = 10; KCDTimer = 10; MimicCDTimer = 10; MimicDurTimer = 0; isShifted = false; lastRpcSend = (LastMimic = (LastHack = (LastKill = Utils.GetTimeStamp()))); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } Utils.GetPlayerById(playerId).AddDoubleTrigger(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = 1f; } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public void Mimic(PlayerControl pc) { if ((Object)(object)pc == (Object)null || !pc.IsAlive() || MimicCDTimer > 0 || isShifted) { return; } List list = Main.AllAlivePlayerControls.Where((PlayerControl a) => a.PlayerId != pc.PlayerId).ToList(); try { pc.RpcShapeshift(list[IRandom.Instance.Next(0, list.Count)], false); isShifted = true; LastMimic = Utils.GetTimeStamp(); MimicCDTimer = MimicCooldown.GetInt(); MimicDurTimer = MimicDuration.GetInt(); } catch (Exception ex) { Logger.Error(ex.ToString(), "Glitch.Mimic.RpcShapeshift", escapeCRLF: true, 106, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Glitch.cs"); } } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null) { return false; } if ((Object)(object)target == (Object)null) { return false; } if (KCDTimer > 0 && HackCDTimer > 0) { return false; } if (killer.CheckDoubleTrigger(target, delegate { if (HackCDTimer <= 0) { Utils.NotifyRoles(killer); HackCDTimer = HackCooldown.GetInt(); hackedIdList.TryAdd(target.PlayerId, Utils.GetTimeStamp()); LastHack = Utils.GetTimeStamp(); } })) { if (KCDTimer > 0) { return false; } LastKill = Utils.GetTimeStamp(); KCDTimer = KillCooldown.GetInt(); return true; } return false; } public override void OnFixedUpdateLowLoad(PlayerControl player) { //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) if (HackCDTimer > 180 || HackCDTimer < 0) { HackCDTimer = 0; } if (KCDTimer > 180 || KCDTimer < 0) { KCDTimer = 0; } if (MimicCDTimer > 180 || MimicCDTimer < 0) { MimicCDTimer = 0; } if (MimicDurTimer > 180 || MimicDurTimer < 0) { MimicDurTimer = 0; } bool flag = false; foreach (KeyValuePair hackedId in hackedIdList) { if (hackedId.Value + HackDuration.GetInt() < Utils.GetTimeStamp()) { hackedIdList.Remove(hackedId.Key); flag = true; } } if ((Object)(object)player == (Object)null || !player.Is(CustomRoles.Glitch)) { return; } if (flag) { Utils.NotifyRoles(player, null, isForMeeting: false, NoCache: false, ForceLoop: false); } if (!player.IsAlive()) { HackCDTimer = 0; KCDTimer = 0; MimicCDTimer = 0; MimicDurTimer = 0; if (lastRpcSend <= Utils.GetTimeStamp() + 500) { SendRPC(); lastRpcSend += 9999L; } return; } if (MimicDurTimer > 0) { try { MimicDurTimer = (int)(MimicDuration.GetInt() - (Utils.GetTimeStamp() - LastMimic)); } catch { MimicDurTimer = 0; } if (MimicDurTimer > 180) { MimicDurTimer = 0; } } if ((MimicDurTimer <= 0 || !GameStates.IsInTask) && isShifted) { try { player.RpcShapeshift(player, false); isShifted = false; } catch (Exception ex) { Logger.Error(ex.ToString(), "Glitch.Mimic.RpcRevertShapeshift", escapeCRLF: true, 190, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Glitch.cs"); } if (!GameStates.IsInTask) { MimicDurTimer = 0; } } if (HackCDTimer <= 0 && KCDTimer <= 0 && MimicCDTimer <= 0 && MimicDurTimer <= 0) { return; } try { HackCDTimer = (int)(HackCooldown.GetInt() - (Utils.GetTimeStamp() - LastHack)); } catch { HackCDTimer = 0; } if (HackCDTimer > 180 || HackCDTimer < 0) { HackCDTimer = 0; } try { KCDTimer = (int)(KillCooldown.GetInt() - (Utils.GetTimeStamp() - LastKill)); } catch { KCDTimer = 0; } if (KCDTimer > 180 || KCDTimer < 0) { KCDTimer = 0; } try { MimicCDTimer = (int)(MimicCooldown.GetInt() - (Utils.GetTimeStamp() - LastMimic)); } catch { MimicCDTimer = 0; } if (MimicCDTimer > 180 || MimicCDTimer < 0) { MimicCDTimer = 0; } if (!player.IsModClient()) { string text = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Glitch)), player.GetRealName(isMeeting: true)); if (!NameNotifyManager.Notice.TryGetValue(player.PlayerId, out var value) || value.Item1 != text) { player.Notify(text, 1.1f); } } if (!((InnerNetObject)player).AmOwner && lastRpcSend < Utils.GetTimeStamp()) { SendRPC(); lastRpcSend = Utils.GetTimeStamp(); } } public override string GetLowerText(PlayerControl player, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)player == (Object)null) { return string.Empty; } if (!player.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(string.Empty); if (MimicDurTimer > 0) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(string.Format(Translator.GetString("Glitch_MimicDur"), MimicDurTimer)); handler.AppendLiteral("\n"); stringBuilder3.Append(ref handler); } if (MimicCDTimer > 0 && MimicDurTimer <= 0) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(string.Format(Translator.GetString("Glitch_MimicCD"), MimicCDTimer)); handler.AppendLiteral("\n"); stringBuilder4.Append(ref handler); } if (HackCDTimer > 0) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder5 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(string.Format(Translator.GetString("Glitch_HackCD"), HackCDTimer)); handler.AppendLiteral("\n"); stringBuilder5.Append(ref handler); } if (KCDTimer > 0) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder6 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(1, 1, stringBuilder2); handler.AppendFormatted(string.Format(Translator.GetString("Glitch_KCD"), KCDTimer)); handler.AppendLiteral("\n"); stringBuilder6.Append(ref handler); } return stringBuilder.ToString(); } public override void AfterMeetingTasks() { LastMimic = (LastHack = (LastKill = Utils.GetTimeStamp())); KCDTimer = 10; HackCDTimer = 10; MimicCDTimer = 10; SendRPC(); } public override bool OnCoEnterVentOthers(PlayerPhysics physics, int ventId) { if (hackedIdList.ContainsKey(physics.myPlayer.PlayerId)) { new LateTask(delegate { physics.myPlayer?.Notify(string.Format(Translator.GetString("HackedByGlitch"), Translator.GetString("GlitchVent"))); PlayerPhysics obj = physics; if (obj != null) { obj.RpcBootFromVent(ventId); } }, 0.5f, "Player Boot From Vent By Glith"); return true; } return false; } public static bool OnCheckFixedUpdateReport(PlayerControl __instance, byte id) { if (hackedIdList.ContainsKey(id)) { __instance.Notify(string.Format(Translator.GetString("HackedByGlitch"), "Report")); Logger.Info("Dead Body Report Blocked (player is hacked by Glitch)", "FixedUpdate.ReportDeadBody", escapeCRLF: true, 271, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Glitch.cs"); ReportDeadBodyPatch.WaitReport[id].Clear(); return false; } return true; } public static bool OnCheckMurderOthers(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)(object)target || (Object)(object)killer == (Object)null) { return true; } if (hackedIdList.ContainsKey(killer.PlayerId)) { killer.Notify(string.Format(Translator.GetString("HackedByGlitch"), Translator.GetString("GlitchKill"))); return false; } return true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText")); ((ActionButton)hud.SabotageButton).OverrideText(Translator.GetString("Glitch_MimicButtonText")); } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)0, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(HackCDTimer); val.Write(KCDTimer); val.Write(MimicCDTimer); val.Write(MimicDurTimer); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { HackCDTimer = reader.ReadInt32(); KCDTimer = reader.ReadInt32(); MimicCDTimer = reader.ReadInt32(); MimicDurTimer = reader.ReadInt32(); } } internal class God : RoleBase { private const int Id = 25100; public static readonly HashSet playerIdList = new HashSet(); public static OptionItem NotifyGodAlive; public static OptionItem CanGuess; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(25100, TabGroup.NeutralRoles, CustomRoles.God); NotifyGodAlive = BooleanOptionItem.Create(25103, "NotifyGodAlive", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.God]); CanGuess = BooleanOptionItem.Create(25104, GeneralOption.CanGuess, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.God]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (!CanGuess.GetBool()) { Logger.Info($"Guess Disabled for this player {guesser.PlayerId}", "GuessManager", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\God.cs"); guesser.ShowInfoMessage(isUI, Translator.GetString("GuessDisabled")); return true; } return false; } public override void OnMeetingHudStart(PlayerControl pc) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (pc.IsAlive() && NotifyGodAlive.GetBool()) { MeetingHudStartPatch.AddMsg(Translator.GetString("GodNoticeAlive"), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.God)), Translator.GetString("GodAliveTitle"))); } } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return seer.Is(CustomRoles.God); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { return Main.roleColors[target.GetCustomRole()]; } } internal class Hater : RoleBase { private const int Id = 12900; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem ChooseConverted; private static OptionItem MisFireKillTarget; private static OptionItem CanKillLovers; private static OptionItem CanKillMadmate; private static OptionItem CanKillCharmed; private static OptionItem CanKillAdmired; private static OptionItem CanKillSidekicks; private static OptionItem CanKillEgoists; private static OptionItem CanKillInfected; private static OptionItem CanKillContagious; public static bool isWon = false; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(12900, TabGroup.NeutralRoles, CustomRoles.Hater); MisFireKillTarget = BooleanOptionItem.Create(12911, "HaterMisFireKillTarget", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hater]); ChooseConverted = BooleanOptionItem.Create(12912, "HaterChooseConverted", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hater]); CanKillMadmate = BooleanOptionItem.Create(12913, "HaterCanKillMadmate", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillCharmed = BooleanOptionItem.Create(12914, "HaterCanKillCharmed", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillLovers = BooleanOptionItem.Create(12915, "HaterCanKillLovers", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillSidekicks = BooleanOptionItem.Create(12916, "HaterCanKillSidekick", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillEgoists = BooleanOptionItem.Create(12917, "HaterCanKillEgoist", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillInfected = BooleanOptionItem.Create(12918, "HaterCanKillInfected", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillContagious = BooleanOptionItem.Create(12919, "HaterCanKillContagious", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); CanKillAdmired = BooleanOptionItem.Create(12920, "HaterCanKillAdmired", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ChooseConverted); } public override void Init() { playerIdList.Clear(); isWon = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (killer.PlayerId == target.PlayerId) { return true; } if (target.GetCustomSubRoles().Any(delegate(CustomRoles addOn) { bool flag = addOn.IsConverted(); if (!flag) { bool flag2 = ((addOn == CustomRoles.Admired || addOn == CustomRoles.Lovers || addOn == CustomRoles.Madmate) ? true : false); flag = flag2; } return flag; }) || IsConvertedMainRole(target.GetCustomRole())) { if (!ChooseConverted.GetBool()) { isWon = true; Logger.Info(killer.GetRealName() + " killed right target case 1", "FFF", escapeCRLF: true, 70, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Hater.cs"); return false; } if (((target.Is(CustomRoles.Madmate) || target.Is(CustomRoles.Gangster)) && CanKillMadmate.GetBool()) || ((target.Is(CustomRoles.Charmed) || target.Is(CustomRoles.Cultist)) && CanKillCharmed.GetBool()) || (target.Is(CustomRoles.Lovers) && CanKillLovers.GetBool()) || ((target.Is(CustomRoles.Romantic) || target.Is(CustomRoles.RuthlessRomantic) || target.Is(CustomRoles.VengefulRomantic) || Romantic.BetPlayer.ContainsValue(target.PlayerId)) && CanKillLovers.GetBool()) || ((target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Recruit)) && CanKillSidekicks.GetBool()) || (target.Is(CustomRoles.Egoist) && CanKillEgoists.GetBool()) || ((target.Is(CustomRoles.Infected) || target.Is(CustomRoles.Infectious)) && CanKillInfected.GetBool()) || ((target.Is(CustomRoles.Contagious) || target.Is(CustomRoles.Virus)) && CanKillContagious.GetBool()) || ((target.Is(CustomRoles.Admired) || target.Is(CustomRoles.Admirer)) && CanKillAdmired.GetBool())) { isWon = true; Logger.Info(killer.GetRealName() + " killed right target case 2", "FFF", escapeCRLF: true, 87, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Hater.cs"); return false; } } if (MisFireKillTarget.GetBool()) { target.SetDeathReason(PlayerState.DeathReason.Misfire); killer.RpcMurderPlayer(target); } killer.SetDeathReason(PlayerState.DeathReason.Sacrifice); killer.RpcMurderPlayer(killer); Logger.Info(killer.GetRealName() + " killed incorrect target => misfire", "FFF", escapeCRLF: true, 100, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Hater.cs"); return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: true); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("HaterButtonText")); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = 1f; } private static bool IsConvertedMainRole(CustomRoles role) { switch (role) { case CustomRoles.Gangster: case CustomRoles.Admirer: case CustomRoles.Cultist: case CustomRoles.Infectious: case CustomRoles.Jackal: case CustomRoles.Romantic: case CustomRoles.RuthlessRomantic: case CustomRoles.Sidekick: case CustomRoles.VengefulRomantic: case CustomRoles.Virus: return true; default: return false; } } } internal class HexMaster : RoleBase { private enum SwitchTriggerList { TriggerKill, TriggerVent, TriggerDouble } private const int Id = 16400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ModeSwitchAction; private static OptionItem HexesLookLikeSpells; private static OptionItem HasImpostorVision; private static readonly Dictionary HexMode = new Dictionary(); private static readonly Dictionary> HexedPlayer = new Dictionary>(); private static readonly Color RoleColorHex = Utils.GetRoleColor(CustomRoles.HexMaster); private static readonly Color RoleColorSpell = Utils.GetRoleColor(CustomRoles.Impostor); private static SwitchTriggerList NowSwitchTrigger; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16400, TabGroup.NeutralRoles, CustomRoles.HexMaster); ModeSwitchAction = StringOptionItem.Create(16410, GeneralOption.ModeSwitchAction, EnumHelper.GetAllNames(), 2, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.HexMaster]); HexesLookLikeSpells = BooleanOptionItem.Create(16411, "HexesLookLikeSpells", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.HexMaster]); HasImpostorVision = BooleanOptionItem.Create(16412, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.HexMaster]); } public override void Init() { playerIdList.Clear(); HexMode.Clear(); HexedPlayer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); HexMode.Add(playerId, value: false); HexedPlayer.Add(playerId, new List()); NowSwitchTrigger = (SwitchTriggerList)ModeSwitchAction.GetValue(); Utils.GetPlayerById(playerId).AddDoubleTrigger(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private static void SendRPC(bool doHex, byte hexId, byte target = byte.MaxValue) { if (doHex) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)140, (SendOption)1, -1); val.Write(hexId); val.Write(target); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else { MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)130, (SendOption)1, -1); val2.Write(hexId); val2.Write(HexMode[hexId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); } } public static void ReceiveRPC(MessageReader reader, bool doHex) { if (doHex) { byte key = reader.ReadByte(); byte b = reader.ReadByte(); if (b != byte.MaxValue) { HexedPlayer[key].Add(b); } else { HexedPlayer[key].Clear(); } } else { byte key2 = reader.ReadByte(); HexMode[key2] = reader.ReadBoolean(); } } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return true; } private static bool IsHexMode(byte playerId) { if (HexMode.ContainsKey(playerId)) { return HexMode[playerId]; } return false; } private static void SwitchHexMode(byte playerId, bool kill) { bool flag = false; switch (NowSwitchTrigger) { case SwitchTriggerList.TriggerKill: flag = kill; break; case SwitchTriggerList.TriggerVent: flag = !kill; break; } if (flag) { HexMode[playerId] = !HexMode[playerId]; SendRPC(doHex: false, playerId); Utils.NotifyRoles(Utils.GetPlayerById(playerId)); } } private static bool IsHexed(byte target) { foreach (byte playerId in playerIdList) { if (HexedPlayer[playerId].Contains(target)) { return true; } } return false; } private static void SetHexed(PlayerControl killer, PlayerControl target) { if (!IsHexed(target.PlayerId)) { HexedPlayer[killer.PlayerId].Add(target.PlayerId); SendRPC(doHex: true, killer.PlayerId, target.PlayerId); killer.SetKillCooldown(); } } public override void AfterMeetingTasks() { foreach (byte playerId in playerIdList) { HexedPlayer[playerId].Clear(); SendRPC(doHex: true, playerId); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (Medic.ProtectList.Contains(target.PlayerId)) { return false; } if (target.Is(CustomRoles.Pestilence)) { return false; } if (NowSwitchTrigger == SwitchTriggerList.TriggerDouble) { return killer.CheckDoubleTrigger(target, delegate { SetHexed(killer, target); }); } if (!IsHexMode(killer.PlayerId)) { SwitchHexMode(killer.PlayerId, kill: true); return true; } SetHexed(killer, target); SwitchHexMode(killer.PlayerId, kill: true); return false; } public static void OnCheckForEndVoting(PlayerState.DeathReason deathReason, params byte[] exileIds) { if (!HasEnabled || deathReason != PlayerState.DeathReason.Vote) { return; } byte[] array = exileIds; foreach (byte key in array) { if (HexedPlayer.ContainsKey(key)) { HexedPlayer[key].Clear(); } } List list = new List(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl pc in allAlivePlayerControls) { IEnumerable>> source = HexedPlayer.Where((KeyValuePair> x) => x.Value.Contains(pc.PlayerId)); if (!source.Any()) { continue; } PlayerControl playerById = Utils.GetPlayerById(source.FirstOrDefault().Key); if ((Object)(object)playerById != (Object)null && playerById.IsAlive()) { if (!Main.AfterMeetingDeathPlayers.ContainsKey(pc.PlayerId)) { pc.SetRealKiller(playerById); list.Add(pc.PlayerId); } } else { Main.AfterMeetingDeathPlayers.Remove(pc.PlayerId); } } int i = 0; array = new byte[list.Count]; foreach (byte item in list) { array[i] = item; i++; } CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Hex, array); RemoveHexedPlayer(); } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { RemoveHexedPlayer(); } private static void RemoveHexedPlayer() { foreach (byte playerId in playerIdList) { HexedPlayer[playerId].Clear(); SendRPC(doHex: true, playerId); } } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (NowSwitchTrigger == SwitchTriggerList.TriggerVent) { SwitchHexMode(pc.PlayerId, kill: false); } } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting && IsHexed(target.PlayerId)) { if (!HexesLookLikeSpells.GetBool()) { return Utils.ColorString(Color32.op_Implicit(RoleColorHex), "乂"); } return Utils.ColorString(Color32.op_Implicit(RoleColorSpell), "†"); } return string.Empty; } public override string GetLowerText(PlayerControl hexmaster, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if (!hexmaster.IsAlive() || isForMeeting || (Object)(object)hexmaster != (Object)(object)seen) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (isForHud) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(Translator.GetString("WitchCurrentMode")); handler.AppendLiteral(": "); stringBuilder3.Append(ref handler); } else { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(Translator.GetString("Mode")); handler.AppendLiteral(": "); stringBuilder4.Append(ref handler); } if (NowSwitchTrigger == SwitchTriggerList.TriggerDouble) { stringBuilder.Append(Translator.GetString("HexMasterModeDouble")); } else { stringBuilder.Append(IsHexMode(hexmaster.PlayerId) ? Translator.GetString("HexMasterModeHex") : Translator.GetString("HexMasterModeKill")); } return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte playerid) { if (IsHexMode(playerid) && NowSwitchTrigger != SwitchTriggerList.TriggerDouble) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("HexButtonText") ?? ""); } else { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } } } internal class Huntsman : RoleBase { private const int Id = 16500; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem SuccessKillCooldown; private static OptionItem FailureKillCooldown; private static OptionItem NumOfTargets; private static OptionItem MinKCD; private static OptionItem MaxKCD; private readonly HashSet Targets = new HashSet(); private float KCD = 25f; public static bool HasEnabled => CustomRoles.Huntsman.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16500, TabGroup.NeutralRoles, CustomRoles.Huntsman); KillCooldown = FloatOptionItem.Create(16510, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Seconds); SuccessKillCooldown = FloatOptionItem.Create(16511, "HHSuccessKCDDecrease", new FloatValueRule(0f, 180f, 0.5f), 5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Seconds); FailureKillCooldown = FloatOptionItem.Create(16512, "HHFailureKCDIncrease", new FloatValueRule(0f, 180f, 0.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16513, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]); HasImpostorVision = BooleanOptionItem.Create(16514, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]); NumOfTargets = IntegerOptionItem.Create(16515, "HHNumOfTargets", new IntegerValueRule(0, 10, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Times); MaxKCD = FloatOptionItem.Create(16516, "HHMaxKCD", new FloatValueRule(0f, 180f, 2.5f), 60f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Seconds); MinKCD = FloatOptionItem.Create(16517, "HHMinKCD", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Huntsman]).SetValueFormat(OptionFormat.Seconds); } public override void Add(byte playerId) { new LateTask(delegate { ResetTargets(isStartedGame: true); }, 8f, "Huntsman Reset Targets"); KCD = KillCooldown.GetFloat(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public void SendRPC(bool isSetTarget, byte targetId = byte.MaxValue) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(isSetTarget); if (isSetTarget) { val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { if (!reader.ReadBoolean()) { Targets.Clear(); return; } byte item = reader.ReadByte(); Targets.Add(item); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void OnReportDeadBody(PlayerControl Ronaldo, NetworkedPlayerInfo IsTheGoat) { ResetTargets(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { float kCD = KCD; if (Targets.Contains(target.PlayerId)) { Math.Clamp(KCD -= SuccessKillCooldown.GetFloat(), MinKCD.GetFloat(), MaxKCD.GetFloat()); } else { Math.Clamp(KCD += FailureKillCooldown.GetFloat(), MinKCD.GetFloat(), MaxKCD.GetFloat()); } if (KCD != kCD) { killer.ResetKillCooldown(); killer.SyncSettings(); } return true; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KCD; } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override string GetLowerText(PlayerControl player, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if (isForMeeting) { return string.Empty; } byte playerId = player.PlayerId; string text = string.Empty; byte b = 0; foreach (byte target in Targets) { if (b != 0) { text += ", "; } text += Utils.GetPlayerById(target).GetRealName(); b++; } if (playerId == byte.MaxValue) { return string.Empty; } return Translator.GetString("Targets") + "" + text + ""; } private void ResetTargets(bool isStartedGame = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } Targets.Clear(); SendRPC(isSetTarget: false); int num = Main.AllAlivePlayerControls.Length - 1; if (num < 0) { num = 0; } int num2 = Math.Min(num, NumOfTargets.GetInt()); for (int i = 0; i < num2; i++) { try { List collection = new List(Main.AllAlivePlayerControls.Where((PlayerControl pc) => !Targets.Contains(pc.PlayerId) && pc.GetCustomRole() != CustomRoles.Huntsman)); _ = IRandom.Instance; byte playerId = collection.RandomElement().PlayerId; Targets.Add(playerId); SendRPC(isSetTarget: true, playerId); } catch (Exception value) { Logger.Warn($"Not enough targets for Head Hunter could be assigned. This may be due to a low player count or the following error:\n\n{value}", "HuntsmanAssignTargets", escapeCRLF: true, 148, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Huntsman.cs"); break; } } if (isStartedGame) { Utils.NotifyRoles(); } } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!Targets.Contains(target.PlayerId)) { return string.Empty; } return "6e5524"; } } internal class Imitator : RoleBase { private enum ImitatorIncompatibleNeutralModeSelectList { Role_Imitator, Role_Pursuer, Role_Follower, Role_Maverick, Role_Amnesiac } private const int Id = 13000; private static OptionItem RememberCooldown; private static OptionItem IncompatibleNeutralMode; public static bool HasEnabled => CustomRoles.Imitator.HasEnabled(); public override bool IsExperimental => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(13000, TabGroup.NeutralRoles, CustomRoles.Imitator); RememberCooldown = FloatOptionItem.Create(13010, "RememberCooldown", new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Imitator]).SetValueFormat(OptionFormat.Seconds); IncompatibleNeutralMode = StringOptionItem.Create(13012, "IncompatibleNeutralMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Imitator]); } public override void Add(byte playerId) { base.AbilityLimit = 1f; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = RememberCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl player) { return base.AbilityLimit > 0f; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) if (base.AbilityLimit < 1f) { return false; } CustomRoles customRole = target.GetCustomRole(); bool flag; switch (customRole) { case CustomRoles.Sheriff: case CustomRoles.BloodKnight: case CustomRoles.HexMaster: case CustomRoles.Jackal: case CustomRoles.Juggernaut: case CustomRoles.Poisoner: flag = true; break; default: flag = false; break; } if (flag) { base.AbilityLimit--; SendSkillRPC(); killer.RpcSetCustomRole(customRole); killer.GetRoleClass().OnAdd(killer.PlayerId); if (customRole.IsCrewmate()) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedCrewmate"))); } else { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedNeutralKiller"))); } target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("ImitatorImitated"))); } else if (customRole.IsAmneMaverick()) { base.AbilityLimit--; SendSkillRPC(); switch (IncompatibleNeutralMode.GetInt()) { case 0: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedImitator"))); break; case 1: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedPursuer"))); killer.RpcSetCustomRole(CustomRoles.Pursuer); killer.GetRoleClass().OnAdd(killer.PlayerId); break; case 2: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedFollower"))); killer.RpcSetCustomRole(CustomRoles.Follower); killer.GetRoleClass().OnAdd(killer.PlayerId); break; case 3: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedMaverick"))); killer.RpcSetCustomRole(CustomRoles.Maverick); killer.GetRoleClass().OnAdd(killer.PlayerId); break; case 4: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedAmnesiac"))); killer.RpcSetCustomRole(CustomRoles.Amnesiac); killer.GetRoleClass().OnAdd(killer.PlayerId); break; } } else if (customRole.IsCrewmate()) { base.AbilityLimit--; SendSkillRPC(); killer.RpcSetCustomRole(CustomRoles.Sheriff); killer.GetRoleClass().OnAdd(killer.PlayerId); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedCrewmate"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("ImitatorImitated"))); } else if (customRole.IsImpostor()) { base.AbilityLimit--; SendSkillRPC(); killer.RpcSetCustomRole(CustomRoles.Refugee); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("RememberedImpostor"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("ImitatorImitated"))); } CustomRoles customRole2 = killer.GetCustomRole(); if (customRole2 != CustomRoles.Imitator) { killer.ResetKillCooldown(); killer.SetKillCooldown(-1f, null, forceAnime: true); object obj; if (target == null) { obj = null; } else { NetworkedPlayerInfo data = target.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.Info("Imitator remembered: " + (string?)obj + " = " + target.GetCustomRole(), "Imitator Assign", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Imitator.cs"); Logger.Info($"{killer.GetNameWithRole()} : {base.AbilityLimit} remember limits left", "Imitator", escapeCRLF: true, 129, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Imitator.cs"); Utils.NotifyRoles(killer); } else if (customRole2 == CustomRoles.Imitator) { killer.SetKillCooldown(-1f, null, forceAnime: true); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Imitator)), Translator.GetString("ImitatorInvalidTarget"))); } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("ImitatorKillButtonText")); } } internal class Infectious : RoleBase { private const int Id = 16600; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem BiteCooldown; private static OptionItem BiteMax; private static OptionItem KnowTargetRole; private static OptionItem TargetKnowOtherTarget; private static OptionItem HasImpostorVision; private static OptionItem CanVent; private static OptionItem DoubleClickKill; private static int BiteLimit; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public static bool TargetKnowOtherTargets => TargetKnowOtherTarget.GetBool(); public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16600, TabGroup.NeutralRoles, CustomRoles.Infectious); BiteCooldown = FloatOptionItem.Create(16610, "InfectiousBiteCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]).SetValueFormat(OptionFormat.Seconds); BiteMax = IntegerOptionItem.Create(16612, "InfectiousBiteMax", new IntegerValueRule(1, 15, 1), 15, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]).SetValueFormat(OptionFormat.Times); KnowTargetRole = BooleanOptionItem.Create(16613, "InfectiousKnowTargetRole", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]); TargetKnowOtherTarget = BooleanOptionItem.Create(16614, "InfectiousTargetKnowOtherTarget", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]); HasImpostorVision = BooleanOptionItem.Create(16615, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]); CanVent = BooleanOptionItem.Create(16617, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]); DoubleClickKill = BooleanOptionItem.Create(16618, "DoubleClickKill", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Infectious]); } public override void Init() { BiteLimit = 0; PlayerIds.Clear(); } public override void Add(byte playerId) { BiteLimit = BiteMax.GetInt(); PlayerIds.Add(playerId); Utils.GetPlayerById(playerId)?.AddDoubleTrigger(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = BiteCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl player) { return BiteLimit >= 1; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } private static bool InfectOrMurder(PlayerControl killer, PlayerControl target) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) if (CanBeBitten(target)) { BiteLimit--; target.RpcSetCustomRole(CustomRoles.Infected); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infectious)), Translator.GetString("InfectiousBittenPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infectious)), Translator.GetString("BittenByInfectious"))); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); target.RpcGuardAndKill(target); string[] obj = new string[6] { "设置职业:", null, null, null, null, null }; object obj2; if (target == null) { obj2 = null; } else { NetworkedPlayerInfo data = target.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = target.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Infected.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Infected, escapeCRLF: true, 87, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Infectious.cs"); if (BiteLimit < 0) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } Logger.Info($"{killer.GetNameWithRole()} : 剩余{BiteLimit}次招募机会", "Infectious", escapeCRLF: true, 94, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Infectious.cs"); return true; } if (!CanBeBitten(target) && !target.Is(CustomRoles.Infected)) { killer.RpcMurderPlayer(target); } if (BiteLimit < 0) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infectious)), Translator.GetString("InfectiousInvalidTarget"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{BiteLimit}次招募机会", "Infectious", escapeCRLF: true, 110, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Infectious.cs"); return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.Pestilence)) { return true; } if (target.Is(CustomRoles.Infectious)) { return true; } if (target.Is(CustomRoles.SerialKiller)) { return true; } if (BiteLimit < 1) { return false; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if (DoubleClickKill.GetBool()) { if (killer.CheckDoubleTrigger(target, delegate { InfectOrMurder(killer, target); })) { killer.RpcMurderPlayer(target); } } else { InfectOrMurder(killer, target); } return false; } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { if (player.IsAlive()) { return; } foreach (PlayerControl item in Main.AllAlivePlayerControls.Where((PlayerControl pc) => pc.Is(CustomRoles.Infected))) { item.SetDeathReason(PlayerState.DeathReason.Infected); item.RpcMurderPlayer(item); item.SetRealKiller(Utils.GetPlayerById(PlayerIds.First())); } } public static bool KnowRole(PlayerControl player, PlayerControl target) { if (player.Is(CustomRoles.Infected) && target.Is(CustomRoles.Infectious)) { return true; } if (KnowTargetRole.GetBool() && player.Is(CustomRoles.Infectious) && target.Is(CustomRoles.Infected)) { return true; } if (TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Infected) && target.Is(CustomRoles.Infected)) { return true; } return false; } public static bool InfectedKnowColorOthersInfected(PlayerControl player, PlayerControl target) { if (player.Is(CustomRoles.Infected) && target.Is(CustomRoles.Infectious)) { return true; } if (player.Is(CustomRoles.Infectious) && target.Is(CustomRoles.Infected)) { return true; } if (TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Infected) && target.Is(CustomRoles.Infected)) { return true; } return false; } public override string GetProgressText(byte playerid, bool cooms) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((BiteLimit >= 1) ? Utils.GetRoleColor(CustomRoles.Infectious).ShadeColor(0.25f) : Color.gray), $"({BiteLimit})"); } public static bool CanBeBitten(PlayerControl pc) { if ((Object)(object)pc != (Object)null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || pc.GetCustomRole().IsNK()) && !pc.Is(CustomRoles.Infected) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Cultist) && !pc.Is(CustomRoles.Infectious)) { return !pc.Is(CustomRoles.Virus); } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("InfectiousKillButtonText")); } } internal class Innocent : RoleBase { private const int Id = 14300; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem InnocentCanWinByImp; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupRoleOptions(14300, TabGroup.NeutralRoles, CustomRoles.Innocent); InnocentCanWinByImp = BooleanOptionItem.Create(14302, "InnocentCanWinByImp", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Innocent]); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { target.RpcMurderPlayer(killer); return false; } public override void CheckExileTarget(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { CustomRoles customRole = exiled.GetCustomRole(); IEnumerable enumerable = Main.AllPlayerControls.Where(delegate(PlayerControl x) { if (x.Is(CustomRoles.Innocent) && !x.IsAlive()) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == exiled.PlayerId; } return false; }); if (!enumerable.Any()) { return; } if (!InnocentCanWinByImp.GetBool() && customRole.IsImpostor()) { if (!isMeetingHud) { Logger.Info("Exeiled Winner Check for impostor", "Innocent", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Innocent.cs"); } return; } if (isMeetingHud) { if (DecidedWinner) { name += string.Format(Translator.GetString("ExiledInnocentTargetAddBelow")); } else { name = string.Format(Translator.GetString("ExiledInnocentTargetInOneLine"), Main.LastVotedPlayer, Utils.GetDisplayRoleAndSubName(exiled.PlayerId, exiled.PlayerId, notShowAddOns: true)); } } else { bool flag = false; foreach (PlayerControl item in enumerable) { if (CustomWinnerHolder.CheckForConvertedWinner(item.PlayerId)) { flag = true; break; } } if (!flag) { if (DecidedWinner) { CustomWinnerHolder.ShiftWinnerAndSetWinner(CustomWinner.Innocent); } else { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Innocent); } CollectionExtensions.Do(enumerable, (Action)delegate(PlayerControl x) { CustomWinnerHolder.WinnerIds.Add(x.PlayerId); }); } } DecidedWinner = true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("InnocentButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Suidce"); } } internal class Jackal : RoleBase { private enum SidekickAssignModeSelectList { Jackal_SidekickAssignMode_SidekickAndRecruit, Jackal_SidekickAssignMode_Sidekick, Jackal_SidekickAssignMode_Recruit } private enum SidekickCountModeSelectList { Jackal_SidekickCountMode_Jackal, Jackal_SidekickCountMode_None, Jackal_SidekickCountMode_Original } private const int Id = 16700; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem CanUsesSabotage; public static OptionItem CanWinBySabotageWhenNoImpAlive; public static OptionItem HasImpostorVision; private static OptionItem OptionResetKillCooldownWhenSbGetKilled; private static OptionItem ResetKillCooldownWhenSbGetKilled; private static OptionItem ResetKillCooldownOn; private static OptionItem JackalCanKillSidekick; private static OptionItem CanRecruitSidekick; private static OptionItem SidekickRecruitLimitOpt; public static OptionItem SidekickCountMode; private static OptionItem SidekickAssignMode; public static OptionItem KillCooldownSK; public static OptionItem CanVentSK; public static OptionItem CanUseSabotageSK; private static OptionItem SidekickCanKillJackal; private static OptionItem SidekickCanKillSidekick; public static bool HasEnabled => CustomRoles.Jailer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16700, TabGroup.NeutralRoles, CustomRoles.Jackal); KillCooldown = FloatOptionItem.Create(16710, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16711, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); CanUsesSabotage = BooleanOptionItem.Create(16712, GeneralOption.CanUseSabotage, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); CanWinBySabotageWhenNoImpAlive = BooleanOptionItem.Create(16714, "JackalCanWinBySabotageWhenNoImpAlive", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanUsesSabotage); HasImpostorVision = BooleanOptionItem.Create(16713, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); OptionResetKillCooldownWhenSbGetKilled = BooleanOptionItem.Create(16716, "JackalResetKillCooldownWhenPlayerGetKilled", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); ResetKillCooldownOn = FloatOptionItem.Create(16728, "JackalResetKillCooldownOn", new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(OptionResetKillCooldownWhenSbGetKilled).SetValueFormat(OptionFormat.Seconds); JackalCanKillSidekick = BooleanOptionItem.Create(16715, "JackalCanKillSidekick", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); CanRecruitSidekick = BooleanOptionItem.Create(16730, "JackalCanRecruitSidekick", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jackal]); SidekickAssignMode = StringOptionItem.Create(16734, "Jackal_SidekickAssignMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick).SetHidden(value: false); SidekickRecruitLimitOpt = IntegerOptionItem.Create(16733, "JackalSidekickRecruitLimit", new IntegerValueRule(0, 15, 1), 2, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick).SetValueFormat(OptionFormat.Times); KillCooldownSK = FloatOptionItem.Create(16720, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick).SetValueFormat(OptionFormat.Seconds); CanVentSK = BooleanOptionItem.Create(16721, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick); CanUseSabotageSK = BooleanOptionItem.Create(16722, GeneralOption.CanUseSabotage, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick); SidekickCanKillJackal = BooleanOptionItem.Create(16723, "Jackal_SidekickCanKillJackal", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick); SidekickCanKillSidekick = BooleanOptionItem.Create(16724, "Jackal_SidekickCanKillSidekick", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick); SidekickCountMode = StringOptionItem.Create(16725, "Jackal_SidekickCountMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(CanRecruitSidekick).SetHidden(value: false); } public override void Init() { ResetKillCooldownWhenSbGetKilled = OptionResetKillCooldownWhenSbGetKilled; } public override void Add(byte playerId) { base.AbilityLimit = (CanRecruitSidekick.GetBool() ? SidekickRecruitLimitOpt.GetInt() : 0); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(OthersPlayersDead); } } public override void ApplyGameOptions(IGameOptions opt, byte babuyaga) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return CanUsesSabotage.GetBool(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public static bool JackalKnowRole(PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Jackal) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit))) { return true; } if (seer.Is(CustomRoles.Sidekick) && (target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick))) { return true; } if (seer.Is(CustomRoles.Recruit) && (target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit))) { return true; } return false; } private bool CanRecruit(byte id) { return base.AbilityLimit > 0f; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (CanRecruit(playerId)) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("GangsterButtonText") ?? ""); } } else { KillButton killButton2 = hud.KillButton; if (killButton2 != null) { ((ActionButton)killButton2).OverrideText(Translator.GetString("KillButtonText") ?? ""); } } } private void OthersPlayersDead(PlayerControl killer, PlayerControl target, bool inMeeting) { if (!inMeeting && !target.IsDisconnected() && ResetKillCooldownWhenSbGetKilled.GetBool() && !killer.Is(CustomRoles.Sidekick) && !killer.Is(CustomRoles.Jackal) && !target.Is(CustomRoles.Sidekick) && !target.Is(CustomRoles.Jackal) && !GameStates.IsMeeting) { CollectionExtensions.Do(Main.AllAlivePlayerControls.Where((PlayerControl x) => !target.Is(CustomRoles.Jackal) && x.Is(CustomRoles.Jackal)), (Action)delegate(PlayerControl x) { x.SetKillCooldown(ResetKillCooldownOn.GetFloat()); }); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.Jackal)) { return false; } if (!CanRecruitSidekick.GetBool() || base.AbilityLimit < 1f) { return true; } if (SidekickAssignMode.GetValue() != 2 && CanBeSidekick(target)) { base.AbilityLimit--; SendSkillRPC(); target.GetRoleClass()?.OnRemove(target.PlayerId); target.RpcSetCustomRole(CustomRoles.Sidekick); target.GetRoleClass()?.OnAdd(target.PlayerId); if (!Main.ResetCamPlayerList.Contains(target.PlayerId)) { Main.ResetCamPlayerList.Add(target.PlayerId); } Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jackal)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jackal)), Translator.GetString("BeRecruitedByJackal"))); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); target.RpcGuardAndKill(target); killer.ResetKillCooldown(); killer.SetKillCooldown(); target.ResetKillCooldown(); target.SetKillCooldown(); Logger.Info($"Target: {target.GetRealName()} : {target.GetCustomRole()} => {216}", "Assign Sidekick", escapeCRLF: true, 165, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jackal.cs"); if (base.AbilityLimit < 0f) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} - Recruit limit:{base.AbilityLimit}", "Jackal", escapeCRLF: true, 170, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jackal.cs"); return false; } if (SidekickAssignMode.GetValue() != 1 && !target.GetCustomRole().IsNeutral() && !target.Is(CustomRoles.Sidekick) && !target.Is(CustomRoles.Recruit) && !target.Is(CustomRoles.Loyal) && !target.Is(CustomRoles.Admired)) { base.AbilityLimit--; SendSkillRPC(); target.RpcSetCustomRole(CustomRoles.Recruit); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jackal)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jackal)), Translator.GetString("BeRecruitedByJackal"))); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); target.RpcGuardAndKill(target); killer.ResetKillCooldown(); killer.SetKillCooldown(); target.ResetKillCooldown(); target.SetKillCooldown(); Logger.Info($"Target: {target.GetRealName()} = {target.GetCustomRole()} => {552}", "Assign Recruit", escapeCRLF: true, 198, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jackal.cs"); if (base.AbilityLimit < 0f) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} - Recruit limit:{base.AbilityLimit}", "Jackal", escapeCRLF: true, 203, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jackal.cs"); return false; } if (base.AbilityLimit < 0f) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} - Recruit limit:{base.AbilityLimit}", "Jackal", escapeCRLF: true, 210, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jackal.cs"); return true; } public static bool CanBeSidekick(PlayerControl pc) { if ((Object)(object)pc != (Object)null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Recruit) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Rascal) && !pc.Is(CustomRoles.Madmate) && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Infected) && !pc.Is(CustomRoles.Paranoia) && !pc.Is(CustomRoles.Contagious) && pc.GetCustomRole().IsAbleToBeSidekicked()) { if (pc.GetCustomSubRoles().Contains(CustomRoles.Hurried)) { return Hurried.CanBeConverted.GetBool(); } return true; } return false; } private string GetRecruitLimit(byte playerId) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CanRecruit(playerId) ? Utils.GetRoleColor(CustomRoles.Jackal).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override string GetProgressText(byte playerId, bool comms) { if (!CanRecruitSidekick.GetBool()) { return ""; } return GetRecruitLimit(playerId); } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (!JackalCanKillSidekick.GetBool()) { if (killer.Is(CustomRoles.Jackal) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit))) { return true; } if ((killer.Is(CustomRoles.Sidekick) || killer.Is(CustomRoles.Recruit)) && target.Is(CustomRoles.Jackal)) { return true; } } if (!SidekickCanKillSidekick.GetBool()) { if (killer.Is(CustomRoles.Sidekick) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit))) { return true; } if (killer.Is(CustomRoles.Recruit) && (target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick))) { return true; } } if (!SidekickCanKillJackal.GetBool() && target.Is(CustomRoles.Jackal) && (killer.Is(CustomRoles.Sidekick) || killer.Is(CustomRoles.Recruit))) { return true; } return false; } } internal class Jester : RoleBase { private const int Id = 14400; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem JesterCanUseButton; private static OptionItem JesterHasImpostorVision; private static OptionItem JesterCanVent; private static OptionItem MeetingsNeededForJesterWin; private static OptionItem HideJesterVote; public static OptionItem SunnyboyChance; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase { get { if (!JesterCanVent.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupRoleOptions(14400, TabGroup.NeutralRoles, CustomRoles.Jester); JesterCanUseButton = BooleanOptionItem.Create(14402, GeneralOption.CanUseMeetingButton, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]); JesterCanVent = BooleanOptionItem.Create(14403, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]); JesterHasImpostorVision = BooleanOptionItem.Create(14404, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]); HideJesterVote = BooleanOptionItem.Create(14405, GeneralOption.HideVote, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]); MeetingsNeededForJesterWin = IntegerOptionItem.Create(14406, "MeetingsNeededForWin", new IntegerValueRule(0, 10, 1), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]).SetValueFormat(OptionFormat.Times); SunnyboyChance = IntegerOptionItem.Create(14407, "SunnyboyChance", new IntegerValueRule(0, 100, 5), 0, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jester]).SetValueFormat(OptionFormat.Percent); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; opt.SetVision(JesterHasImpostorVision.GetBool()); } public override bool HideVote(PlayerVoteArea votedPlayer) { return HideJesterVote.GetBool(); } public override bool OnCheckStartMeeting(PlayerControl reporter) { return JesterCanUseButton.GetBool(); } public override void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { if (MeetingsNeededForJesterWin.GetInt() <= Main.MeetingsPassed) { if (isMeetingHud) { name = string.Format(Translator.GetString("ExiledJester"), Main.LastVotedPlayer, Utils.GetDisplayRoleAndSubName(exiled.PlayerId, exiled.PlayerId, notShowAddOns: true)); DecidedWinner = true; return; } if (!CustomWinnerHolder.CheckForConvertedWinner(exiled.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Jester); CustomWinnerHolder.WinnerIds.Add(exiled.PlayerId); } foreach (byte playerId in Executioner.playerIdList) { if (Executioner.IsTarget(playerId, exiled.PlayerId)) { CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Executioner); CustomWinnerHolder.WinnerIds.Add(playerId); } } DecidedWinner = true; } else if (Options.CEMode.GetInt() == 2 && isMeetingHud) { name += string.Format(Translator.GetString("JesterMeetingLoose"), MeetingsNeededForJesterWin.GetInt() + 1); } } } internal class Jinx : RoleBase { private const int Id = 16800; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem JinxSpellTimes; private static OptionItem killAttacker; public static bool HasEnabled => CustomRoles.Jinx.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16800, TabGroup.NeutralRoles, CustomRoles.Jinx); KillCooldown = FloatOptionItem.Create(16810, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jinx]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(16811, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jinx]); HasImpostorVision = BooleanOptionItem.Create(16813, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jinx]); JinxSpellTimes = IntegerOptionItem.Create(16814, "JinxSpellTimes", new IntegerValueRule(1, 15, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jinx]).SetValueFormat(OptionFormat.Times); killAttacker = BooleanOptionItem.Create(16815, GeneralOption.KillAttackerWhenAbilityRemaining, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jinx]); } public override void Add(byte playerId) { base.AbilityLimit = JinxSpellTimes.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (base.AbilityLimit <= 0f) { return true; } if (killer.Is(CustomRoles.Pestilence)) { return true; } if ((Object)(object)killer == (Object)(object)target) { return true; } killer.RpcGuardAndKill(target); target.RpcGuardAndKill(target); base.AbilityLimit -= 1f; SendSkillRPC(); if (killAttacker.GetBool() && target.RpcCheckAndMurder(killer, check: true)) { Logger.Info($"{target.GetNameWithRole()}: ability left {base.AbilityLimit}", "Jinx", escapeCRLF: true, 57, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Jinx.cs"); killer.SetDeathReason(PlayerState.DeathReason.Jinx); killer.RpcMurderPlayer(killer); killer.SetRealKiller(target); } return false; } public override void ApplyGameOptions(IGameOptions opt, byte babushka) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl player) { return CanVent.GetBool(); } public override string GetProgressText(byte playerId, bool comms) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CanJinx(playerId) ? Utils.GetRoleColor(CustomRoles.Gangster).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } private bool CanJinx(byte id) { return base.AbilityLimit > 0f; } } internal class Juggernaut : RoleBase { private const int Id = 16900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem DefaultKillCooldown; private static OptionItem ReduceKillCooldown; private static OptionItem MinKillCooldown; private static OptionItem HasImpostorVision; private static OptionItem CanVent; private static readonly Dictionary NowCooldown = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(16900, TabGroup.NeutralRoles, CustomRoles.Juggernaut); DefaultKillCooldown = FloatOptionItem.Create(16910, GeneralOption.DefaultKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 65f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Juggernaut]).SetValueFormat(OptionFormat.Seconds); ReduceKillCooldown = FloatOptionItem.Create(16911, GeneralOption.ReduceKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Juggernaut]).SetValueFormat(OptionFormat.Seconds); MinKillCooldown = FloatOptionItem.Create(16912, GeneralOption.MinKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 2.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Juggernaut]).SetValueFormat(OptionFormat.Seconds); HasImpostorVision = BooleanOptionItem.Create(16913, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Juggernaut]); CanVent = BooleanOptionItem.Create(16914, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Juggernaut]); } public override void Init() { playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = NowCooldown[id]; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { NowCooldown[killer.PlayerId] = Math.Clamp(NowCooldown[killer.PlayerId] - ReduceKillCooldown.GetFloat(), MinKillCooldown.GetFloat(), DefaultKillCooldown.GetFloat()); killer.ResetKillCooldown(); killer.SyncSettings(); return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpostorVision.GetBool()); } } internal class Lawyer : RoleBase { private enum ChangeRolesSelectList { Role_Crewmate, Role_Jester, Role_Opportunist, Role_Celebrity, Role_Bodyguard, Role_Dictator, Role_Mayor, Role_Doctor } private const int Id = 13100; private static OptionItem CanTargetImpostor; private static OptionItem CanTargetNeutralKiller; private static OptionItem CanTargetCrewmate; private static OptionItem CanTargetJester; private static OptionItem ShouldChangeRoleAfterTargetDeath; private static OptionItem ChangeRolesAfterTargetKilled; private static OptionItem KnowTargetRole; private static OptionItem TargetKnowsLawyer; public static readonly Dictionary Target = new Dictionary(); public static readonly CustomRoles[] CRoleChangeRoles = new CustomRoles[8] { CustomRoles.CrewmateTOHE, CustomRoles.Jester, CustomRoles.Opportunist, CustomRoles.Celebrity, CustomRoles.Bodyguard, CustomRoles.Dictator, CustomRoles.Mayor, CustomRoles.Doctor }; public static bool HasEnabled => CustomRoles.Lawyer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public static bool TargetKnowLawyer => TargetKnowsLawyer.GetBool(); public override void SetupCustomOption() { Options.SetupRoleOptions(13100, TabGroup.NeutralRoles, CustomRoles.Lawyer); CanTargetImpostor = BooleanOptionItem.Create(13110, "LawyerCanTargetImpostor", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); CanTargetNeutralKiller = BooleanOptionItem.Create(13111, "LawyerCanTargetNeutralKiller", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); CanTargetCrewmate = BooleanOptionItem.Create(13112, "LawyerCanTargetCrewmate", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); CanTargetJester = BooleanOptionItem.Create(13113, "LawyerCanTargetJester", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); KnowTargetRole = BooleanOptionItem.Create(13114, "KnowTargetRole", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); TargetKnowsLawyer = BooleanOptionItem.Create(13115, "TargetKnowsLawyer", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); ShouldChangeRoleAfterTargetDeath = BooleanOptionItem.Create(13117, "LaywerShouldChangeRoleAfterTargetKilled", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lawyer]); ChangeRolesAfterTargetKilled = StringOptionItem.Create(13116, "LawyerChangeRolesAfterTargetKilled", EnumHelper.GetAllNames(), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(ShouldChangeRoleAfterTargetDeath); } public override void Init() { Target.Clear(); } public override void Add(byte playerId) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } CustomRoleManager.CheckDeadBodyOthers.Add(OthersAfterPlayerDeathTask); List list = new List(); _ = IRandom.Instance; PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (playerId != val.PlayerId && (CanTargetImpostor.GetBool() || !val.Is(Custom_Team.Impostor)) && (CanTargetNeutralKiller.GetBool() || !val.IsNeutralKiller()) && (CanTargetCrewmate.GetBool() || !val.Is(Custom_Team.Crewmate)) && (CanTargetJester.GetBool() || !val.Is(CustomRoles.Jester)) && (!val.Is(Custom_Team.Neutral) || val.IsNeutralKiller() || val.Is(CustomRoles.Jester))) { bool flag; switch (val.GetCustomRole()) { case CustomRoles.EvilMini: case CustomRoles.NiceMini: case CustomRoles.SuperStar: case CustomRoles.GM: flag = true; break; default: flag = false; break; } if (!flag && (!Utils.GetPlayerById(playerId).Is(CustomRoles.Lovers) || !val.Is(CustomRoles.Lovers))) { list.Add(val); } } } if (!list.Any()) { Logger.Info("Wow, not target for lawyer to select! Changing lawyer role to other", "Lawyer", escapeCRLF: true, 92, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Lawyer.cs"); CustomRoles role = (ShouldChangeRoleAfterTargetDeath.GetBool() ? CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()] : CustomRoles.Opportunist); PlayerControl playerById = Utils.GetPlayerById(playerId); if (playerById.IsAlive()) { playerById.GetRoleClass()?.OnRemove(playerId); playerById.RpcSetCustomRole(role); playerById.GetRoleClass()?.OnAdd(playerId); } } else { PlayerControl val2 = list.RandomElement(); Target.Add(playerId, val2.PlayerId); SendRPC(playerId, val2.PlayerId, SetTarget: true); Logger.Info(Utils.GetPlayerById(playerId)?.GetNameWithRole() + ":" + val2.GetNameWithRole(), "Lawyer", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Lawyer.cs"); } } public override void Remove(byte playerId) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Remove(OthersAfterPlayerDeathTask); Target.Remove(playerId); SendRPC(playerId, 115); } } private void SendRPC(byte lawyerId, byte targetId = 115, bool SetTarget = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(SetTarget); if (SetTarget) { val.Write(lawyerId); val.Write(targetId); } else { val.Write(lawyerId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { if (reader.ReadBoolean()) { byte key = reader.ReadByte(); byte value = reader.ReadByte(); Target.Add(key, value); } else { Target.Remove(reader.ReadByte()); } } public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { if (ChangeRolesAfterTargetKilled.GetValue() != 1) { return !ForRecompute; } return false; } private void OthersAfterPlayerDeathTask(PlayerControl killer, PlayerControl target, bool inMeeting) { if (!Target.ContainsValue(target.PlayerId)) { return; } byte lawyerId = 115; if (!ShouldChangeRoleAfterTargetDeath.GetBool()) { Logger.Info("Laywer target dead " + target.GetRealName() + ", but change role setting is off", "Lawyer", escapeCRLF: true, 161, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Lawyer.cs"); return; } CollectionExtensions.Do>((IEnumerable>)Target, (Action>)delegate(KeyValuePair x) { if (x.Value == target.PlayerId) { lawyerId = x.Key; } }); if (lawyerId == 115) { return; } PlayerControl playerById = Utils.GetPlayerById(lawyerId); if (!((Object)(object)playerById == (Object)null)) { playerById.GetRoleClass()?.OnRemove(lawyerId); playerById.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]); playerById.GetRoleClass()?.OnAdd(lawyerId); if (inMeeting) { Utils.SendMessage(Translator.GetString("LawyerTargetDeadInMeeting"), lawyerId); } else { Utils.NotifyRoles(Utils.GetPlayerById(lawyerId)); } } } public override bool KnowRoleTarget(PlayerControl player, PlayerControl target) { if (!KnowTargetRole.GetBool()) { return false; } if (player.Is(CustomRoles.Lawyer) && Target.TryGetValue(player.PlayerId, out var value)) { return value == target.PlayerId; } return false; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seer == (Object)null || (Object)(object)target == (Object)null) { return string.Empty; } if (seer.Is(CustomRoles.Lawyer)) { if (!Target.TryGetValue(seer.PlayerId, out var value) || value != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lawyer)), "♦"); } if (seer.IsAlive() && TargetKnowsLawyer.GetBool()) { if (!Target.TryGetValue(target.PlayerId, out var value2) || seer.PlayerId != value2) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lawyer)), "♦"); } if (!seer.IsAlive() && Target.ContainsValue(target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lawyer)), "♦"); } return string.Empty; } public override void AfterMeetingTasks() { CollectionExtensions.Do>((IEnumerable>)Target, (Action>)delegate(KeyValuePair x) { if (Main.PlayerStates[x.Value].IsDead) { PlayerControl playerById = Utils.GetPlayerById(x.Key); if (playerById.IsAlive()) { ChangeRole(playerById); } } }); } private static void ChangeRole(PlayerControl lawyer) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (!ShouldChangeRoleAfterTargetDeath.GetBool()) { Logger.Info("Laywer target dead, but change role setting is off", "Lawyer", escapeCRLF: true, 236, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Lawyer.cs"); return; } lawyer.GetRoleClass()?.OnRemove(lawyer.PlayerId); lawyer.RpcSetCustomRole(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()]); lawyer.GetRoleClass()?.OnAdd(lawyer.PlayerId); string format = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lawyer)), Translator.GetString("")); format = string.Format(format, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()])), Translator.GetString(CRoleChangeRoles[ChangeRolesAfterTargetKilled.GetValue()].ToString()))); lawyer.Notify(format); } } internal class Maverick : RoleBase { private const int Id = 13200; public static bool HasEnabled = CustomRoles.Maverick.HasEnabled(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; public static OptionItem MinKillsForWin; public int NumKills; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(13200, TabGroup.NeutralRoles, CustomRoles.Maverick); KillCooldown = FloatOptionItem.Create(13210, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Maverick]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(13211, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Maverick]); HasImpostorVision = BooleanOptionItem.Create(13213, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Maverick]); MinKillsForWin = IntegerOptionItem.Create(13214, "Maverick_MinKillsToWin", new IntegerValueRule(0, 14, 1), 2, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Maverick]); } public override void Add(byte playerId) { NumKills = 0; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override string GetProgressText(byte playerId, bool comms) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) int @int = MinKillsForWin.GetInt(); if (@int == 0) { return string.Empty; } if (!(Main.PlayerStates[playerId].RoleClass is Maverick maverick)) { return string.Empty; } int numKills = maverick.NumKills; return Utils.ColorString(Color32.op_Implicit((numKills >= @int) ? Color.green : Color.red), $"({numKills}/{@int})"); } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!isSuicide) { NumKills++; } } } internal class Medusa : RoleBase { private const int Id = 17000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem KillCooldownAfterStoneGazing; private static OptionItem CanVent; private static OptionItem HasImpostorVision; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17000, TabGroup.NeutralRoles, CustomRoles.Medusa); KillCooldown = FloatOptionItem.Create(17012, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medusa]).SetValueFormat(OptionFormat.Seconds); KillCooldownAfterStoneGazing = FloatOptionItem.Create(17015, "KillCooldownAfterStoneGazing", new FloatValueRule(0f, 180f, 2.5f), 40f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medusa]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17011, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medusa]); HasImpostorVision = BooleanOptionItem.Create(17013, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medusa]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target, PlayerControl killer) { if (reporter.Is(CustomRoles.Medusa)) { Main.UnreportableBodies.Add(target.PlayerId); reporter.Notify(Translator.GetString("MedusaStoneBody")); reporter.SetKillCooldownV3(KillCooldownAfterStoneGazing.GetFloat(), null, forceAnime: true); Logger.Info(reporter.GetRealName() + " stoned " + target.PlayerName + " body", "Medusa", escapeCRLF: true, 57, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Medusa.cs"); return false; } return true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("MedusaReportButtonText")); } } internal class Necromancer : RoleBase { private const int Id = 17100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem RevengeTime; public static PlayerControl Killer = null; private static bool IsRevenge = false; private static int Timer = 0; private static bool Success = false; private static float tempKillTimer = 0f; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17100, TabGroup.NeutralRoles, CustomRoles.Necromancer); KillCooldown = FloatOptionItem.Create(17110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necromancer]).SetValueFormat(OptionFormat.Seconds); RevengeTime = IntegerOptionItem.Create(17111, "NecromancerRevengeTime", new IntegerValueRule(0, 60, 1), 30, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necromancer]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17112, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necromancer]); HasImpostorVision = BooleanOptionItem.Create(17113, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necromancer]); } public override void Init() { playerIdList.Clear(); IsRevenge = false; Success = false; Killer = null; tempKillTimer = 0f; } public override void Add(byte playerId) { playerIdList.Add(playerId); Timer = RevengeTime.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (IsRevenge) { return true; } if ((killer.Is(CustomRoles.Retributionist) || killer.Is(CustomRoles.Nemesis)) && !killer.IsAlive()) { return true; } new LateTask(target.RpcRandomVentTeleport, 0.01f, "Random Vent Teleport - Necromancer"); Timer = RevengeTime.GetInt(); Countdown(Timer, target); IsRevenge = true; killer.SetKillCooldown(); killer.Notify(Translator.GetString("NecromancerHide"), RevengeTime.GetFloat()); tempKillTimer = target.killTimer; target.SetKillCooldown(1f); Killer = killer; return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || !killer.IsAlive()) { return false; } if (!IsRevenge) { return true; } if ((Object)(object)target == (Object)(object)Killer) { Success = true; killer.Notify(Translator.GetString("NecromancerSuccess")); killer.SetKillCooldown(KillCooldown.GetFloat() + tempKillTimer); IsRevenge = false; return true; } killer.RpcMurderPlayer(killer); return false; } private static void Countdown(int seconds, PlayerControl player) { PlayerControl killer = Killer; if (Success || !player.IsAlive()) { Timer = RevengeTime.GetInt(); Success = false; Killer = null; } else if (GameStates.IsMeeting && player.IsAlive()) { player.SetDeathReason(PlayerState.DeathReason.Kill); player.RpcExileV2(); player.Data.IsDead = true; player.Data.MarkDirty(); Main.PlayerStates[player.PlayerId].SetDead(); player.SetRealKiller(killer); Killer = null; } else if (seconds <= 0) { player.RpcMurderPlayer(player); player.SetRealKiller(killer); Killer = null; } else { player.Notify(string.Format(Translator.GetString("NecromancerRevenge"), seconds, Killer.GetRealName()), 1.1f); Timer = seconds; new LateTask(delegate { Countdown(seconds - 1, player); }, 1.01f, "Necromancer Countdown"); } } } internal class Opportunist : RoleBase { private const int Id = 13300; private static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled = PlayerIds.Any(); private static OptionItem OppoImmuneToAttacksWhenTasksDone; public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override void SetupCustomOption() { Options.SetupRoleOptions(13300, TabGroup.NeutralRoles, CustomRoles.Opportunist); OppoImmuneToAttacksWhenTasksDone = BooleanOptionItem.Create(13302, "ImmuneToAttacksWhenTasksDone", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Opportunist]); Options.OverrideTasksData.Create(13303, TabGroup.NeutralRoles, CustomRoles.Opportunist); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (OppoImmuneToAttacksWhenTasksDone.GetBool()) { return !target.AllTasksCompleted(); } return true; } } internal class Pelican : RoleBase { private const int Id = 17300; private static OptionItem KillCooldown; private static OptionItem HasImpostorVision; private static OptionItem CanVent; private static readonly Dictionary> eatenList = new Dictionary>(); private static readonly Dictionary originalSpeed = new Dictionary(); public static Dictionary PelicanLastPosition = new Dictionary(); private static int Count = 0; public static bool HasEnabled => CustomRoles.Pelican.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17300, TabGroup.NeutralRoles, CustomRoles.Pelican); KillCooldown = FloatOptionItem.Create(17310, "PelicanKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pelican]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17311, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pelican]); HasImpostorVision = BooleanOptionItem.Create(17312, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pelican]); } public override void Init() { eatenList.Clear(); originalSpeed.Clear(); PelicanLastPosition.Clear(); Count = 0; } public override void Add(byte playerId) { if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { ReturnEatenPlayerBack(Utils.GetPlayerById(playerId)); } private void SyncEatenList() { SendRPC(byte.MaxValue); foreach (KeyValuePair> eaten in eatenList) { SendRPC(eaten.Key); } } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); if (playerId != byte.MaxValue) { val.Write(eatenList[playerId].Count); foreach (byte item in eatenList[playerId]) { val.Write(item); } } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte b = reader.ReadByte(); if (b == byte.MaxValue) { eatenList.Clear(); return; } int num = reader.ReadInt32(); eatenList.Remove(b); List list = new List(); for (int i = 0; i < num; i++) { list.Add(reader.ReadByte()); } eatenList.Add(b, list); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } private static bool IsEaten(PlayerControl pc, byte id) { if (eatenList.ContainsKey(pc.PlayerId)) { return eatenList[pc.PlayerId].Contains(id); } return false; } public static bool IsEaten(byte id) { foreach (KeyValuePair> eaten in eatenList) { if (eaten.Value.Contains(id)) { return true; } } return false; } public static bool CanEat(PlayerControl pc, byte id) { if (!pc.Is(CustomRoles.Pelican) || GameStates.IsMeeting) { return false; } PlayerControl target = Utils.GetPlayerById(id); List list = Utils.GetRoleBasesByType()?.ToList(); if (list != null && list.Any(delegate(Penguin pg) { byte playerId = target.PlayerId; PlayerControl abductVictim = pg.AbductVictim; return playerId == ((abductVictim != null) ? new byte?(abductVictim.PlayerId) : null); })) { return false; } if ((Object)(object)target != (Object)null && target.CanBeTeleported() && !target.Is(CustomRoles.Pestilence) && !Medic.ProtectList.Contains(target.PlayerId) && !target.Is(CustomRoles.GM) && !IsEaten(pc, id)) { return !IsEaten(id); } return false; } public static Vector2 GetBlackRoomPSForPelican() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) return (Vector2)(Utils.GetActiveMapId() switch { 0 => new Vector2(-27f, 3.3f), 1 => new Vector2(-11.4f, 8.2f), 2 => new Vector2(42.6f, -19.9f), 3 => new Vector2(27f, 3.3f), 4 => new Vector2(-16.8f, -6.2f), 5 => new Vector2(9.6f, 23.2f), _ => throw new NotImplementedException(), }); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override string GetProgressText(byte playerId, bool coooms) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) int num = 0; if (eatenList.ContainsKey(playerId)) { num = eatenList[playerId].Count; } return Utils.ColorString(Color32.op_Implicit((num < 1) ? Color.gray : Utils.GetRoleColor(CustomRoles.Pelican)), $"({num})"); } private void EatPlayer(PlayerControl pc, PlayerControl target) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pc == (Object)null || (Object)(object)target == (Object)null || !target.CanBeTeleported()) { return; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { pc.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceMini)), Translator.GetString("CantEat"))); return; } if (!eatenList.ContainsKey(pc.PlayerId)) { eatenList.Add(pc.PlayerId, new List()); } eatenList[pc.PlayerId].Add(target.PlayerId); SyncEatenList(); originalSpeed.Remove(target.PlayerId); originalSpeed.Add(target.PlayerId, Main.AllPlayerSpeed[target.PlayerId]); target.RpcTeleport(GetBlackRoomPSForPelican()); Main.AllPlayerSpeed[target.PlayerId] = 0.5f; ReportDeadBodyPatch.CanReport[target.PlayerId] = false; target.MarkDirtySettings(); Utils.NotifyRoles(pc); Utils.NotifyRoles(target); Logger.Info(pc.GetRealName() + " eat player => " + target.GetRealName(), "Pelican", escapeCRLF: true, 170, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pelican.cs"); } public override void OnReportDeadBody(PlayerControl Nah_Id, NetworkedPlayerInfo win) { foreach (KeyValuePair> eaten in eatenList) { foreach (byte item in eaten.Value) { PlayerControl playerById = Utils.GetPlayerById(item); PlayerControl playerById2 = Utils.GetPlayerById(eaten.Key); if (!((Object)(object)playerById2 == (Object)null) && !((Object)(object)playerById == (Object)null)) { Main.AllPlayerSpeed[item] = Main.AllPlayerSpeed[item] - 0.5f + originalSpeed[item]; ReportDeadBodyPatch.CanReport[item] = true; playerById.RpcExileV2(); playerById.SetRealKiller(playerById2); item.SetDeathReason(PlayerState.DeathReason.Eaten); Main.PlayerStates[item].SetDead(); MurderPlayerPatch.AfterPlayerDeathTasks(playerById2, playerById, inMeeting: true); Logger.Info(playerById2.GetRealName() + " 消化了 " + playerById.GetRealName(), "Pelican", escapeCRLF: true, 189, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pelican.cs"); } } } eatenList.Clear(); SyncEatenList(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (CanEat(killer, target.PlayerId)) { EatPlayer(killer, target); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(killer); } killer.SetKillCooldown(); killer.RPCPlayCustomSound("Eat"); target.RPCPlayCustomSound("Eat"); } else { killer.SetKillCooldown(); killer.Notify(Translator.GetString("Pelican.TargetCannotBeEaten")); } return false; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (killer.Is(CustomRoles.Scavenger) || killer.Is(CustomRoles.Pelican)) { PelicanLastPosition[target.PlayerId] = target.GetCustomPosition(); } return true; } public override void OnMurderPlayerAsTarget(PlayerControl SLAT, PlayerControl pelican, bool inMeeting, bool isSuicide) { if (!inMeeting) { ReturnEatenPlayerBack(pelican); } } private void ReturnEatenPlayerBack(PlayerControl pelican) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) byte playerId = pelican.PlayerId; if (!eatenList.ContainsKey(playerId)) { return; } GameEndCheckerForNormal.ShouldNotCheck = true; try { Vector2 value; Vector2 val = ((!Scavenger.KilledPlayersId.Contains(playerId) || !PelicanLastPosition.TryGetValue(playerId, out value)) ? pelican.GetCustomPosition() : value); foreach (byte item in eatenList[playerId]) { PlayerControl playerById = Utils.GetPlayerById(item); if (!((Object)(object)Utils.GetPlayerById(playerId) == (Object)null) && !((Object)(object)playerById == (Object)null)) { playerById.RpcTeleport(val); Main.AllPlayerSpeed[item] = Main.AllPlayerSpeed[item] - 0.5f + originalSpeed[item]; ReportDeadBodyPatch.CanReport[item] = true; playerById.SyncSettings(); RPC.PlaySoundRPC(item, Sounds.TaskComplete); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(31, 3); object value2; if (pelican == null) { value2 = null; } else { NetworkedPlayerInfo data = pelican.Data; value2 = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral(" dead, player return back: "); object value3; if (playerById == null) { value3 = null; } else { NetworkedPlayerInfo data2 = playerById.Data; value3 = ((data2 != null) ? data2.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value3); defaultInterpolatedStringHandler.AppendLiteral(" in "); defaultInterpolatedStringHandler.AppendFormatted(val); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Pelican", escapeCRLF: true, 256, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pelican.cs"); } } eatenList.Remove(playerId); SyncEatenList(); Utils.NotifyRoles(); } catch (Exception ex) { Utils.ThrowException(ex, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pelican.cs", 264, "ReturnEatenPlayerBack"); } GameEndCheckerForNormal.ShouldNotCheck = false; } public override void OnFixedUpdateLowLoad(PlayerControl pelican) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Count--; if (Count > 0) { return; } Count = 2; foreach (List value in eatenList.Values) { byte[] array = value.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!((Object)(object)playerById == (Object)null)) { Vector2 blackRoomPSForPelican = GetBlackRoomPSForPelican(); if (!(Vector2.Distance(blackRoomPSForPelican, playerById.GetCustomPosition()) < 1f)) { playerById.RpcTeleport(blackRoomPSForPelican, isRandomSpawn: false, sendInfoInLogs: false); } } } } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("PelicanButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Vulture"); } } internal class Pickpocket : RoleBase { private const int Id = 17400; private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem VotesPerKill; private static OptionItem HideAdditionalVotes; public static bool HasEnabled => CustomRoles.Pickpocket.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17400, TabGroup.NeutralRoles, CustomRoles.Pickpocket); KillCooldown = FloatOptionItem.Create(17410, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pickpocket]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17411, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pickpocket]); HasImpostorVision = BooleanOptionItem.Create(17413, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pickpocket]); VotesPerKill = FloatOptionItem.Create(17412, "VotesPerKill", new FloatValueRule(0.1f, 10f, 0.1f), 0.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pickpocket]); HideAdditionalVotes = BooleanOptionItem.Create(17414, GeneralOption.HideAdditionalVotes, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pickpocket]); } public override void Add(byte playerId) { if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override int AddRealVotesNum(PlayerVoteArea ps) { return (int)((float)Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == ps.TargetPlayerId; }) * VotesPerKill.GetFloat()); } public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!HideAdditionalVotes.GetBool()) { int num = (int)((float)Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == votedPlayer.TargetPlayerId; }) * VotesPerKill.GetFloat()); for (int i = 0; i < num; i++) { statesList.Add(new VoterState { VoterId = votedPlayer.TargetPlayerId, VotedForId = votedPlayer.VotedFor }); } } } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!(isSuicide || inMeeting)) { killer.Notify(string.Format(Translator.GetString("PickpocketGetVote"), ((float)(Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == killer.PlayerId; }) + 1) * VotesPerKill.GetFloat()).ToString("0.0#####"))); } } } internal class Pirate : RoleBase { private const int Id = 15000; private static OptionItem SuccessfulDuelsToWin; private static OptionItem TryHideMsg; private static OptionItem DuelCooldown; private static readonly Dictionary DuelDone = new Dictionary(); private static byte PirateTarget; private static int pirateChose; private static int targetChose; public static int NumWin = 0; public static bool HasEnabled => CustomRoles.Pirate.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(15000, TabGroup.NeutralRoles, CustomRoles.Pirate); DuelCooldown = FloatOptionItem.Create(15012, "DuelCooldown", new FloatValueRule(0f, 180f, 2.5f), 22.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pirate]).SetValueFormat(OptionFormat.Seconds); TryHideMsg = BooleanOptionItem.Create(15010, "PirateTryHideMsg", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pirate]).SetColor(Color.green); SuccessfulDuelsToWin = IntegerOptionItem.Create(15011, "SuccessfulDuelsToWin", new IntegerValueRule(1, 20, 1), 2, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pirate]).SetValueFormat(OptionFormat.Times); } public override void Init() { PirateTarget = byte.MaxValue; DuelDone.Clear(); pirateChose = -1; targetChose = -1; NumWin = 0; } public override void Add(byte playerId) { DuelDone.Add(playerId, value: false); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void MeetingHudClear() { if (!HasEnabled || PirateTarget == byte.MaxValue) { return; } PlayerControl pc = base._Player; PlayerControl tpc = Utils.GetPlayerById(PirateTarget); if (tpc.IsAlive()) { new LateTask(delegate { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(Translator.GetString("PirateMeetingMsg"), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pirate)), Translator.GetString("PirateTitle"))); Utils.SendMessage(Translator.GetString("PirateTargetMeetingMsg"), tpc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pirate)), Translator.GetString("PirateTitle"))); }, 3f, "Pirate Meeting Messages"); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = DuelCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pirate).ShadeColor(0.25f)), $"({NumWin}/{SuccessfulDuelsToWin.GetInt()})"); } public void SendRPC(int operate, byte target = byte.MaxValue, int points = -1) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(operate); val.Write(target); if (operate == 1) { val.Write(points); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { int num = reader.ReadInt32(); PirateTarget = reader.ReadByte(); if (num == 1) { NumWin = reader.ReadInt32(); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("CantDuel"))); return true; } if (target.Is(CustomRoles.Pestilence)) { return true; } if (PirateTarget != byte.MaxValue) { killer.Notify(Translator.GetString("PirateTargetAlreadyChosen")); return false; } Logger.Msg(killer.GetNameWithRole() + " chose a target " + target.GetNameWithRole(), "Pirate", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pirate.cs"); PirateTarget = target.PlayerId; SendRPC(0, target.PlayerId); DuelDone.Add(PirateTarget, value: false); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(killer); } else { killer.SetKillCooldown(); } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("PirateDuelButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Challenge"); } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isMeeting = false) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target != (Object)null && isMeeting && target.PlayerId == PirateTarget) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pirate)), " ⦿"); } return ""; } public override void AfterMeetingTasks() { byte playerId = _state.PlayerId; if (PirateTarget != byte.MaxValue && DuelDone[playerId]) { if (DuelDone[PirateTarget]) { if (targetChose == pirateChose) { NumWin++; if (Utils.GetPlayerById(PirateTarget).IsAlive()) { CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Pirate, PirateTarget); Utils.GetPlayerById(PirateTarget).SetRealKiller(Utils.GetPlayerById(playerId)); } } } else if (Utils.GetPlayerById(PirateTarget).IsAlive()) { CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Pirate, PirateTarget); Utils.GetPlayerById(PirateTarget).SetRealKiller(Utils.GetPlayerById(playerId)); } } if (NumWin >= SuccessfulDuelsToWin.GetInt()) { NumWin = SuccessfulDuelsToWin.GetInt(); if (!CustomWinnerHolder.CheckForConvertedWinner(playerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Pirate); CustomWinnerHolder.WinnerIds.Add(playerId); } } DuelDone.Clear(); PirateTarget = byte.MaxValue; SendRPC(1, byte.MaxValue, NumWin); foreach (byte item in from x in Main.PlayerStates.Values where x.MainRole == CustomRoles.Pirate select x.PlayerId) { DuelDone.Add(item, value: false); } } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { PirateTarget = byte.MaxValue; SendRPC(1, byte.MaxValue, NumWin); } public static bool DuelCheckMsg(PlayerControl pc, string msg, bool isUI = false) { string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null || GameStates.IsExilling) { return false; } if (!pc.Is(CustomRoles.Pirate) && PirateTarget != pc.PlayerId) { return false; } msg = msg.ToLower().TrimStart().TrimEnd(); bool flag = false; if (CheckCommond(ref msg, "duel")) { flag = true; if (!pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("PirateDead")); return true; } if (flag) { if (TryHideMsg.GetBool()) { TryHideMsgForDuel(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var rpsOption, out var error)) { Utils.SendMessage(error, pc.PlayerId); return true; } Logger.Info($"{pc.GetNameWithRole()} selected {rpsOption}", "Pirate", escapeCRLF: true, 220, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pirate.cs"); if (DuelDone[pc.PlayerId]) { new LateTask(delegate { pc.ShowInfoMessage(isUI, Translator.GetString("DuelAlreadyDone")); Logger.Msg("Duel attempted more than once", "Pirate", escapeCRLF: true, 227, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pirate.cs"); }, 0.2f, "Pirate Duel Already Done"); return true; } if (pc.Is(CustomRoles.Pirate)) { pirateChose = rpsOption; } else { targetChose = rpsOption; } new LateTask(delegate { pc.ShowInfoMessage(isUI, string.Format(Translator.GetString("DuelDone"), rpsOption)); }, 0.2f, "Pirate Duel Done"); DuelDone[pc.PlayerId] = true; return true; } return true; } return false; } private static bool MsgToPlayerAndRole(string msg, out int rpsOpt, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } MatchCollection matchCollection = new Regex("\\d+").Matches(msg); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { text += matchCollection[i]; } if (int.TryParse(text, out var result)) { if (result < 0 || result > 2) { rpsOpt = -1; error = Translator.GetString("DuelHelp"); return false; } rpsOpt = result; error = string.Empty; return true; } rpsOpt = -1; error = Translator.GetString("DuelHelp"); return false; } public static bool CheckCommond(ref string msg, string command) { string[] array = command.Split('|'); for (int i = 0; i < array.Length; i++) { if (msg.StartsWith("/" + array[i])) { msg = msg.Replace("/" + array[i], string.Empty); return true; } } return false; } public static void TryHideMsgForDuel() { ChatUpdatePatch.DoBlockChat = true; CustomRolesHelper.AllRoles.Where((CustomRoles x) => x != CustomRoles.NotAssigned).ToList(); IRandom instance = IRandom.Instance; string[] array = new string[2] { "duel", "rps" }; for (int i = 0; i < 20; i++) { string text = "/"; if (instance.Next(1, 100) < 20) { text += "id"; } else { text += array[instance.Next(0, array.Length - 1)]; text += " "; text += instance.Next(0, 3); } PlayerControl val = Main.AllAlivePlayerControls.RandomElement(); DestroyableSingleton.Instance.Chat.AddChat(val, text, true); CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(text).EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } ChatUpdatePatch.DoBlockChat = false; } } internal class Pixie : RoleBase { private const int Id = 25900; private static OptionItem PixiePointsToWin; private static OptionItem PixieMaxTargets; private static OptionItem PixieMarkCD; private static OptionItem PixieSuicideOpt; private static readonly Dictionary> PixieTargets = new Dictionary>(); private static readonly Dictionary PixiePoints = new Dictionary(); public static bool HasEnabled => CustomRoles.Pirate.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(25900, TabGroup.NeutralRoles, CustomRoles.Pixie); PixiePointsToWin = IntegerOptionItem.Create(25910, "PixiePointsToWin", new IntegerValueRule(1, 14, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pixie]).SetValueFormat(OptionFormat.Times); PixieMaxTargets = IntegerOptionItem.Create(25911, "MaxTargets", new IntegerValueRule(1, 14, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pixie]).SetValueFormat(OptionFormat.Players); PixieMarkCD = FloatOptionItem.Create(25912, "MarkCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pixie]).SetValueFormat(OptionFormat.Seconds); PixieSuicideOpt = BooleanOptionItem.Create(25913, "PixieSuicide", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pixie]); } public override void Init() { PixieTargets.Clear(); PixiePoints.Clear(); } public override void Add(byte playerId) { PixieTargets[playerId] = new HashSet(); PixiePoints.Add(playerId, 0); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { PixieTargets.Remove(playerId); PixiePoints.Remove(playerId); } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pixie).ShadeColor(0.25f)), PixiePoints.TryGetValue(playerId, out value) ? $"({value}/{PixiePointsToWin.GetInt()})" : "Invalid"); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = PixieMarkCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return false; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("PixieButtonText")); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { string result = string.Empty; if (seer.Is(CustomRoles.Pixie) && PixieTargets[seer.PlayerId].Contains(target.PlayerId)) { result = Main.roleColors[CustomRoles.Pixie]; } return result; } public void SendRPC(byte pixieId, bool operate, byte targetId = byte.MaxValue) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(pixieId); val.Write(operate); if (!operate) { val.Write(targetId); } else { val.Write(PixiePoints[pixieId]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); if (!reader.ReadBoolean()) { if (!PixieTargets.ContainsKey(key)) { PixieTargets[key] = new HashSet(); } byte item = reader.ReadByte(); PixieTargets[key].Add(item); return; } int value = reader.ReadInt32(); if (!PixiePoints.ContainsKey(key)) { PixiePoints[key] = 0; } PixiePoints[key] = value; PixieTargets[key].Clear(); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } byte playerId = target.PlayerId; byte playerId2 = killer.PlayerId; if (!PixieTargets.ContainsKey(playerId2)) { PixieTargets[playerId2] = new HashSet(); } if (PixieTargets[playerId2].Count >= PixieMaxTargets.GetInt()) { killer.Notify(Translator.GetString("PixieMaxTargetReached")); Logger.Info($"Max targets per round already reached, {PixieTargets[playerId2].Count}/{PixieMaxTargets.GetInt()}", "Pixie", escapeCRLF: true, 119, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pixie.cs"); return false; } if (PixieTargets[playerId2].Contains(playerId)) { killer.Notify(Translator.GetString("PixieTargetAlreadySelected")); return false; } PixieTargets[playerId2].Add(playerId); SendRPC(playerId2, operate: false, playerId); Utils.NotifyRoles(killer); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(killer); } SetKillCooldown(killer.PlayerId); return false; } public override void OnPlayerExiled(PlayerControl pc, NetworkedPlayerInfo exiled) { byte playerId = pc.PlayerId; if (!PixieTargets.ContainsKey(playerId)) { return; } if ((Object)(object)exiled != (Object)null) { if (PixieTargets[playerId].Count == 0) { return; } if (!PixiePoints.ContainsKey(playerId)) { PixiePoints[playerId] = 0; } if (PixiePoints[playerId] >= PixiePointsToWin.GetInt()) { return; } if (PixieTargets[playerId].Contains(exiled.PlayerId)) { PixiePoints[playerId]++; } else if (PixieSuicideOpt.GetBool() && PixieTargets[playerId].Any((byte eid) => Utils.GetPlayerById(eid)?.IsAlive() ?? false)) { pc.SetRealKiller(pc); CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, playerId); Logger.Info(pc.GetNameWithRole() + " committed suicide because target not exiled and target(s) were alive during ejection", "Pixie", escapeCRLF: true, 155, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pixie.cs"); } } PixieTargets[playerId].Clear(); SendRPC(playerId, operate: true); } public static void PixieWinCondition(PlayerControl pc) { if (!((Object)(object)pc == (Object)null) && PixiePoints.TryGetValue(pc.PlayerId, out var value) && value >= PixiePointsToWin.GetInt()) { CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Pixie); } } } internal class PlagueBearer : RoleBase { private const int Id = 17600; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem PlagueBearerCooldownOpt; public static OptionItem PestilenceCooldownOpt; public static OptionItem PestilenceCanVent; public static OptionItem PestilenceHasImpostorVision; private static readonly Dictionary> PlaguedList = new Dictionary>(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17600, TabGroup.NeutralRoles, CustomRoles.PlagueBearer); PlagueBearerCooldownOpt = FloatOptionItem.Create(17610, "PlagueBearerCooldown", new FloatValueRule(0f, 180f, 2.5f), 22.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueBearer]).SetValueFormat(OptionFormat.Seconds); PestilenceCooldownOpt = FloatOptionItem.Create(17611, "PestilenceCooldown", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueBearer]).SetValueFormat(OptionFormat.Seconds); PestilenceCanVent = BooleanOptionItem.Create(17612, "PestilenceCanVent", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueBearer]); PestilenceHasImpostorVision = BooleanOptionItem.Create(17613, "PestilenceHasImpostorVision", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueBearer]); } public override void Init() { playerIdList.Clear(); PlaguedList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); PlaguedList[playerId] = new HashSet(); CustomRoleManager.CheckDeadBodyOthers.Add(OnPlayerDead); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); PlaguedList.Remove(playerId); CustomRoleManager.CheckDeadBodyOthers.Remove(OnPlayerDead); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = PlagueBearerCooldownOpt.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } private static bool IsPlagued(byte pc, byte target) { if (PlaguedList.TryGetValue(pc, out var value)) { return value.Contains(target); } return false; } public static void SendRPC(PlayerControl player, PlayerControl target) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)Utils.GetPlayerById(playerIdList.First())); val.Write(player.PlayerId); val.Write(target.PlayerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); byte item = reader.ReadByte(); PlaguedList[key].Add(item); } public static void CheckAndInfect(PlayerControl seer, PlayerControl target) { bool flag = seer.PlayerId == target.PlayerId; bool flag2 = false; foreach (KeyValuePair> plagued in PlaguedList) { plagued.Deconstruct(out var key, out var value); byte b = key; HashSet hashSet = value; PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { if (target.Is(CustomRoles.PlagueBearer) && !flag) { PlaguedList[b].Add(seer.PlayerId); SendRPC(playerById, seer); flag2 = true; } else if (flag) { flag2 = true; } else if (hashSet.Contains(seer.PlayerId) && !hashSet.Contains(target.PlayerId)) { PlaguedList[b].Add(target.PlayerId); SendRPC(playerById, target); flag2 = true; } else if (!hashSet.Contains(seer.PlayerId) && hashSet.Contains(target.PlayerId)) { PlaguedList[b].Add(seer.PlayerId); SendRPC(playerById, seer); flag2 = true; } PlaguedList[b].Remove(b); } } if (flag2) { Utils.NotifyRoles(); CheckPlagueAllPlayers(); } } private static (int, int) PlaguedPlayerCount(byte playerId) { int item = Main.AllAlivePlayerControls.Count((PlayerControl pc) => pc.PlayerId != playerId); return (Main.AllAlivePlayerControls.Count((PlayerControl pc) => pc.PlayerId != playerId && IsPlagued(playerId, pc.PlayerId)), item); } private static bool IsPlaguedAll(PlayerControl player) { if (!player.Is(CustomRoles.PlagueBearer)) { return false; } var (num, num2) = PlaguedPlayerCount(player.PlayerId); return num >= num2; } public static void CheckPlagueAllPlayers() { foreach (byte key in PlaguedList.Keys) { PlayerControl playerById = Utils.GetPlayerById(key); if (!((Object)(object)playerById == (Object)null) && IsPlaguedAll(playerById)) { playerIdList.Remove(key); playerById.RpcSetCustomRole(CustomRoles.Pestilence); playerById.GetRoleClass()?.OnAdd(key); playerById.Notify(Translator.GetString("PlagueBearerToPestilence"), 2f); playerById.RpcGuardAndKill(playerById); playerById.ResetKillCooldown(); Utils.NotifyRoles(playerById); playerById.MarkDirtySettings(); } } } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (IsPlagued(killer.PlayerId, target.PlayerId)) { killer.Notify(Translator.GetString("PlagueBearerAlreadyPlagued")); return false; } PlaguedList[killer.PlayerId].Add(target.PlayerId); SendRPC(killer, target); Utils.NotifyRoles(killer); CheckPlagueAllPlayers(); killer.ResetKillCooldown(); killer.SetKillCooldown(); return false; } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (HasEnabled && (Object)(object)deadBody != (Object)null && (Object)(object)deadBody.Object != (Object)null) { CheckAndInfect(reporter, deadBody.Object); } return true; } private void OnPlayerDead(PlayerControl killer, PlayerControl deadBody, bool inMeeting) { if (HasEnabled) { CheckAndInfect(killer, deadBody); } } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!IsPlagued(seer.PlayerId, seen.PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pestilence)), "⦿"); } public override string GetProgressText(byte playerId, bool comms) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) var (value, value2) = PlaguedPlayerCount(playerId); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.PlagueBearer).ShadeColor(0.25f)), $"({value}/{value2})"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("InfectiousKillButtonText")); } } internal class Pestilence : RoleBase { public static bool HasEnabled => CustomRoles.PlagueBearer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void Add(byte playerId) { if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = PlagueBearer.PestilenceCooldownOpt.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(PlagueBearer.PestilenceHasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return PlagueBearer.PestilenceCanVent.GetBool(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { killer.SetRealKiller(target); target.RpcMurderPlayer(killer); return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessPestilence")); guesserSuicide = true; Logger.Msg($"Is Active: {guesserSuicide}", "guesserSuicide - Pestilence", escapeCRLF: true, 243, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\PlagueBearer.cs"); return false; } } internal class PlagueDoctor : RoleBase { private const int Id = 27600; private static OptionItem OptionInfectLimit; private static OptionItem OptionInfectWhenKilled; private static OptionItem OptionInfectTime; private static OptionItem OptionInfectDistance; private static OptionItem OptionInfectInactiveTime; private static OptionItem OptionInfectCanInfectSelf; private static OptionItem OptionInfectCanInfectVent; private int InfectCount; private bool InfectActive; private bool LateCheckWin; private static bool InfectWhenKilled; private float InfectTime; private float InfectDistance; private static float InfectInactiveTime; private static bool CanInfectSelf; private static bool CanInfectVent; private static readonly Dictionary InfectInfos = new Dictionary(); public static bool HasEnabled => CustomRoles.PlagueDoctor.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(27600, TabGroup.NeutralRoles, CustomRoles.PlagueDoctor); OptionInfectLimit = IntegerOptionItem.Create(27610, "PlagueDoctorInfectLimit", new IntegerValueRule(1, 3, 1), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]).SetValueFormat(OptionFormat.Times); OptionInfectWhenKilled = BooleanOptionItem.Create(27611, "PlagueDoctorInfectWhenKilled", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]); OptionInfectTime = FloatOptionItem.Create(27612, "PlagueDoctorInfectTime", new FloatValueRule(3f, 20f, 1f), 8f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]).SetValueFormat(OptionFormat.Seconds); OptionInfectDistance = FloatOptionItem.Create(27613, "PlagueDoctorInfectDistance", new FloatValueRule(0.5f, 2f, 0.25f), 1.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]).SetValueFormat(OptionFormat.Multiplier); OptionInfectInactiveTime = FloatOptionItem.Create(27614, "PlagueDoctorInfectInactiveTime", new FloatValueRule(0.5f, 10f, 0.5f), 3.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]).SetValueFormat(OptionFormat.Seconds); OptionInfectCanInfectSelf = BooleanOptionItem.Create(27615, "PlagueDoctorCanInfectSelf", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]); OptionInfectCanInfectVent = BooleanOptionItem.Create(27616, "PlagueDoctorCanInfectVent", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PlagueDoctor]); } public override void Init() { InfectInfos.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = OptionInfectLimit.GetInt(); InfectWhenKilled = OptionInfectWhenKilled.GetBool(); InfectTime = OptionInfectTime.GetFloat(); InfectDistance = OptionInfectDistance.GetFloat(); InfectInactiveTime = OptionInfectInactiveTime.GetFloat(); CanInfectSelf = OptionInfectCanInfectSelf.GetBool(); CanInfectVent = OptionInfectCanInfectVent.GetBool(); InfectCount = (int)base.AbilityLimit; InfectActive = true; if (Main.NormalOptions.MapId == 4) { InfectInactiveTime += 5f; } if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateOthers.Add(OnCheckPlayerPosition); CustomRoleManager.CheckDeadBodyOthers.Add(OnAnyMurder); } } public override bool CanUseKillButton(PlayerControl pc) { return InfectCount != 0; } public override string GetProgressText(byte plr, bool coomns) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.PlagueDoctor).ShadeColor(0.25f)), $"({InfectCount})"); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpVision: false); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("InfectiousKillButtonText")); } public bool CanInfect(PlayerControl player) { if (!((Object)(object)player != (Object)(object)base._Player)) { if (CanInfectSelf) { return InfectCount == 0; } return false; } return true; } public void SendRPC(byte targetId, float rate, bool firstInfect) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(firstInfect); val.Write(targetId); val.Write(rate); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { bool num = reader.ReadBoolean(); byte key = reader.ReadByte(); float value = reader.ReadSingle(); if (num) { InfectCount = 0; } InfectInfos[key] = value; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (InfectCount > 0) { InfectCount = 0; killer.RpcGuardAndKill(target); DirectInfect(target, killer); } return false; } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (InfectWhenKilled && InfectCount > 0) { InfectCount = 0; DirectInfect(killer, target); } } private void OnAnyMurder(PlayerControl killer, PlayerControl target, bool inMeeting) { LateCheckWin = true; } public override void OnReportDeadBody(PlayerControl W, NetworkedPlayerInfo L) { InfectActive = false; } private void OnCheckPlayerPosition(PlayerControl player) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if (LateCheckWin) { LateCheckWin = false; CheckWin(); } if (!player.IsAlive() || (Object)(object)player == (Object)null || !InfectActive || !InfectInfos.TryGetValue(player.PlayerId, out var value) || !(value >= 100f)) { return; } bool flag = false; bool inVent = player.inVent; List list = new List(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!CanInfect(val) || (!CanInfectVent && val.inVent != inVent)) { continue; } InfectInfos.TryGetValue(val.PlayerId, out var value2); if (!(value2 >= 100f) && !(Vector3.Distance(((Component)player).transform.position, ((Component)val).transform.position) > InfectDistance)) { float value3 = value2 + Time.fixedDeltaTime / InfectTime * 100f; value3 = Math.Clamp(value3, 0f, 100f); InfectInfos[val.PlayerId] = value3; if ((value2 < 50f && value3 >= 50f) || value3 >= 100f) { flag = true; list.Add(val); Logger.Info($"InfectRate [{val.GetNameWithRole()}]: {value3}%", "PlagueDoctor", escapeCRLF: true, 197, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\PlagueDoctor.cs"); SendRPC(val.PlayerId, value3, firstInfect: false); } } } if (flag) { CheckWin(); PlayerControl player2 = base._Player; allAlivePlayerControls = list.ToArray(); foreach (PlayerControl specifyTarget in allAlivePlayerControls) { Utils.NotifyRoles(player2, specifyTarget); } } } public override void AfterMeetingTasks() { LateCheckWin = true; new LateTask(delegate { Logger.Info("Infect Active", "PlagueDoctor", escapeCRLF: true, 220, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\PlagueDoctor.cs"); InfectActive = true; }, InfectInactiveTime, "ResetInfectInactiveTime"); } public override string GetMarkOthers(PlayerControl seer, PlayerControl seen = null, bool Isformeetingguwno = false) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!CanInfect(seen)) { return string.Empty; } if (!seer.Is(CustomRoles.PlagueDoctor) && seer.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.PlagueDoctor)), GetInfectRateCharactor(seen)); } public override string GetLowerTextOthers(PlayerControl seer, PlayerControl seen = null, bool isformeetingguwno = false, bool znowupierdol = false) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!seen.Is(CustomRoles.PlagueDoctor)) { return string.Empty; } if (!seer.Is(CustomRoles.PlagueDoctor) && seer.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(40); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!val.Is(CustomRoles.PlagueDoctor)) { stringBuilder.Append(GetInfectRateCharactor(val)); } } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.PlagueDoctor)), stringBuilder.ToString()); } private static bool IsInfected(byte playerId) { InfectInfos.TryGetValue(playerId, out var value); return value >= 100f; } private string GetInfectRateCharactor(PlayerControl player) { if (!HasEnabled) { return string.Empty; } if (!CanInfect(player) || !player.IsAlive()) { return string.Empty; } InfectInfos.TryGetValue(player.PlayerId, out var value); if (!(value < 50f)) { if (value >= 50f) { if (value < 100f) { return "▄"; } return "█"; } return string.Empty; } return "▁"; } private void DirectInfect(PlayerControl target, PlayerControl plague) { if (!((Object)(object)target == (Object)null)) { Logger.Info("InfectRate [" + target.GetNameWithRole() + "]: 100%", "PlagueDoctor", escapeCRLF: true, 268, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\PlagueDoctor.cs"); InfectInfos[target.PlayerId] = 100f; SendRPC(target.PlayerId, 100f, firstInfect: true); Utils.NotifyRoles(plague, target); CheckWin(); } } private void CheckWin() { if (!HasEnabled || !((InnerNetClient)AmongUsClient.Instance).AmHost || CustomWinnerHolder.WinnerTeam != CustomWinner.Default || !Main.AllAlivePlayerControls.All((PlayerControl p) => p.Is(CustomRoles.PlagueDoctor) || IsInfected(p.PlayerId))) { return; } InfectActive = false; CustomWinnerHolder.ResetAndSetWinner(CustomWinner.PlagueDoctor); PlayerControl[] array = Main.AllPlayerControls.Where((PlayerControl p) => p.Is(CustomRoles.PlagueDoctor)).ToArray(); foreach (PlayerControl val in array) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } array = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in array) { if (!val2.Is(CustomRoles.PlagueDoctor)) { val2.SetDeathReason(PlayerState.DeathReason.Infected); val2.RpcMurderPlayer(val2); } } } } internal class Poisoner : RoleBase { private class PoisonedInfo { public byte PoisonerId; public float KillTimer; public PoisonedInfo(byte poisonerId, float killTimer) { PoisonerId = poisonerId; KillTimer = killTimer; base..ctor(); } } private const int Id = 17500; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem OptionKillDelay; private static OptionItem CanVent; public static OptionItem KillCooldown; private static OptionItem HasImpostorVision; private static readonly Dictionary PoisonedPlayers = new Dictionary(); private static float KillDelay; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17500, TabGroup.NeutralRoles, CustomRoles.Poisoner); KillCooldown = FloatOptionItem.Create(17510, "PoisonCooldown", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Poisoner]).SetValueFormat(OptionFormat.Seconds); OptionKillDelay = FloatOptionItem.Create(17511, "PoisonerKillDelay", new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Poisoner]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17512, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Poisoner]); HasImpostorVision = BooleanOptionItem.Create(17513, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Poisoner]); } public override void Init() { playerIdList.Clear(); PoisonedPlayers.Clear(); KillDelay = OptionKillDelay.GetFloat(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (target.Is(CustomRoles.Bait)) { return true; } killer.SetKillCooldown(); if (!PoisonedPlayers.ContainsKey(target.PlayerId)) { PoisonedPlayers.Add(target.PlayerId, new PoisonedInfo(killer.PlayerId, 0f)); } return false; } public override void OnFixedUpdate(PlayerControl poisoner) { byte poisonerID = poisoner.PlayerId; List list = new List(from b in PoisonedPlayers where b.Value.PoisonerId == poisonerID select b.Key); for (int i = 0; i < list.Count; i++) { byte b2 = list[i]; PoisonedInfo poisonedInfo = PoisonedPlayers[b2]; if (poisonedInfo.KillTimer >= KillDelay) { PlayerControl playerById = Utils.GetPlayerById(b2); KillPoisoned(poisoner, playerById); PoisonedPlayers.Remove(b2); } else { poisonedInfo.KillTimer += Time.fixedDeltaTime; PoisonedPlayers[b2] = poisonedInfo; } } } private static void KillPoisoned(PlayerControl poisoner, PlayerControl target, bool isButton = false) { if ((Object)(object)poisoner == (Object)null || (Object)(object)target == (Object)null || target.Data.Disconnected) { return; } if (target.IsAlive()) { target.SetDeathReason(PlayerState.DeathReason.Poison); target.RpcMurderPlayer(target); target.SetRealKiller(poisoner); Logger.Info(target.GetRealName() + " Died by Poison", "Poisoner", escapeCRLF: true, 107, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Poisoner.cs"); if (!isButton && poisoner.IsAlive()) { RPC.PlaySoundRPC(poisoner.PlayerId, Sounds.KillSound); if (target.Is(CustomRoles.Trapper)) { poisoner.TrapperKilled(target); } poisoner.Notify(Translator.GetString("PoisonerTargetDead")); poisoner.SetKillCooldown(); } } else { Logger.Info(target.GetRealName() + " was in an unkillable state, poison was canceled", "Poisoner", escapeCRLF: true, 119, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Poisoner.cs"); } } public override void OnReportDeadBody(PlayerControl sans, NetworkedPlayerInfo bateman) { foreach (byte key in PoisonedPlayers.Keys) { PlayerControl playerById = Utils.GetPlayerById(key); KillPoisoned(Utils.GetPlayerById(PoisonedPlayers[key].PoisonerId), playerById); } PoisonedPlayers.Clear(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("PoisonerPoisonButtonText")); } } internal class PotionMaster : RoleBase { private const int Id = 17700; private static OptionItem KillCooldown; private static OptionItem RitualMaxCount; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static readonly Dictionary> RitualTarget = new Dictionary>(); public static bool HasEnabled => CustomRoles.PotionMaster.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17700, TabGroup.NeutralRoles, CustomRoles.PotionMaster); KillCooldown = FloatOptionItem.Create(17714, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PotionMaster]).SetValueFormat(OptionFormat.Seconds); RitualMaxCount = IntegerOptionItem.Create(17711, "RitualMaxCount", new IntegerValueRule(1, 15, 1), 5, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PotionMaster]).SetValueFormat(OptionFormat.Times); CanVent = BooleanOptionItem.Create(17712, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PotionMaster]); HasImpostorVision = BooleanOptionItem.Create(17713, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PotionMaster]); } public override void Init() { RitualTarget.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = RitualMaxCount.GetInt(); RitualTarget.TryAdd(playerId, new List()); Utils.GetPlayerById(playerId)?.AddDoubleTrigger(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC(byte playerId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(base.AbilityLimit); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); base.AbilityLimit = reader.ReadSingle(); RitualTarget[key].Add(reader.ReadByte()); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseSabotage(PlayerControl pc) { return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (base.AbilityLimit > 0f) { return killer.CheckDoubleTrigger(target, delegate { SetRitual(killer, target); }); } return true; } public static bool IsRitual(byte seer, byte target) { if (RitualTarget[seer].Contains(target)) { return true; } return false; } private void SetRitual(PlayerControl killer, PlayerControl target) { if (!IsRitual(killer.PlayerId, target.PlayerId)) { base.AbilityLimit--; RitualTarget[killer.PlayerId].Add(target.PlayerId); Logger.Info($"{killer.GetNameWithRole()}: Divined divination destination -> {target.GetNameWithRole()} || remaining {base.AbilityLimit} times", "PotionMaster", escapeCRLF: true, 98, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\PotionMaster.cs"); Utils.NotifyRoles(killer); SendRPC(killer.PlayerId, target.PlayerId); killer.SetKillCooldown(); } } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { bool IsWatch = false; CollectionExtensions.Do>>((IEnumerable>>)RitualTarget, (Action>>)delegate(KeyValuePair> x) { if (x.Value != null && seer.PlayerId == x.Key && x.Value.Contains(target.PlayerId) && Utils.GetPlayerById(x.Key).IsAlive()) { IsWatch = true; } }); return IsWatch; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return KnowRoleTarget(seer, target); } public override string GetProgressText(byte playerId, bool coooonms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.PotionMaster).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class Provocateur : RoleBase { private const int Id = 15100; private static readonly HashSet Playerids = new HashSet(); private static OptionItem ProvKillCD; public static readonly Dictionary Provoked = new Dictionary(); public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(15100, TabGroup.NeutralRoles, CustomRoles.Provocateur); ProvKillCD = FloatOptionItem.Create(15110, GeneralOption.KillCooldown, new FloatValueRule(0f, 100f, 2.5f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Provocateur]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { Playerids.Clear(); Provoked.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ProvKillCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceMini)), Translator.GetString("CantBoom"))); return false; } target.SetDeathReason(PlayerState.DeathReason.PissedOff); killer.RpcMurderPlayer(target); killer.RpcMurderPlayer(killer); killer.SetRealKiller(target); Provoked.TryAdd(killer.PlayerId, target.PlayerId); return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("ProvocateurButtonText")); } } internal class PunchingBag : RoleBase { private const int Id = 14500; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem PunchingBagKillMax; private readonly Dictionary PunchingBagMax = new Dictionary(); private readonly HashSet BlockGuess = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupRoleOptions(14500, TabGroup.NeutralRoles, CustomRoles.PunchingBag); PunchingBagKillMax = IntegerOptionItem.Create(14502, "PunchingBagKillMax", new IntegerValueRule(1, 30, 1), 5, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.PunchingBag]).SetValueFormat(OptionFormat.Times); } public override void Init() { PlayerIds.Clear(); PunchingBagMax.Clear(); BlockGuess.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); PunchingBagMax.Add(playerId, 0); } private void SendRPC(byte punchingbagId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(punchingbagId); val.Write(PunchingBagMax[punchingbagId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); PunchingBagMax[key] = value; } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.PunchingBag).ShadeColor(0.25f)), $"({(PunchingBagMax.TryGetValue(playerId, out value) ? value : 0)}/{PunchingBagKillMax.GetInt()})"); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(-1f, target, forceAnime: true); PunchingBagMax[target.PlayerId]++; SendRPC(target.PlayerId); target.Notify(string.Format(Translator.GetString("PunchingBagKill"), PunchingBagMax[target.PlayerId])); CheckWin(); return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (BlockGuess.Contains(pc.PlayerId)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessPunchingBagAgain")); return true; } pc.ShowInfoMessage(isUI, Translator.GetString("GuessPunchingBag")); BlockGuess.Add(pc.PlayerId); PunchingBagMax[target.PlayerId]++; SendRPC(target.PlayerId); CheckWin(); return true; } private void CheckWin() { byte playerId = base._Player.PlayerId; if (PunchingBagMax[playerId] >= PunchingBagKillMax.GetInt() && !CustomWinnerHolder.CheckForConvertedWinner(playerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.PunchingBag); CustomWinnerHolder.WinnerIds.Add(playerId); } } public override bool GuessCheck(bool isUI, PlayerControl pc, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessPunchingBagBlocked")); return true; } } internal class Pursuer : RoleBase { private const int Id = 13400; private static OptionItem PursuerSkillCooldown; private static OptionItem PursuerSkillLimitTimes; private readonly HashSet notActiveList = new HashSet(); private readonly HashSet clientList = new HashSet(); public static bool HasEnabled => CustomRoles.Pursuer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(13400, TabGroup.NeutralRoles, CustomRoles.Pursuer); PursuerSkillCooldown = FloatOptionItem.Create(13410, "PursuerSkillCooldown", new FloatValueRule(2.5f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pursuer]).SetValueFormat(OptionFormat.Seconds); PursuerSkillLimitTimes = IntegerOptionItem.Create(13411, "PursuerSkillLimitTimes", new IntegerValueRule(1, 20, 1), 2, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pursuer]).SetValueFormat(OptionFormat.Times); } public override void Init() { notActiveList.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = PursuerSkillLimitTimes.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl pc) { return CanUseKillButton(pc.PlayerId); } public bool CanUseKillButton(byte playerId) { if (!Main.PlayerStates[playerId].IsDead) { return base.AbilityLimit >= 1f; } return false; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CanUseKillButton(playerId) ? Utils.GetRoleColor(CustomRoles.Pursuer) : Color.gray), $"({base.AbilityLimit})"); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CanUseKillButton(id) ? PursuerSkillCooldown.GetFloat() : 300f); } public bool IsClient(byte playerId) { return clientList.Contains(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: true); } public bool CanBeClient(PlayerControl pc) { if ((Object)(object)pc != (Object)null && pc.IsAlive() && !GameStates.IsMeeting) { return !IsClient(pc.PlayerId); } return false; } public bool CanSeel(byte playerId) { return base.AbilityLimit > 0f; } public override bool OnCheckMurderAsKiller(PlayerControl pc, PlayerControl target) { if ((Object)(object)pc == (Object)null || (Object)(object)target == (Object)null || !pc.Is(CustomRoles.Pursuer)) { return true; } if (target.Is(CustomRoles.Pestilence) || target.Is(CustomRoles.SerialKiller)) { return false; } if (!CanBeClient(target) || !CanSeel(pc.PlayerId)) { return false; } base.AbilityLimit--; SendSkillRPC(); if (target.Is(CustomRoles.KillingMachine)) { Logger.Info("target is Killing Machine, ability used count reduced, but target will not die", "Purser", escapeCRLF: true, 67, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pursuer.cs"); return false; } clientList.Add(target.PlayerId); if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(pc); } notActiveList.Add(pc.PlayerId); pc.SetKillCooldown(); pc.RPCPlayCustomSound("Bet"); Utils.NotifyRoles(pc); Logger.Info("Counterfeiters " + pc.GetRealName() + " sell counterfeits to " + target.GetRealName(), "Pursuer", escapeCRLF: true, 82, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pursuer.cs"); return false; } public override bool CheckMurderOnOthersTarget(PlayerControl pc, PlayerControl _) { if (!IsClient(pc.PlayerId) || notActiveList.Contains(pc.PlayerId)) { return false; } byte b = byte.MaxValue; foreach (byte client in clientList) { if (client == pc.PlayerId) { b = client; } } if (b == byte.MaxValue) { return false; } PlayerControl playerById = Utils.GetPlayerById(b); if ((Object)(object)playerById == (Object)null) { return false; } pc.SetDeathReason(PlayerState.DeathReason.Misfire); pc.RpcMurderPlayer(pc); pc.SetRealKiller(playerById); Logger.Info($"赝品商 {pc.GetRealName()} 的客户 {pc.GetRealName()} 因使用赝品走火自杀", "Pursuer", escapeCRLF: true, 103, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Pursuer.cs"); return true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("PursuerButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Pursuer"); } } internal class Pyromaniac : RoleBase { private const int Id = 17800; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem DouseCooldown; private static OptionItem BurnCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static readonly HashSet DousedList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17800, TabGroup.NeutralRoles, CustomRoles.Pyromaniac); KillCooldown = FloatOptionItem.Create(17810, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pyromaniac]).SetValueFormat(OptionFormat.Seconds); DouseCooldown = FloatOptionItem.Create(17811, "PyroDouseCooldown", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pyromaniac]).SetValueFormat(OptionFormat.Seconds); BurnCooldown = FloatOptionItem.Create(17812, "PyroBurnCooldown", new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pyromaniac]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17813, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pyromaniac]); HasImpostorVision = BooleanOptionItem.Create(17814, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pyromaniac]); } public override void Init() { playerIdList.Clear(); DousedList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); Utils.GetPlayerById(playerId).AddDoubleTrigger(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!seer.Is(CustomRoles.Pyromaniac) || !DousedList.Contains(target.PlayerId)) { return string.Empty; } return "#BA4A00"; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null) { return true; } if ((Object)(object)target == (Object)null) { return true; } if (DousedList.Contains(target.PlayerId)) { new LateTask(delegate { killer.SetKillCooldown(BurnCooldown.GetFloat()); }, 0.1f, "Pyromaniac Set Kill Cooldown"); return true; } return killer.CheckDoubleTrigger(target, delegate { DousedList.Add(target.PlayerId); killer.SetKillCooldown(DouseCooldown.GetFloat()); Utils.NotifyRoles(killer, target); }); } } internal class Quizmaster : RoleBase { private const int Id = 27000; private static OptionItem QuestionDifficulty; public static OptionItem CanKillAfterMarkOpt; private static OptionItem CanVentAfterMark; private static OptionItem NumOfKillAfterMark; private static OptionItem CanGiveQuestionsAboutPastGames; private static QuizQuestionBase Question = new SetAnswersQuestion { Stage = 0, Answer = "Select Me", PossibleAnswers = { "Select me", "Die", "Die", "Die" }, Question = "This question is to prevent crashes answer the letter with the answer \"Select me\"", HasAnswersTranslation = false, HasQuestionTranslation = false }; private static QuizQuestionBase previousQuestion = new SetAnswersQuestion { Stage = 0, Answer = "Select Me", PossibleAnswers = { "Select me", "Die", "Die", "Die" }, Question = "This question is to prevent crashes answer the letter with the answer \"Select me\"", HasAnswersTranslation = false, HasQuestionTranslation = false }; private static PlayerControl Player; public static Sabotages lastSabotage = Sabotages.None; public static Sabotages firstSabotageOfRound = Sabotages.None; private static bool allowedKilling = false; private static bool AlreadyMarked = false; private static byte MarkedPlayer = byte.MaxValue; public static string lastExiledColor = "None"; public static string lastReportedColor = "None"; public static string thisReportedColor = "None"; public static string lastButtonPressedColor = "None"; public static string thisButtonPressedColor = "None"; public static int meetingNum = 0; public static int diedThisRound = 0; public static int buttonMeeting = 0; public static bool CanKillAfterMark = false; public static bool HasEnabled => CustomRoles.Quizmaster.HasEnabled(); public override bool IsExperimental => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType { get { if (!CanKillsAfterMark()) { return Custom_RoleType.NeutralChaos; } return Custom_RoleType.NeutralKilling; } } public override void SetupCustomOption() { TabGroup tab = TabGroup.NeutralRoles; Options.SetupSingleRoleOptions(27000, tab, CustomRoles.Quizmaster); QuestionDifficulty = IntegerOptionItem.Create(27010, "QuizmasterSettings.QuestionDifficulty", new IntegerValueRule(1, 4, 1), 1, tab, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Quizmaster]); CanVentAfterMark = BooleanOptionItem.Create(27011, "QuizmasterSettings.CanVentAfterMark", defaultValue: true, tab, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Quizmaster]); CanKillAfterMarkOpt = BooleanOptionItem.Create(27012, "QuizmasterSettings.CanKillAfterMark", defaultValue: false, tab, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Quizmaster]); NumOfKillAfterMark = IntegerOptionItem.Create(27013, "QuizmasterSettings.NumOfKillAfterMark", new IntegerValueRule(1, 15, 1), 1, tab, isSingleValue: false).SetValueFormat(OptionFormat.Players).SetParent(CanKillAfterMarkOpt); CanGiveQuestionsAboutPastGames = BooleanOptionItem.Create(27014, "QuizmasterSettings.CanGiveQuestionsAboutPastGames", defaultValue: false, tab, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Quizmaster]); } public override void Init() { Player = null; firstSabotageOfRound = Sabotages.None; allowedKilling = false; AlreadyMarked = false; MarkedPlayer = byte.MaxValue; if (!CanGiveQuestionsAboutPastGames.GetBool()) { lastExiledColor = "None"; lastReportedColor = "None"; lastButtonPressedColor = "None"; lastSabotage = Sabotages.None; } thisReportedColor = "None"; thisButtonPressedColor = "None"; diedThisRound = 0; meetingNum = 0; buttonMeeting = 0; CanKillAfterMark = CanKillAfterMarkOpt.GetBool(); } public override void Add(byte playerId) { Player = base._Player; MarkedPlayer = byte.MaxValue; CustomRoleManager.CheckDeadBodyOthers.Add(OnPlayerDead); } public void SendRPC(byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte b = reader.ReadByte(); if (b != byte.MaxValue) { AlreadyMarked = true; MarkedPlayer = b; allowedKilling = CanKillAfterMark; } else { MarkedPlayer = b; } } public static bool CanKillsAfterMark() { return CanKillAfterMark; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = 15f; } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { if ((Object)(object)pc == (Object)null || !pc.IsAlive()) { return false; } bool result = false; if (CanVentAfterMark.GetBool() && MarkedPlayer != byte.MaxValue) { result = true; } return result; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!killer.RpcCheckAndMurder(target, check: true)) { return false; } if (!AlreadyMarked) { AlreadyMarked = true; MarkedPlayer = target.PlayerId; SendRPC(target.PlayerId); Utils.NotifyRoles(killer, target); allowedKilling = CanKillAfterMark; killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.MarkDirtySettings(); killer.RPCPlayCustomSound("Clothe"); return false; } if (allowedKilling) { return AlreadyMarked; } return false; } private static QuizQuestionBase GetRandomQuestion(List qt) { List list = qt.Where((QuizQuestionBase a) => a.Stage <= QuestionDifficulty.GetInt()).ToList(); IRandom instance = IRandom.Instance; QuizQuestionBase quizQuestionBase = list[instance.Next(0, list.Count)]; if (quizQuestionBase == previousQuestion) { quizQuestionBase = list[instance.Next(0, list.Count)]; } if (quizQuestionBase == null) { quizQuestionBase = new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }; } previousQuestion = quizQuestionBase; quizQuestionBase.FixUnsetAnswers(); return quizQuestionBase; } private static CustomRoles GetRandomRole(List roles, bool AllowAddons) { IRandom instance = IRandom.Instance; CustomRoles customRoles = roles[instance.Next(0, roles.Count)]; if (customRoles.IsAdditionRole() && !AllowAddons) { for (int i = 0; i < -1; i++) { if (!customRoles.IsAdditionRole()) { break; } if (AllowAddons) { break; } customRoles = roles[instance.Next(0, roles.Count)]; } } return customRoles; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (!((Object)(object)reporter == (Object)null)) { if ((Object)(object)target == (Object)null) { buttonMeeting++; lastButtonPressedColor = thisButtonPressedColor; thisButtonPressedColor = reporter.Data.GetPlayerColorString((PlayerOutfitType)0); } else { lastReportedColor = thisReportedColor; thisReportedColor = target.GetPlayerColorString((PlayerOutfitType)0); } meetingNum++; DoQuestion(); } } private void DoQuestion() { //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) Player = base._Player; if (MarkedPlayer != byte.MaxValue) { CustomRoles[] allRoles = CustomRolesHelper.AllRoles; List list = new List(allRoles.Length); CustomRoles[] array = allRoles; foreach (CustomRoles item in array) { list.Add(item); } CustomRoles randomRole = GetRandomRole(list, AllowAddons: false); CustomRoles[] allRoles2 = CustomRolesHelper.AllRoles; list = new List(allRoles2.Length); array = allRoles2; foreach (CustomRoles item in array) { list.Add(item); } CustomRoles randomRole2 = GetRandomRole(list, AllowAddons: false); List obj = new List(17) { new SabotageQuestion { Stage = 1, Question = "LastSabotage", QuizmasterQuestionType = QuizmasterQuestionType.LatestSabotageQuestion }, new SabotageQuestion { Stage = 1, Question = "FirstRoundSabotage", QuizmasterQuestionType = QuizmasterQuestionType.FirstRoundSabotageQuestion }, new PlrColorQuestion { Stage = 1, Question = "LastEjectedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.EjectionColorQuestion }, new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }, new PlrColorQuestion { Stage = 1, Question = "LastButtonPressedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.LastMeetingColorQuestion }, new CountQuestion { Stage = 2, Question = "MeetingPassed", QuizmasterQuestionType = QuizmasterQuestionType.MeetingCountQuestion }, new SetAnswersQuestion { Stage = 2, Question = "HowManyFactions", Answer = "Three", PossibleAnswers = { "One", "Two", "Three", "Four", "Five" }, QuizmasterQuestionType = QuizmasterQuestionType.FactionQuestion }, new SetAnswersQuestion { Stage = 2, Question = Translator.GetString("QuizmasterQuestions.BasisOfRole").Replace("{QMROLE}", randomRole2.ToString()), HasQuestionTranslation = false, Answer = randomRole2.GetCustomRoleTeam().ToString(), PossibleAnswers = { "Crewmate", "Impostor", "Neutral", "Addon" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleBasisQuestion } }; SetAnswersQuestion obj2 = new SetAnswersQuestion { Stage = 2, Question = Translator.GetString("QuizmasterQuestions.FactionOfRole").Replace("{QMROLE}", randomRole.ToString()), HasQuestionTranslation = false }; RoleTypes roleTypes = randomRole.GetRoleTypes(); obj2.Answer = ((object)(RoleTypes)(ref roleTypes)).ToString(); obj2.PossibleAnswers.Add("Crewmate"); obj2.PossibleAnswers.Add("Impostor"); obj2.PossibleAnswers.Add("Neutral"); obj2.QuizmasterQuestionType = QuizmasterQuestionType.RoleFactionQuestion; obj.Add(obj2); obj.Add(new SetAnswersQuestion { Stage = 3, Question = "FactionRemovedName", Answer = "Coven", PossibleAnswers = { "Sabotuer", "Sorcerers", "Coven", "Killer" }, QuizmasterQuestionType = QuizmasterQuestionType.RemovedFactionQuestion }); obj.Add(new SetAnswersQuestion { Stage = 3, Question = "WhatDoesEOgMeansInName", Answer = "Edited", PossibleAnswers = { "Edition", "Experimental", "Enhanced", "Edited" }, QuizmasterQuestionType = QuizmasterQuestionType.NameOriginQuestion }); obj.Add(new CountQuestion { Stage = 3, Question = "HowManyDiedFirstRound", QuizmasterQuestionType = QuizmasterQuestionType.DiedFirstRoundCountQuestion }); obj.Add(new CountQuestion { Stage = 3, Question = "ButtonPressedBefore", QuizmasterQuestionType = QuizmasterQuestionType.ButtonPressedBeforeThisQuestion }); obj.Add(new DeathReasonQuestion { Stage = 4, Question = "PlrDieReason", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathReasonQuestion }); obj.Add(new DeathReasonQuestion { Stage = 4, Question = "PlrDieMethod", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathMethodQuestion }); obj.Add(new SetAnswersQuestion { Stage = 4, Question = "LastAddedRoleForKarped", Answer = "Pacifist", PossibleAnswers = { "Pacifist", "Vampire", "Snitch", "Vigilante", "Jackal", "Mole", "Sniper" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleAddedQuestion }); obj.Add(new DeathReasonQuestion { Stage = 4, Question = "PlrDieFaction", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathKillerFactionQuestion }); Question = GetRandomQuestion(obj); } } public override void OnMeetingHudStart(PlayerControl pc) { if (pc.PlayerId == Player.PlayerId && MarkedPlayer != byte.MaxValue) { MeetingHudStartPatch.AddMsg(Translator.GetString("QuizmasterChat.Marked").Replace("{QMTARGET}", Utils.GetPlayerById(MarkedPlayer)?.GetRealName(isMeeting: true)).Replace("{QMQUESTION}", Question.HasQuestionTranslation ? Translator.GetString("QuizmasterQuestions." + Question.Question) : Question.Question), pc.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } public override void OnOthersMeetingHudStart(PlayerControl pc) { if (Utils.GetPlayerById(MarkedPlayer).IsAlive()) { if (pc.PlayerId == MarkedPlayer) { ShowQuestion(pc); } else if (pc.PlayerId != Player.PlayerId && pc.PlayerId != MarkedPlayer) { MeetingHudStartPatch.AddMsg(Translator.GetString("QuizmasterChat.MarkedPublic").Replace("{QMCOLOR}", Utils.GetRoleColorCode(CustomRoles.Quizmaster)).Replace("{QMTARGET}", Utils.GetPlayerById(MarkedPlayer)?.GetRealName(isMeeting: true)), pc.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { if (!((Object)(object)exiled == (Object)null)) { if (exiled.Object.Is(CustomRoles.Quizmaster)) { ResetMarkedPlayer(canMarkAgain: false); } lastExiledColor = exiled.GetPlayerColorString((PlayerOutfitType)0); } } public override void AfterMeetingTasks() { firstSabotageOfRound = Sabotages.None; allowedKilling = false; diedThisRound = 0; if (MarkedPlayer != byte.MaxValue) { KillPlayer(Utils.GetPlayerById(MarkedPlayer)); } ResetMarkedPlayer(); } public static void ResetMarkedPlayer(bool canMarkAgain = true) { if (canMarkAgain) { AlreadyMarked = false; } MarkedPlayer = byte.MaxValue; if (Player?.GetRoleClass() is Quizmaster quizmaster) { quizmaster.SendRPC(byte.MaxValue); } } private void OnPlayerDead(PlayerControl killer, PlayerControl target, bool inMeeting) { diedThisRound++; if (target.PlayerId == MarkedPlayer) { ResetMarkedPlayer(canMarkAgain: false); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString(allowedKilling ? "KillButtonText" : "QuizmasterKillButtonText")); } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || seer.PlayerId == target.PlayerId || MarkedPlayer != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Quizmaster)), " ?!"); } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!isForMeeting || MarkedPlayer != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Quizmaster)), " ?!"); } public static void OnSabotageCall(SystemTypes systemType) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Invalid comparison between Unknown and I4 bool flag = !Main.MeetingIsStarted; bool flag2; if (flag) { if ((int)systemType <= 8) { if ((int)systemType == 3 || systemType - 7 <= 1) { goto IL_002d; } } else if ((int)systemType == 14 || (int)systemType == 21 || systemType - 57 <= 1) { goto IL_002d; } flag2 = false; goto IL_0033; } goto IL_0035; IL_008b: if (firstSabotageOfRound == Sabotages.None) { firstSabotageOfRound = lastSabotage; } return; IL_002d: flag2 = true; goto IL_0033; IL_0035: if (!flag) { return; } if ((int)systemType <= 8) { if ((int)systemType == 3) { goto IL_0065; } if ((int)systemType != 7) { if ((int)systemType == 8) { lastSabotage = Sabotages.O2; } } else { lastSabotage = Sabotages.Lights; } } else if ((int)systemType <= 21) { if ((int)systemType != 14) { if ((int)systemType == 21) { goto IL_0065; } } else { lastSabotage = Sabotages.Communications; } } else if ((int)systemType != 57) { if ((int)systemType == 58) { goto IL_0065; } } else { lastSabotage = Sabotages.MushroomMixup; } goto IL_008b; IL_0033: flag = flag2; goto IL_0035; IL_0065: lastSabotage = Sabotages.Reactor; goto IL_008b; } private static void KillPlayer(PlayerControl plrToKill) { plrToKill.SetDeathReason(PlayerState.DeathReason.WrongAnswer); Main.PlayerStates[plrToKill.PlayerId].SetDead(); plrToKill.Data.IsDead = true; plrToKill.RpcExileV2(); plrToKill.SetRealKiller(Player); ResetMarkedPlayer(); } private static void RightAnswer(PlayerControl target) { lastReportedColor = thisReportedColor; PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (val.PlayerId != Player.PlayerId && target.PlayerId != val.PlayerId) { Utils.SendMessage(Translator.GetString("QuizmasterChat.CorrectPublic").Replace("{QMCOLOR}", Utils.GetRoleColorCode(CustomRoles.Quizmaster)).Replace("{QMTARGET}", target.GetRealName()), val.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } Utils.SendMessage(Translator.GetString("QuizmasterChat.CorrectTarget"), target.PlayerId, Translator.GetString("QuizmasterChat.Title")); Utils.SendMessage(Translator.GetString("QuizmasterChat.Correct").Replace("{QMTARGET}", target.GetRealName()), Player.PlayerId, Translator.GetString("QuizmasterChat.Title")); ResetMarkedPlayer(); } private static void WrongAnswer(PlayerControl target, string wrongAnswer, string rightAnswer) { lastReportedColor = thisReportedColor; KillPlayer(target); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (val.PlayerId != Player.PlayerId && target.PlayerId != val.PlayerId) { Utils.SendMessage(Translator.GetString("QuizmasterChat.WrongPublic").Replace("{QMCOLOR}", Utils.GetRoleColorCode(CustomRoles.Quizmaster)).Replace("{QMTARGET}", target.GetRealName()), val.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } Utils.SendMessage(Translator.GetString("QuizmasterChat.Wrong").Replace("{QMTARGET}", target.GetRealName()), Player.PlayerId, Translator.GetString("QuizmasterChat.Title")); Utils.SendMessage(Translator.GetString("QuizmasterChat.WrongTarget").Replace("{QMWRONG}", wrongAnswer).Replace("{QMRIGHT}", rightAnswer) .Replace("{QM}", Player.GetRealName()), target.PlayerId, Translator.GetString("QuizmasterChat.Title")); } public static void AnswerByChat(PlayerControl plr, string[] args) { if (MarkedPlayer == plr.PlayerId) { if (args.Length == 2) { string text = args[1].ToUpper(); bool num = text == "A" || text == "B" || text == "C"; string text2 = Question.AnswerLetter.Trim().ToUpper(); if (num) { if (text2 == text) { RightAnswer(plr); } else { WrongAnswer(plr, text, text2); } } else { Utils.SendMessage(Translator.GetString("QuizmasterAnswerNotValid"), plr.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } else { Utils.SendMessage(Translator.GetString("QuizmasterSyntaxNotValid"), plr.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } else if (plr.GetCustomRole() == CustomRoles.Quizmaster) { Utils.SendMessage(Translator.GetString("QuizmasterCantAnswer"), plr.PlayerId, Translator.GetString("QuizmasterChat.Title")); } } public static void ShowQuestion(PlayerControl plr) { if (plr.PlayerId == MarkedPlayer) { Utils.SendMessage(Translator.GetString("QuizmasterChat.MarkedBy").Replace("{QMCOLOR}", Utils.GetRoleColorCode(CustomRoles.Quizmaster)).Replace("{QMQUESTION}", Question.HasQuestionTranslation ? Translator.GetString("QuizmasterQuestions." + Question.Question) : Question.Question), MarkedPlayer, Translator.GetString("QuizmasterChat.Title")); Utils.SendMessage(Translator.GetString("QuizmasterChat.Answers").Replace("{QMA}", Question.HasAnswersTranslation ? Translator.GetString(Question.Answers[0], null, console: false, Question.ShowInvalid) : Question.Answers[0]).Replace("{QMB}", Question.HasAnswersTranslation ? Translator.GetString(Question.Answers[1], null, console: false, Question.ShowInvalid) : Question.Answers[1]) .Replace("{QMC}", Question.HasAnswersTranslation ? Translator.GetString(Question.Answers[2], null, console: false, Question.ShowInvalid) : Question.Answers[2]), MarkedPlayer, Translator.GetString("QuizmasterChat.Title")); } } } public abstract class QuizQuestionBase { public int Stage { get; set; } public QuizmasterQuestionType QuizmasterQuestionType { get; set; } public string Question { get; set; } public string Answer { get; set; } public string AnswerLetter { get; set; } public List Answers { get; set; } public List PossibleAnswers { get; set; } = new List(); public bool HasAnswersTranslation { get; set; } = true; public bool HasQuestionTranslation { get; set; } = true; public bool ShowInvalid { get; set; } = true; public abstract void FixUnsetAnswers(); } internal class PlrColorQuestion : QuizQuestionBase { public override void FixUnsetAnswers() { base.Answers = new List(); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!base.PossibleAnswers.Contains(val.Data.GetPlayerColorString((PlayerOutfitType)0))) { base.PossibleAnswers.Add(val.Data.GetPlayerColorString((PlayerOutfitType)0)); } } IRandom instance = IRandom.Instance; int num = instance.Next(3); base.Answer = base.QuizmasterQuestionType switch { QuizmasterQuestionType.EjectionColorQuestion => Quizmaster.lastExiledColor, QuizmasterQuestionType.ReportColorQuestion => Quizmaster.lastReportedColor, QuizmasterQuestionType.LastMeetingColorQuestion => Quizmaster.lastButtonPressedColor, _ => "None", }; base.HasQuestionTranslation = false; base.HasAnswersTranslation = false; base.ShowInvalid = false; if (base.PossibleAnswers.Contains(base.Answer)) { base.PossibleAnswers.Remove(base.Answer); } for (int j = 0; j < 3; j++) { string text = ""; if (j == num) { base.AnswerLetter = new List { "A", "B", "C" }[num]; base.Answer = Translator.GetString(text + base.Answer); base.Answers.Add(text + base.Answer); } else { string text2 = base.PossibleAnswers[instance.Next(base.PossibleAnswers.Count)]; text2 = Translator.GetString(text + text2); base.Answers.Add(text + text2); base.PossibleAnswers.Remove(text2); } } } } internal class DeathReasonQuestion : QuizQuestionBase { public override void FixUnsetAnswers() { //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) base.Answers = new List(); IRandom instance = IRandom.Instance; PlayerControl val = null; if (base.QuizmasterQuestionType == QuizmasterQuestionType.PlrDeathReasonQuestion) { base.PossibleAnswers.Add("None"); base.PossibleAnswers.Add(PlayerState.DeathReason.etc.ToString()); base.PossibleAnswers.Add(Translator.GetString("DeathReason.Vote")); } else if (base.QuizmasterQuestionType == QuizmasterQuestionType.PlrDeathMethodQuestion) { base.PossibleAnswers.Add(Translator.GetString("Disconnected")); base.PossibleAnswers.Add(Translator.GetString("DeathReason.Vote")); base.PossibleAnswers.Add(Translator.GetString("DeathReason.Kill")); } else if (base.QuizmasterQuestionType == QuizmasterQuestionType.PlrDeathKillerFactionQuestion) { base.PossibleAnswers.Add(""); base.PossibleAnswers.Add(Translator.GetString("DeathReason.Vote")); base.PossibleAnswers.Add(Translator.GetString("DeathReason.Kill")); } val = Main.AllPlayerControls[instance.Next(Main.AllPlayerControls.Length)]; PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls) { if (base.QuizmasterQuestionType == QuizmasterQuestionType.PlrDeathReasonQuestion && val2.Data.IsDead && !base.PossibleAnswers.Contains(Main.PlayerStates[val.PlayerId].deathReason.ToString())) { base.PossibleAnswers.Add(Main.PlayerStates[val.PlayerId].deathReason.ToString()); } } int num = instance.Next(0, 3); base.HasQuestionTranslation = false; base.Question = Translator.GetString("QuizmasterQuestions." + base.Question).Replace("{PLR}", val.GetRealName()); base.ShowInvalid = false; string answer; switch (base.QuizmasterQuestionType) { case QuizmasterQuestionType.PlrDeathReasonQuestion: answer = (val.Data.IsDead ? Main.PlayerStates[val.PlayerId].deathReason.ToString() : "None"); break; case QuizmasterQuestionType.PlrDeathMethodQuestion: answer = (val.Data.Disconnected ? Translator.GetString("Disconnected") : ((Main.PlayerStates[val.PlayerId].deathReason == PlayerState.DeathReason.Vote) ? Translator.GetString("DeathReason.Vote") : Translator.GetString("DeathReason.Kill"))); break; case QuizmasterQuestionType.PlrDeathKillerFactionQuestion: { RoleTypes roleTypes = val.GetRealKiller().GetCustomRole().GetRoleTypes(); answer = ((object)(RoleTypes)(ref roleTypes)).ToString(); break; } default: answer = "None"; break; } base.Answer = answer; base.PossibleAnswers.Remove(base.Answer); for (int j = 0; j < 3; j++) { string text = ""; if (base.QuizmasterQuestionType == QuizmasterQuestionType.PlrDeathKillerFactionQuestion) { text = "Type."; } if (j == num) { base.AnswerLetter = new List { "A", "B", "C" }[num]; if (base.Answer == "None") { text = "Quizmaster."; } if (text != "") { base.Answer = Translator.GetString(text + base.Answer); } base.Answers.Add(text + base.Answer); } else { string text2 = base.PossibleAnswers[instance.Next(0, base.PossibleAnswers.Count)]; if (text2 == "None") { text = "Quizmaster."; } if (text != "") { text2 = Translator.GetString(text + text2); } base.Answers.Add(text + text2); base.PossibleAnswers.Remove(text2); } } } } internal class CountQuestion : QuizQuestionBase { public override void FixUnsetAnswers() { IRandom instance = IRandom.Instance; base.Answer = base.QuizmasterQuestionType switch { QuizmasterQuestionType.MeetingCountQuestion => Quizmaster.meetingNum.ToString(), QuizmasterQuestionType.ButtonPressedBeforeThisQuestion => (Quizmaster.buttonMeeting - 1).ToString(), QuizmasterQuestionType.DiedFirstRoundCountQuestion => Quizmaster.diedThisRound.ToString(), _ => "None", }; base.Answers = new List(); int num = int.Parse(base.Answer); if (num < 1) { base.PossibleAnswers.Add((num + instance.Next(1, 3)).ToString()); base.PossibleAnswers.Add((num + instance.Next(3, 5)).ToString()); } else { base.PossibleAnswers.Add((num + instance.Next(1, 3)).ToString()); base.PossibleAnswers.Add((num - 1).ToString()); } base.HasAnswersTranslation = false; int num2 = instance.Next(0, 3); base.PossibleAnswers.Remove(base.Answer); for (int i = 0; i < 3; i++) { if (i == num2) { base.AnswerLetter = new List { "A", "B", "C" }[num2]; base.Answers.Add(base.Answer); } else { string item = base.PossibleAnswers[instance.Next(0, base.PossibleAnswers.Count)]; base.Answers.Add(item); base.PossibleAnswers.Remove(item); } } } } internal class SetAnswersQuestion : QuizQuestionBase { public override void FixUnsetAnswers() { base.Answers = new List(); IRandom instance = IRandom.Instance; int num = instance.Next(0, 3); base.PossibleAnswers.Remove(base.Answer); for (int i = 0; i < 3; i++) { string text; switch (base.QuizmasterQuestionType) { case QuizmasterQuestionType.RoleBasisQuestion: case QuizmasterQuestionType.RoleFactionQuestion: case QuizmasterQuestionType.FactionQuestion: case QuizmasterQuestionType.RemovedFactionQuestion: case QuizmasterQuestionType.NameOriginQuestion: case QuizmasterQuestionType.RoleAddedQuestion: text = "QuizmasterAnswers."; break; default: text = ""; break; } string text2 = text; if (i == num) { base.AnswerLetter = new List { "A", "B", "C" }[num]; if (base.Answer == "None") { text2 = "Quizmaster."; } base.Answers.Add(text2 + base.Answer); base.ShowInvalid = false; } else { string text3 = base.PossibleAnswers[instance.Next(0, base.PossibleAnswers.Count)]; if (text3 == "None") { text2 = "Quizmaster."; } base.Answers.Add(text2 + text3); base.PossibleAnswers.Remove(text3); } } } } internal class SabotageQuestion : QuizQuestionBase { private static readonly List SkeldSabotages = new List(4) { Sabotages.None, Sabotages.Lights, Sabotages.Reactor, Sabotages.O2 }; private static readonly List MiraSabotages = new List(5) { Sabotages.None, Sabotages.Lights, Sabotages.Reactor, Sabotages.O2, Sabotages.Communications }; private static readonly List PolusSabotages = new List(4) { Sabotages.None, Sabotages.Lights, Sabotages.Reactor, Sabotages.Communications }; private static readonly List AirshitSabotages = new List(4) { Sabotages.None, Sabotages.Lights, Sabotages.Reactor, Sabotages.Communications }; private static readonly List FungleSabotages = new List(4) { Sabotages.None, Sabotages.Communications, Sabotages.Reactor, Sabotages.MushroomMixup }; public override void FixUnsetAnswers() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown base.Answers = new List(); MapNames activeMapName = Utils.GetActiveMapName(); base.PossibleAnswers = (int)activeMapName switch { 0 => SkeldSabotages.ConvertAll((Sabotages f) => f.ToString()), 3 => SkeldSabotages.ConvertAll((Sabotages f) => f.ToString()), 1 => MiraSabotages.ConvertAll((Sabotages f) => f.ToString()), 2 => PolusSabotages.ConvertAll((Sabotages f) => f.ToString()), 4 => AirshitSabotages.ConvertAll((Sabotages f) => f.ToString()), 5 => FungleSabotages.ConvertAll((Sabotages f) => f.ToString()), _ => throw new NotImplementedException(), }; IRandom instance = IRandom.Instance; int num = instance.Next(0, 3); base.Answer = base.QuizmasterQuestionType switch { QuizmasterQuestionType.LatestSabotageQuestion => Quizmaster.lastSabotage.ToString(), QuizmasterQuestionType.FirstRoundSabotageQuestion => Quizmaster.firstSabotageOfRound.ToString(), _ => Sabotages.None.ToString(), }; base.PossibleAnswers.Remove(base.Answer); for (int i = 0; i < 3; i++) { string text = "QuizmasterSabotages."; if (i == num) { base.AnswerLetter = new List { "A", "B", "C" }[num]; if (base.Answer == "None") { text = "Quizmaster."; } base.Answers.Add(text + base.Answer); } else { string text2 = base.PossibleAnswers[instance.Next(0, base.PossibleAnswers.Count)]; if (text2 == "None") { text = "Quizmaster."; } base.Answers.Add(text + text2); base.PossibleAnswers.Remove(text2); } } } } public enum QuizmasterQuestionType { FirstRoundSabotageQuestion, LatestSabotageQuestion, EjectionColorQuestion, ReportColorQuestion, LastMeetingColorQuestion, RoleBasisQuestion, RoleFactionQuestion, MeetingCountQuestion, FactionQuestion, RemovedFactionQuestion, ButtonPressedBeforeThisQuestion, DiedFirstRoundCountQuestion, NameOriginQuestion, PlrDeathReasonQuestion, PlrDeathMethodQuestion, RoleAddedQuestion, PlrDeathKillerFactionQuestion } public enum Sabotages { None = -1, Lights, Reactor, O2, Communications, MushroomMixup } internal class Revolutionist : RoleBase { private const int Id = 15200; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem RevolutionistDrawTime; private static OptionItem RevolutionistCooldown; private static OptionItem RevolutionistDrawCount; private static OptionItem RevolutionistKillProbability; private static OptionItem RevolutionistVentCountDown; public static readonly Dictionary<(byte, byte), bool> IsDraw = new Dictionary<(byte, byte), bool>(); private static readonly Dictionary RevolutionistTimer = new Dictionary(); private static readonly Dictionary RevolutionistStart = new Dictionary(); private static readonly Dictionary RevolutionistLastTime = new Dictionary(); private static readonly Dictionary RevolutionistCountdown = new Dictionary(); private static byte CurrentDrawTarget = byte.MaxValue; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(15200, TabGroup.NeutralRoles, CustomRoles.Revolutionist); RevolutionistDrawTime = FloatOptionItem.Create(15202, "RevolutionistDrawTime", new FloatValueRule(0f, 10f, 1f), 3f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Revolutionist]).SetValueFormat(OptionFormat.Seconds); RevolutionistCooldown = FloatOptionItem.Create(15203, "RevolutionistCooldown", new FloatValueRule(5f, 100f, 1f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Revolutionist]).SetValueFormat(OptionFormat.Seconds); RevolutionistDrawCount = IntegerOptionItem.Create(15204, "RevolutionistDrawCount", new IntegerValueRule(1, 14, 1), 6, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Revolutionist]).SetValueFormat(OptionFormat.Players); RevolutionistKillProbability = IntegerOptionItem.Create(15205, "RevolutionistKillProbability", new IntegerValueRule(0, 100, 5), 15, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Revolutionist]).SetValueFormat(OptionFormat.Percent); RevolutionistVentCountDown = FloatOptionItem.Create(15206, "RevolutionistVentCountDown", new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Revolutionist]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { IsDraw.Clear(); RevolutionistTimer.Clear(); RevolutionistStart.Clear(); RevolutionistLastTime.Clear(); RevolutionistCountdown.Clear(); CurrentDrawTarget = byte.MaxValue; PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); CustomRoleManager.OnFixedUpdateOthers.Add(OnFixUpdateOthers); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { IsDraw.Add((playerId, val.PlayerId), value: false); } if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = RevolutionistCooldown.GetFloat(); } public override string GetProgressText(byte playerId, bool comms) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) List winnerList; (int, int) drawPlayerCount = GetDrawPlayerCount(playerId, out winnerList); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Revolutionist).ShadeColor(0.25f)), $"({drawPlayerCount.Item1}/{drawPlayerCount.Item2})"); } public override bool CanUseKillButton(PlayerControl pc) { return !IsDrawDone(pc); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return IsDrawDone(pc); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { byte[] array = RevolutionistStart.Keys.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!((Object)(object)playerById == (Object)null)) { playerById.Data.IsDead = true; playerById.SetDeathReason(PlayerState.DeathReason.Sacrifice); playerById.RpcExileV2(); Main.PlayerStates[playerById.PlayerId].SetDead(); Logger.Info(playerById.GetRealName() + " 因会议革命失败", "Revolutionist", escapeCRLF: true, 99, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Revolutionist.cs"); } } RevolutionistTimer.Clear(); RevolutionistStart.Clear(); RevolutionistLastTime.Clear(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("RevolutionistDrawButtonText")); ((TMP_Text)((ActionButton)hud.ImpostorVentButton).buttonLabelText).text = Translator.GetString("RevolutionistVentButtonText"); } private static void SetDrawPlayerRPC(PlayerControl player, PlayerControl target, bool isDrawed) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)149, (SendOption)1, -1); val.Write(player.PlayerId); val.Write(target.PlayerId); val.Write(isDrawed); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveDrawPlayerRPC(MessageReader reader) { byte item = reader.ReadByte(); byte item2 = reader.ReadByte(); bool value = reader.ReadBoolean(); IsDraw[(item, item2)] = value; } private static void SetCurrentDrawTargetRPC(byte arsonistId, byte targetId) { if (PlayerControl.LocalPlayer.PlayerId == arsonistId) { CurrentDrawTarget = targetId; return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)151, (SendOption)1, -1); val.Write(arsonistId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveSetCurrentDrawTarget(MessageReader reader) { byte b = reader.ReadByte(); byte currentDrawTarget = reader.ReadByte(); if (PlayerControl.LocalPlayer.PlayerId == b) { CurrentDrawTarget = currentDrawTarget; } } public static void ResetCurrentDrawTarget(byte arsonistId) { SetCurrentDrawTargetRPC(arsonistId, byte.MaxValue); } public static bool IsDrawPlayer(PlayerControl arsonist, PlayerControl target) { if ((Object)(object)arsonist == (Object)null && (Object)(object)target == (Object)null && IsDraw == null) { return false; } IsDraw.TryGetValue((arsonist.PlayerId, target.PlayerId), out var value); return value; } public static bool IsDrawDone(PlayerControl player) { var (num, num2) = GetDrawPlayerCount(player.PlayerId, out var _); return num >= num2; } public static (int, int) GetDrawPlayerCount(byte playerId, out List winnerList) { int num = 0; int num2 = RevolutionistDrawCount.GetInt(); int num3 = Main.AllAlivePlayerControls.Length; if (!Main.PlayerStates[playerId].IsDead) { num3--; } winnerList = new List(); if (num2 > num3) { num2 = num3; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (IsDraw.TryGetValue((playerId, val.PlayerId), out var value) && value) { winnerList.Add(val); num++; } } return (num, num2); } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { if (IsDrawPlayer(seer, target)) { return "●"; } if (RevolutionistTimer.TryGetValue(seer.PlayerId, out var value) && (Object)(object)value.Item1 == (Object)(object)target) { return "○"; } return string.Empty; } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting) { return string.Empty; } int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Revolutionist)), string.Format(Translator.GetString("EnterVentWinCountDown"), RevolutionistCountdown.TryGetValue(seer.PlayerId, out value) ? value : 10)); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(RevolutionistDrawTime.GetFloat()); if (!IsDraw[(killer.PlayerId, target.PlayerId)] && !RevolutionistTimer.ContainsKey(killer.PlayerId)) { RevolutionistTimer.TryAdd(killer.PlayerId, (target, 0f)); Utils.NotifyRoles(killer, target); SetCurrentDrawTargetRPC(killer.PlayerId, target.PlayerId); } return false; } private static void OnFixUpdateOthers(PlayerControl player) { //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) if (RevolutionistTimer.TryGetValue(player.PlayerId, out var value)) { byte playerId = player.PlayerId; if (!player.IsAlive() || Pelican.IsEaten(playerId)) { RevolutionistTimer.Remove(playerId); Utils.NotifyRoles(player); ResetCurrentDrawTarget(playerId); } else { var (val, num) = value; if (!val.IsAlive()) { RevolutionistTimer.Remove(playerId); } else if (num >= RevolutionistDrawTime.GetFloat()) { byte playerId2 = val.PlayerId; player.SetKillCooldown(); RevolutionistTimer.Remove(playerId); IsDraw[(playerId, playerId2)] = true; SetDrawPlayerRPC(player, val, isDrawed: true); Utils.NotifyRoles(player, val); ResetCurrentDrawTarget(playerId); if (IRandom.Instance.Next(1, 100) <= RevolutionistKillProbability.GetInt()) { playerId2.SetDeathReason(PlayerState.DeathReason.Sacrifice); player.RpcMurderPlayer(val); val.SetRealKiller(player); Main.PlayerStates[playerId2].SetDead(); Logger.Info("Revolutionist: " + player.GetNameWithRole() + " killed by " + val.GetNameWithRole(), "Revolutionist", escapeCRLF: true, 237, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Revolutionist.cs"); } } else { float num2 = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(player.Is(Reach.IsReach) ? 2 : Main.NormalOptions.KillDistance, 0, 2)] + 0.5f; if (Vector2.Distance(player.GetCustomPosition(), val.GetCustomPosition()) <= num2) { RevolutionistTimer[playerId] = (val, num + Time.fixedDeltaTime); } else { RevolutionistTimer.Remove(playerId); Utils.NotifyRoles(player, val); ResetCurrentDrawTarget(playerId); Logger.Info("Canceled: " + player.GetNameWithRole(), "Revolutionist", escapeCRLF: true, 253, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Revolutionist.cs"); } } } } if (!IsDrawDone(player) || !player.IsAlive()) { return; } byte playerId3 = player.PlayerId; if (RevolutionistStart.TryGetValue(playerId3, out var value2)) { if (RevolutionistLastTime.TryGetValue(playerId3, out var value3)) { long timeStamp = Utils.GetTimeStamp(); if (value3 != timeStamp) { RevolutionistLastTime[playerId3] = timeStamp; value3 = timeStamp; } int num3 = (int)(value3 - value2); int num4 = RevolutionistVentCountDown.GetInt() - num3; RevolutionistCountdown.Clear(); if (num4 <= 0) { GetDrawPlayerCount(playerId3, out var winnerList); PlayerControl[] array = winnerList.Where((PlayerControl x) => (Object)(object)x != (Object)null && x.IsAlive()).ToArray(); foreach (PlayerControl val2 in array) { val2.Data.IsDead = true; val2.SetDeathReason(PlayerState.DeathReason.Sacrifice); val2.RpcMurderPlayer(val2); Main.PlayerStates[val2.PlayerId].SetDead(); Utils.NotifyRoles(val2); } player.Data.IsDead = true; playerId3.SetDeathReason(PlayerState.DeathReason.Sacrifice); player.RpcMurderPlayer(player); Main.PlayerStates[playerId3].SetDead(); } else { RevolutionistCountdown.TryAdd(playerId3, num4); Utils.NotifyRoles(player, null, isForMeeting: false, NoCache: false, ForceLoop: false); } } else { RevolutionistLastTime.TryAdd(playerId3, RevolutionistStart[playerId3]); } } else { RevolutionistStart.TryAdd(playerId3, Utils.GetTimeStamp()); } } public override bool OnCoEnterVentOthers(PlayerPhysics __instance, int ventId) { if (((InnerNetClient)AmongUsClient.Instance).IsGameStarted && IsDrawDone(__instance.myPlayer)) { if (!CustomWinnerHolder.CheckForConvertedWinner(__instance.myPlayer.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Revolutionist); GetDrawPlayerCount(__instance.myPlayer.PlayerId, out var winnerList); CustomWinnerHolder.WinnerIds.Add(__instance.myPlayer.PlayerId); PlayerControl[] array = winnerList.ToArray(); foreach (PlayerControl val in array) { CustomWinnerHolder.WinnerIds.Add(val.PlayerId); } } return true; } return false; } } internal class Romantic : RoleBase { private const int Id = 13500; public static bool isProtect = false; public static bool isRomanticAlive = true; public static bool isPartnerProtected = false; public static OptionItem BetCooldown; private static OptionItem ProtectCooldown; private static OptionItem ProtectDuration; private static OptionItem KnowTargetRole; private static OptionItem BetTargetKnowRomantic; public static OptionItem VengefulKCD; public static OptionItem VengefulCanVent; public static OptionItem RuthlessKCD; public static OptionItem RuthlessCanVent; public static byte VengefulTargetId; private static readonly Dictionary BetTimes = new Dictionary(); public static readonly Dictionary BetPlayer = new Dictionary(); public static bool HasEnabled => CustomRoles.Romantic.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(13500, TabGroup.NeutralRoles, CustomRoles.Romantic); BetCooldown = FloatOptionItem.Create(13510, "RomanticBetCooldown", new FloatValueRule(0f, 60f, 1f), 7f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]).SetValueFormat(OptionFormat.Seconds); ProtectCooldown = FloatOptionItem.Create(13511, "RomanticProtectCooldown", new FloatValueRule(0f, 60f, 2.5f), 25f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]).SetValueFormat(OptionFormat.Seconds); ProtectDuration = FloatOptionItem.Create(13512, "RomanticProtectDuration", new FloatValueRule(0f, 60f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]).SetValueFormat(OptionFormat.Seconds); KnowTargetRole = BooleanOptionItem.Create(13513, "RomanticKnowTargetRole", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]); BetTargetKnowRomantic = BooleanOptionItem.Create(13514, "RomanticBetTargetKnowRomantic", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]); VengefulKCD = FloatOptionItem.Create(13515, "VengefulKCD", new FloatValueRule(0f, 60f, 2.5f), 22.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]).SetValueFormat(OptionFormat.Seconds); VengefulCanVent = BooleanOptionItem.Create(13516, "VengefulCanVent", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]); RuthlessKCD = FloatOptionItem.Create(13517, "RuthlessKCD", new FloatValueRule(0f, 60f, 2.5f), 22.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]).SetValueFormat(OptionFormat.Seconds); RuthlessCanVent = BooleanOptionItem.Create(13518, "RuthlessCanVent", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Romantic]); } public override void Init() { VengefulTargetId = byte.MaxValue; BetTimes.Clear(); BetPlayer.Clear(); isProtect = false; isPartnerProtected = false; } public override void Add(byte playerId) { BetTimes.Add(playerId, 1); CustomRoleManager.CheckDeadBodyOthers.Add(OthersAfterPlayerDeathTask); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { BetTimes.Remove(playerId); CustomRoleManager.CheckDeadBodyOthers.Remove(OthersAfterPlayerDeathTask); } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write((!BetTimes.TryGetValue(playerId, out var value)) ? 1 : value); val.Write(BetPlayer.TryGetValue(playerId, out var value2) ? value2 : byte.MaxValue); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); byte b = reader.ReadByte(); BetTimes.Remove(key); BetPlayer.Remove(key); BetTimes.Add(key, value); if (b != byte.MaxValue) { BetPlayer.Add(key, b); } } public override bool CanUseKillButton(PlayerControl player) { return true; } public override void SetKillCooldown(byte id) { if (BetTimes.TryGetValue(id, out var value) && value < 1) { Main.AllPlayerKillCooldown[id] = ProtectCooldown.GetFloat(); } else { Main.AllPlayerKillCooldown[id] = BetCooldown.GetFloat(); } } public override bool KnowRoleTarget(PlayerControl player, PlayerControl target) { if (!KnowTargetRole.GetBool()) { return false; } if (player.Is(CustomRoles.Romantic) && BetPlayer.TryGetValue(player.PlayerId, out var value)) { return value == target.PlayerId; } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (!isProtect) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("RomanticPartnerButtonText")); } else { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("RomanticProtectButtonText")); } } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if (killer.PlayerId == target.PlayerId) { return true; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if (!BetTimes.TryGetValue(killer.PlayerId, out var value) || value < 1) { isProtect = true; } byte value2; if (!isProtect) { BetTimes[killer.PlayerId]--; BetPlayer.Remove(killer.PlayerId); BetPlayer.Add(killer.PlayerId, target.PlayerId); SendRPC(killer.PlayerId); killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Bet"); killer.Notify(Translator.GetString("RomanticBetPlayer")); if (BetTargetKnowRomantic.GetBool()) { target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Romantic)), Translator.GetString("RomanticBetOnYou"))); } Utils.NotifyRoles(); Logger.Info("Romantic:" + killer.GetNameWithRole().RemoveHtmlTags() + " bet player => " + target.GetNameWithRole().RemoveHtmlTags(), "Romantic", escapeCRLF: true, 166, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); } else if (BetPlayer.TryGetValue(killer.PlayerId, out value2)) { PlayerControl tpc = Utils.GetPlayerById(value2); isPartnerProtected = true; killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Shield"); killer.Notify(Translator.GetString("RomanticProtectPartner")); tpc.Notify(Translator.GetString("RomanticIsProtectingYou")); new LateTask(delegate { if (GameStates.IsInTask && tpc.IsAlive()) { isPartnerProtected = false; killer.Notify(Translator.GetString("ProtectingOver")); tpc.Notify(Translator.GetString("ProtectingOver")); killer.SetKillCooldown(); } }, ProtectDuration.GetFloat(), "Romantic Protecting Is Over"); } return false; } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (isPartnerProtected) { return BetPlayer.ContainsValue(target.PlayerId); } return false; } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { isRomanticAlive = false; } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seer == (Object)(object)seen) { return string.Empty; } if (!BetPlayer.ContainsValue(seen.PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Romantic)), "♥"); } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (!seer.Is(CustomRoles.Romantic) && BetTargetKnowRomantic.GetBool()) { if ((Object)(object)seer == (Object)(object)target && seer.IsAlive() && BetPlayer.ContainsValue(seer.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Romantic)), "♥"); } if ((Object)(object)seer != (Object)(object)target && seer.IsAlive() && BetPlayer.ContainsKey(target.PlayerId) && BetPlayer.ContainsValue(seer.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Romantic)), "♥"); } if ((Object)(object)seer != (Object)(object)target && !seer.IsAlive() && BetPlayer.ContainsValue(target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Romantic)), "♥"); } } return string.Empty; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Utils.GetPlayerById(playerId) == (Object)null) { return null; } int value; int value2; return Utils.ColorString(Color32.op_Implicit((BetTimes.TryGetValue(playerId, out value) && value >= 1) ? Color.white : Utils.GetRoleColor(CustomRoles.Romantic)), "- " + ((BetTimes.TryGetValue(playerId, out value2) && value2 >= 1 && value2 >= 1) ? "♡" : "♥")); } public override void OnReportDeadBody(PlayerControl ugandan, NetworkedPlayerInfo knuckles) { isPartnerProtected = false; } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { if ((Object)(object)exiled == (Object)null) { return; } byte playerId = exiled.PlayerId; if (BetPlayer.ContainsValue(playerId)) { player = Utils.GetPlayerById(playerId); if (!((Object)(object)player == (Object)null)) { ChangeRole(player); } } } private void OthersAfterPlayerDeathTask(PlayerControl killer, PlayerControl player, bool inMeeting) { ChangeRole(player); } private static void ChangeRole(PlayerControl player) { byte playerId = player.PlayerId; if (!BetPlayer.ContainsValue(playerId) || (Object)(object)player == (Object)null) { return; } byte romantic = 115; CollectionExtensions.Do>((IEnumerable>)BetPlayer, (Action>)delegate(KeyValuePair x) { if (x.Value == playerId) { romantic = x.Key; } }); if (romantic == 115) { return; } PlayerControl pc = Utils.GetPlayerById(romantic); if ((Object)(object)pc == (Object)null) { return; } if (player.GetCustomRole().IsImpostorTeamV3()) { Logger.Info("Impostor Romantic Partner Died changing " + pc.GetNameWithRole() + " to Refugee", "Romantic", escapeCRLF: true, 268, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); pc.RpcSetCustomRole(CustomRoles.Refugee); Utils.NotifyRoles(); pc.ResetKillCooldown(); pc.SetKillCooldown(); return; } if (player.IsNeutralKiller()) { Logger.Info("Neutral Romantic Partner Died changing " + pc.GetNameWithRole() + " to Ruthless Romantic", "Romantic", escapeCRLF: true, 276, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); pc.RpcSetCustomRole(CustomRoles.RuthlessRomantic); pc.GetRoleClass().OnAdd(pc.PlayerId); Utils.NotifyRoles(); pc.ResetKillCooldown(); pc.SetKillCooldown(); return; } new LateTask(delegate { Logger.Info("Crew/nnk Romantic Partner Died changing " + pc.GetNameWithRole().RemoveHtmlTags() + " to Vengeful romantic", "Romantic", escapeCRLF: true, 287, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); PlayerControl realKiller = player.GetRealKiller(); if ((Object)(object)realKiller == (Object)null) { pc.RpcSetCustomRole(CustomRoles.RuthlessRomantic); pc.GetRoleClass().OnAdd(pc.PlayerId); Logger.Info("No real killer for " + player.GetRealName().RemoveHtmlTags() + ", role changed to ruthless romantic", "Romantic", escapeCRLF: true, 293, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); } else { VengefulTargetId = realKiller.PlayerId; pc.RpcSetCustomRole(CustomRoles.VengefulRomantic); pc.GetRoleClass().OnAdd(pc.PlayerId); if (pc.GetRoleClass() is VengefulRomantic vengefulRomantic) { vengefulRomantic.SendRPC(pc.PlayerId); } Logger.Info($"Vengeful romantic target: {realKiller.GetRealName().RemoveHtmlTags()}, [{VengefulTargetId}]", "Vengeful Romantic", escapeCRLF: true, 302, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Romantic.cs"); } Utils.NotifyRoles(); pc.ResetKillCooldown(); pc.SetKillCooldown(); }, 0.2f, "Convert to Vengeful Romantic"); } } internal class VengefulRomantic : RoleBase { public static bool hasKilledKiller = false; public static Dictionary VengefulTarget = new Dictionary(); public static bool HasEnabled => CustomRoles.Romantic.HasEnabled(); public override CustomRoles ThisRoleBase => new Romantic().ThisRoleBase; public override Custom_RoleType ThisRoleType => new Romantic().ThisRoleType; public override void Init() { VengefulTarget.Clear(); hasKilledKiller = false; } public override void Add(byte playerId) { VengefulTarget.Add(playerId, Romantic.VengefulTargetId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl player) { if (!player.Data.IsDead) { return !hasKilledKiller; } return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (killer.PlayerId == target.PlayerId) { return true; } if (VengefulTarget.TryGetValue(killer.PlayerId, out var value) && target.PlayerId == value) { hasKilledKiller = true; return true; } killer.SetDeathReason(PlayerState.DeathReason.Misfire); killer.RpcMurderPlayer(killer); return false; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Utils.GetPlayerById(playerId) == (Object)null) { return null; } return Utils.ColorString(Color32.op_Implicit(hasKilledKiller ? Color.green : Utils.GetRoleColor(CustomRoles.VengefulRomantic)), "- " + (hasKilledKiller ? "♥" : "♡")); } public void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(VengefulTarget.TryGetValue(playerId, out var value) ? value : byte.MaxValue); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); byte b = reader.ReadByte(); VengefulTarget.Remove(key); if (b != byte.MaxValue) { VengefulTarget.Add(key, b); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = Romantic.VengefulKCD.GetFloat(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return Romantic.VengefulCanVent.GetBool(); } } internal class RuthlessRomantic : RoleBase { private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => new Romantic().ThisRoleBase; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = Romantic.RuthlessKCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return Romantic.RuthlessCanVent.GetBool(); } } internal class SchrodingersCat : RoleBase { private const int Id = 6900; public static readonly Dictionary teammate = new Dictionary(); public static bool HasEnabled => CustomRoles.SchrodingersCat.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(6900, TabGroup.NeutralRoles, CustomRoles.SchrodingersCat); } public override void Init() { teammate.Clear(); } public override void Add(byte playerId) { teammate[playerId] = byte.MaxValue; } private void SendRPC(byte catID) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(catID); val.Write(teammate[catID]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); byte value = reader.ReadByte(); teammate[key] = value; } public override string GetProgressText(byte catID, bool computervirus) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) byte value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SchrodingersCat).ShadeColor(0.25f)), "(" + ((!teammate.TryGetValue(catID, out value)) ? "0" : ((value != byte.MaxValue) ? "0" : "1")) + ")"); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return true; } if (teammate[target.PlayerId] != byte.MaxValue) { return true; } teammate[target.PlayerId] = killer.PlayerId; SendRPC(target.PlayerId); killer.RpcGuardAndKill(target); target.RpcGuardAndKill(); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); killer.SetKillCooldown(); return false; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seer != (Object)(object)target && seer.IsAlive() && teammate.ContainsKey(seer.PlayerId) && teammate.ContainsValue(target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SchrodingersCat)), " ☜"); } if ((Object)(object)seer != (Object)(object)target && !seer.IsAlive() && teammate.ContainsValue(target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SchrodingersCat)), " ☜"); } return string.Empty; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (teammate.TryGetValue(seer.PlayerId, out var value) && target.PlayerId == value) { if (target.GetCustomRole().IsCrewmate()) { return Main.roleColors[CustomRoles.CrewmateTOHE]; } return Main.roleColors[target.GetCustomRole()]; } return string.Empty; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { if (teammate.TryGetValue(target.PlayerId, out var value) && value == seer.PlayerId) { return true; } return false; } public static void SchrodingerWinCondition(PlayerControl pc) { if (HasEnabled && !((Object)(object)pc == (Object)null) && pc.Is(CustomRoles.SchrodingersCat) && teammate.ContainsKey(pc.PlayerId) && teammate[pc.PlayerId] != byte.MaxValue && (CustomWinnerHolder.WinnerIds.Contains(teammate[pc.PlayerId]) || (Main.PlayerStates.TryGetValue(teammate[pc.PlayerId], out var value) && CustomWinnerHolder.WinnerRoles.Contains(value.MainRole)))) { CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.SchrodingersCat); } } } internal class Seeker : RoleBase { private const int Id = 14600; private static OptionItem PointsToWin; private static OptionItem TagCooldownOpt; private static int PointsToWinOpt; private static readonly Dictionary Targets = new Dictionary(); private static readonly Dictionary TotalPoints = new Dictionary(); private static readonly Dictionary DefaultSpeed = new Dictionary(); public static bool HasEnabled => CustomRoles.Seeker.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void SetupCustomOption() { Options.SetupRoleOptions(14600, TabGroup.NeutralRoles, CustomRoles.Seeker); PointsToWin = IntegerOptionItem.Create(14610, "SeekerPointsToWin", new IntegerValueRule(1, 20, 1), 5, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Seeker]); TagCooldownOpt = FloatOptionItem.Create(14611, "SeekerTagCooldown", new FloatValueRule(0f, 180f, 2.5f), 12.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Seeker]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { Targets.Clear(); TotalPoints.Clear(); DefaultSpeed.Clear(); } public override void Add(byte playerId) { TotalPoints.Add(playerId, 0); DefaultSpeed[playerId] = Main.AllPlayerSpeed[playerId]; PointsToWinOpt = PointsToWin.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { new LateTask(delegate { ResetTarget(Utils.GetPlayerById(playerId)); }, 10f, "Seeker Round 1"); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = TagCooldownOpt.GetFloat(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("SeekerKillButtonText")); } private void SendRPC(byte seekerId, byte targetId = byte.MaxValue, bool setTarget = true) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(setTarget); if (!setTarget) { val.Write(seekerId); val.Write(TotalPoints[seekerId]); } else { val.Write(seekerId); val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { bool num = reader.ReadBoolean(); byte key = reader.ReadByte(); if (!num) { int value = reader.ReadInt32(); if (TotalPoints.ContainsKey(key)) { TotalPoints[key] = value; } else { TotalPoints.Add(key, 0); } } else { byte value2 = reader.ReadByte(); Targets[key] = value2; } } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (GetTarget(killer) == target.PlayerId) { TotalPoints[killer.PlayerId]++; ResetTarget(killer); } else { TotalPoints[killer.PlayerId]--; } if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(); } SetKillCooldown(killer.PlayerId); killer.SyncSettings(); SendRPC(killer.PlayerId, byte.MaxValue, setTarget: false); return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { Main.AllPlayerSpeed[_state.PlayerId] = DefaultSpeed[_state.PlayerId]; } public override void OnFixedUpdateLowLoad(PlayerControl player) { if ((Object)(object)player == (Object)null) { return; } byte target = GetTarget(player); if (target == byte.MaxValue) { return; } byte playerId = player.PlayerId; PlayerState playerState = Main.PlayerStates[target]; int num = TotalPoints[playerId]; if (playerState.IsDead) { ResetTarget(player); } if (num >= PointsToWinOpt) { TotalPoints[playerId] = PointsToWinOpt; if (!CustomWinnerHolder.CheckForConvertedWinner(playerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Seeker); CustomWinnerHolder.WinnerIds.Add(playerId); } } } private byte GetTarget(PlayerControl player) { if ((Object)(object)player == (Object)null || Targets == null) { return byte.MaxValue; } if (!Targets.TryGetValue(player.PlayerId, out var value)) { return ResetTarget(player); } return value; } private static void FreezeSeeker(PlayerControl player) { byte playerId = player.PlayerId; Main.AllPlayerSpeed[playerId] = 0.0001f; ReportDeadBodyPatch.CanReport[playerId] = false; player?.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[playerId] = DefaultSpeed[playerId]; ReportDeadBodyPatch.CanReport[playerId] = true; player?.MarkDirtySettings(); }, 5f, "Freeze Seeker"); } private byte ResetTarget(PlayerControl player) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return byte.MaxValue; } byte playerId = player.PlayerId; List list = new List(Main.AllAlivePlayerControls.Where((PlayerControl pc) => !pc.Is(CustomRoles.Seeker) && !pc.Is(CustomRoles.Solsticer))); if (list.Count >= 2 && Targets.TryGetValue(player.PlayerId, out var nowTarget)) { list.RemoveAll((PlayerControl x) => x.PlayerId == nowTarget); } if (!list.Any()) { Logger.Warn("Failed to specify target: Target candidate does not exist", "Seeker", escapeCRLF: true, 178, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Seeker.cs"); return byte.MaxValue; } PlayerControl val = list.RandomElement(); byte playerId2 = val.PlayerId; Targets[playerId] = playerId2; player.Notify(string.Format(Translator.GetString("SeekerNotify"), val.GetRealName())); val.Notify(Translator.GetString("SeekerTargetNotify")); SendRPC(player.PlayerId, playerId2); Utils.NotifyRoles(player); FreezeSeeker(player); return playerId2; } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!Targets.ContainsValue(target.PlayerId)) { return ""; } return Main.roleColors[CustomRoles.Seeker]; } public override string GetProgressText(byte PlayerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Seeker).ShadeColor(0.25f)), $"({TotalPoints[PlayerId]}/{PointsToWin.GetInt()})"); } public override void AfterMeetingTasks() { PlayerControl player = base._Player; if (player.IsAlive()) { FreezeSeeker(player); } } public override void NotifyAfterMeeting() { PlayerControl player = base._Player; if (player.IsAlive()) { byte target = GetTarget(player); player.Notify(string.Format(Translator.GetString("SeekerNotify"), Utils.GetPlayerById(target).GetRealName())); Utils.GetPlayerById(target)?.Notify(Translator.GetString("SeekerTargetNotify")); } } } internal class SerialKiller : RoleBase { private const int Id = 17900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem HasSerialKillerBuddy; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(17900, TabGroup.NeutralRoles, CustomRoles.SerialKiller); KillCooldown = FloatOptionItem.Create(17910, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SerialKiller]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(17911, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SerialKiller]); HasImpostorVision = BooleanOptionItem.Create(17913, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SerialKiller]); HasSerialKillerBuddy = BooleanOptionItem.Create(17916, "HasSerialKillerBuddy", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SerialKiller]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } } internal class Shaman : RoleBase { private const int Id = 13600; private static OptionItem VoodooCooldown; private byte ShamanTarget = byte.MaxValue; private bool ShamanTargetChoosen; public static bool HasEnabled => CustomRoles.Shaman.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override void SetupCustomOption() { Options.SetupRoleOptions(13600, TabGroup.NeutralRoles, CustomRoles.Shaman); VoodooCooldown = FloatOptionItem.Create(13610, "VoodooCooldown", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shaman]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { ShamanTarget = byte.MaxValue; ShamanTargetChoosen = false; } public override void Add(byte playerId) { if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override void AfterMeetingTasks() { ShamanTarget = byte.MaxValue; ShamanTargetChoosen = false; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = VoodooCooldown.GetFloat(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("ShamanButtonText")); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (ShamanTarget == byte.MaxValue) { return true; } PlayerControl target2 = ChangeTarget(base._Player); if (killer.CheckForInvalidMurdering(target2) && killer.RpcCheckAndMurder(target2, check: true)) { killer.RpcMurderPlayer(target2); target2.SetRealKiller(base._Player); } else { base._Player.Notify(Translator.GetString("Shaman_KillerCannotMurderChosenTarget"), 10f); } ShamanTarget = byte.MaxValue; return false; } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!ShamanTargetChoosen) { ShamanTarget = target.PlayerId; base._Player.RpcGuardAndKill(target); ShamanTargetChoosen = true; } else { base._Player.Notify(Translator.GetString("ShamanTargetAlreadySelected")); } return false; } private PlayerControl ChangeTarget(PlayerControl target) { if (!target.IsAlive() || !ShamanTargetChoosen) { return target; } return Utils.GetPlayerById(ShamanTarget); } } internal class Shroud : RoleBase { private const int Id = 18000; private static OptionItem ShroudCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static readonly Dictionary ShroudList = new Dictionary(); public static bool HasEnabled => CustomRoles.Shroud.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18000, TabGroup.NeutralRoles, CustomRoles.Shroud); ShroudCooldown = FloatOptionItem.Create(18010, "ShroudCooldown", new FloatValueRule(0f, 180f, 1f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shroud]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(18011, GeneralOption.CanVent, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shroud]); HasImpostorVision = BooleanOptionItem.Create(18013, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Shroud]); } public override void Init() { ShroudList.Clear(); } public override void Add(byte playerId) { CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC(byte shroudId, byte targetId, byte typeId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(typeId); val.Write(shroudId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte b = reader.ReadByte(); byte value = reader.ReadByte(); byte key = reader.ReadByte(); switch (b) { case 0: ShroudList.Clear(); break; case 1: ShroudList[key] = value; break; case 2: ShroudList.Remove(key); break; } } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ShroudCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public static bool ShroudIsActive(byte playerId) { return ShroudList.ContainsKey(playerId); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (ShroudList.ContainsKey(target.PlayerId)) { return false; } if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceMini)), Translator.GetString("CantShroud"))); return false; } ShroudList[target.PlayerId] = killer.PlayerId; SendRPC(killer.PlayerId, target.PlayerId, 1); killer.SetKillCooldown(); Utils.NotifyRoles(killer, target); return false; } private void OnFixedUpdateOthers(PlayerControl shroud) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if (!ShroudList.ContainsKey(shroud.PlayerId)) { return; } if (!shroud.IsAlive() || Pelican.IsEaten(shroud.PlayerId)) { ShroudList.Remove(shroud.PlayerId); SendRPC(byte.MaxValue, shroud.PlayerId, 2); return; } Vector3 position = ((Component)shroud).transform.position; Dictionary dictionary = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (val.PlayerId != shroud.PlayerId && !val.Is(CustomRoles.Shroud) && !val.Is(CustomRoles.Pestilence)) { float value = Vector2.Distance(Vector2.op_Implicit(position), Vector2.op_Implicit(((Component)val).transform.position)); dictionary.Add(val.PlayerId, value); } } if (dictionary.Any()) { KeyValuePair keyValuePair = dictionary.OrderBy((KeyValuePair c) => c.Value).FirstOrDefault(); PlayerControl playerById = Utils.GetPlayerById(keyValuePair.Key); float num = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(Main.NormalOptions.KillDistance, 0, 2)]; if (keyValuePair.Value <= num && shroud.CanMove && playerById.CanMove && shroud.RpcCheckAndMurder(playerById, check: true)) { byte b = ShroudList[shroud.PlayerId]; RPC.PlaySoundRPC(b, Sounds.KillSound); playerById.SetDeathReason(PlayerState.DeathReason.Shrouded); shroud.RpcMurderPlayer(playerById); playerById.SetRealKiller(Utils.GetPlayerById(b)); Utils.MarkEveryoneDirtySettings(); ShroudList.Remove(shroud.PlayerId); SendRPC(byte.MaxValue, shroud.PlayerId, 2); Utils.NotifyRoles(Utils.GetPlayerById(b), shroud); } } } public override void OnPlayerExiled(PlayerControl shroud, NetworkedPlayerInfo exiled) { if (!shroud.IsAlive() || ((Object)(object)exiled != (Object)null && exiled.PlayerId == shroud.PlayerId)) { ShroudList.Clear(); SendRPC(byte.MaxValue, byte.MaxValue, 0); return; } foreach (byte key in ShroudList.Keys) { PlayerControl playerById = Utils.GetPlayerById(key); if (playerById.IsAlive()) { playerById.SetDeathReason(PlayerState.DeathReason.Shrouded); playerById.RpcMurderPlayer(playerById); playerById.SetRealKiller(shroud); ShroudList.Remove(playerById.PlayerId); SendRPC(byte.MaxValue, playerById.PlayerId, 2); } } } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isMeeting = false) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!isMeeting || !ShroudList.ContainsKey(target.PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Shroud)), "◈"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("ShroudButtonText") ?? ""); } } } internal class Sidekick : RoleBase { private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = Jackal.KillCooldownSK.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte ico) { opt.SetVision(Jackal.HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl player) { return true; } public override bool CanUseImpostorVentButton(PlayerControl player) { return Jackal.CanVentSK.GetBool(); } public override bool CanUseSabotage(PlayerControl player) { return Jackal.CanUseSabotageSK.GetBool(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText")); ((ActionButton)hud.SabotageButton).OverrideText(Translator.GetString("SabotageButtonText")); } } internal class Solsticer : RoleBase { private const int Id = 26200; private static OptionItem EveryOneKnowSolsticer; private static OptionItem SolsticerCanVent; private static OptionItem SolsticerKnowKiller; public static OptionItem SolsticerCanGuess; private static OptionItem SolsticerSpeed; private static OptionItem AddTasksPreDeadPlayer; private static OptionItem RemainingTasksToBeWarned; private static byte playerid = byte.MaxValue; private static bool patched = false; public static int AddShortTasks = 0; private static int Count = 0; private static bool warningActived = false; private static bool CanGuess = true; private static string MurderMessage = string.Empty; public static bool HasEnabled => CustomRoles.Solsticer.HasEnabled(); public override CustomRoles ThisRoleBase { get { if (!SolsticerCanVent.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(26200, TabGroup.NeutralRoles, CustomRoles.Solsticer); EveryOneKnowSolsticer = BooleanOptionItem.Create(26210, "EveryOneKnowSolsticer", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); SolsticerKnowKiller = BooleanOptionItem.Create(26211, "SolsticerKnowItsKiller", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); SolsticerCanVent = BooleanOptionItem.Create(26212, GeneralOption.CanVent, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); SolsticerCanGuess = BooleanOptionItem.Create(26213, GeneralOption.CanGuess, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); SolsticerSpeed = FloatOptionItem.Create(26214, "SolsticerSpeed", new FloatValueRule(0f, 5f, 0.1f), 1.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); RemainingTasksToBeWarned = IntegerOptionItem.Create(26215, "SolsticerRemainingTaskWarned", new IntegerValueRule(0, 10, 1), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); AddTasksPreDeadPlayer = FloatOptionItem.Create(26216, "SAddTasksPreDeadPlayer", new FloatValueRule(0f, 15f, 0.1f), 0.5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Solsticer]); Options.OverrideTasksData.Create(26217, TabGroup.NeutralRoles, CustomRoles.Solsticer); } public override void Init() { playerid = byte.MaxValue; warningActived = false; patched = false; AddShortTasks = 0; Count = 0; CanGuess = true; MurderMessage = string.Empty; } public override void Add(byte playerId) { playerid = playerId; } public override void ApplyGameOptions(IGameOptions opt, byte id) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; AURoleOptions.PlayerSpeedMod = ((!patched) ? SolsticerSpeed.GetFloat() : 0.5f); } public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if ((Object)(object)player == (Object)null) { return true; } SendRPC(); if (patched) { ResetTasks(player); } TaskState playerTaskState = player.GetPlayerTaskState(); if (playerTaskState.IsTaskFinished) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Solsticer); CustomWinnerHolder.WinnerIds.Add(player.PlayerId); } else if (playerTaskState.AllTasksCount - playerTaskState.CompletedTasksCount <= RemainingTasksToBeWarned.GetInt()) { ActiveWarning(player); } return true; } public override string GetSuffixOthers(PlayerControl seer, PlayerControl target, bool IsForMeeting = false) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (IsForMeeting || !warningActived || seer.Is(CustomRoles.Solsticer)) { return string.Empty; } if (seer.PlayerId != target.PlayerId && !target.Is(CustomRoles.Solsticer)) { return string.Empty; } string text = "⚠"; if (IsSolsticerTarget(seer, onlyKiller: true) && !target.Is(CustomRoles.Solsticer)) { text += TargetArrow.GetArrows(seer, playerid); } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Solsticer)), text); } private void ActiveWarning(PlayerControl pc) { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => IsSolsticerTarget(x, onlyKiller: true)).ToArray(); for (int i = 0; i < array.Length; i++) { TargetArrow.Add(array[i].PlayerId, pc.PlayerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { warningActived = true; SendRPC(); Utils.NotifyRoles(); } } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (!GameStates.IsMeeting) { if (killer.Is(CustomRoles.Quizmaster)) { return true; } target.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); ReportDeadBodyPatch.CanReport[target.PlayerId] = false; target.Notify(string.Format(Translator.GetString("SolsticerMurdered"), killer.GetRealName())); target.RpcGuardAndKill(); patched = true; target.MarkDirtySettings(); ResetTasks(target); if (EveryOneKnowSolsticer.GetBool()) { killer.Notify(Translator.GetString("MurderSolsticer")); RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); } killer.SetKillCooldown(10f, null, EveryOneKnowSolsticer.GetBool()); killer.MarkDirtySettings(); if (SolsticerKnowKiller.GetBool()) { MurderMessage = string.Format(Translator.GetString("SolsticerMurderMessage"), killer.GetRealName(), Translator.GetString(killer.GetCustomRole().ToString())); } else { MurderMessage = ""; } } return false; } public override void AfterMeetingTasks() { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Solsticer)).ToArray(); foreach (PlayerControl val in array) { Main.AllPlayerSpeed[val.PlayerId] = SolsticerSpeed.GetFloat(); ReportDeadBodyPatch.CanReport[val.PlayerId] = true; val.MarkDirtySettings(); ResetTasks(val); } MurderMessage = ""; patched = false; } public override void OnFixedUpdate(PlayerControl pc) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (patched && GameStates.IsInTask) { Count--; if (Count <= 0) { Count = 15; Vector2 blackRoomPosition = ExtendedPlayerControl.GetBlackRoomPosition(); if (!(Vector2.Distance(blackRoomPosition, pc.GetCustomPosition()) < 1f) && !GameStates.IsMeeting && patched) { pc.RpcTeleport(blackRoomPosition); } } } else if (GameStates.IsInGame && Main.AllPlayerSpeed[pc.PlayerId] != SolsticerSpeed.GetFloat()) { Main.AllPlayerSpeed[pc.PlayerId] = SolsticerSpeed.GetFloat(); pc.MarkDirtySettings(); } } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); TaskState playerTaskState = Utils.GetPlayerById(playerid).GetPlayerTaskState(); if (playerTaskState != null) { val.Write(playerTaskState.AllTasksCount); val.Write(playerTaskState.CompletedTasksCount); } else { val.Write(0); val.Write(0); } val.Write(warningActived); val.Write(playerid); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { Logger.Info("syncsolsticer", "solsticer", escapeCRLF: true, 220, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Solsticer.cs"); int num = reader.ReadInt32(); int num2 = reader.ReadInt32(); warningActived = reader.ReadBoolean(); playerid = reader.ReadByte(); if (num != 255 && num2 != 255) { TaskState playerTaskState = Utils.GetPlayerById(playerid).GetPlayerTaskState(); playerTaskState.AllTasksCount = num; playerTaskState.CompletedTasksCount = num2; } if (warningActived) { ActiveWarning(Utils.GetPlayerById(playerid)); } } public static bool OtherKnowSolsticer(PlayerControl target) { if (target.Is(CustomRoles.Solsticer)) { return EveryOneKnowSolsticer.GetBool(); } return false; } private static bool IsSolsticerTarget(PlayerControl pc, bool onlyKiller) { if (pc.IsAlive()) { if (onlyKiller) { return pc.HasImpKillButton(); } return true; } return false; } public void ResetTasks(PlayerControl pc) { SetShortTasksToAdd(); TaskState playerTaskState = pc.GetPlayerTaskState(); pc.Data.RpcSetTasks(new Il2CppStructArray(0L)); playerTaskState.CompletedTasksCount = 0; pc.RpcGuardAndKill(); pc.Notify(Translator.GetString("SolsticerTasksReset")); CollectionExtensions.Do((IEnumerable)Main.AllPlayerControls, (Action)delegate(PlayerControl x) { TargetArrow.Remove(x.PlayerId, pc.PlayerId); }); warningActived = false; SendRPC(); } public static void SetShortTasksToAdd() { int num = Main.PlayerStates.Count((KeyValuePair x) => !x.Value.Disconnected); int num2 = Main.AllAlivePlayerControls.Length; AddShortTasks = (int)((float)(num - num2) * AddTasksPreDeadPlayer.GetFloat()); } public override bool CheckMisGuessed(bool isUI, PlayerControl pc, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { PlayerControl dp = (guesserSuicide ? pc : target); if (pc.PlayerId == target.PlayerId) { CanGuess = false; new LateTask(delegate { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(Translator.GetString("SolsticerMisGuessed"), dp.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Solsticer)), Translator.GetString("GuessKillTitle")), logforChatManager: true); }, 0.6f, "Solsticer MisGuess Msg"); return true; } return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.Solsticer) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSolsticer")); return true; } return false; } public override bool GuessCheck(bool isUI, PlayerControl pc, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (!CanGuess || !SolsticerCanGuess.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("SolsticerGuessMax")); return true; } return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { patched = false; } public override void OnMeetingHudStart(PlayerControl pc) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if (pc.Is(CustomRoles.Solsticer)) { SetShortTasksToAdd(); if (MurderMessage == "") { MurderMessage = string.Format(Translator.GetString("SolsticerOnMeeting"), AddShortTasks); } MeetingHudStartPatch.AddMsg(MurderMessage, pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Solsticer)), Translator.GetString("SolsticerTitle"))); } } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.SchrodingersCat) && SchrodingersCat.teammate.ContainsKey(seer.PlayerId) && target.PlayerId == SchrodingersCat.teammate[seer.PlayerId]) { if (target.GetCustomRole().IsCrewmate()) { return "#8CFFFF"; } return Main.roleColors[target.GetCustomRole()]; } if (target.Is(CustomRoles.SchrodingersCat) && SchrodingersCat.teammate.ContainsKey(target.PlayerId) && seer.PlayerId == SchrodingersCat.teammate[target.PlayerId]) { if (seer.GetCustomRole().IsCrewmate()) { return "#8CFFFF"; } return Main.roleColors[seer.GetCustomRole()]; } return string.Empty; } } internal class SoulCollector : RoleBase { private const int Id = 15300; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem SoulCollectorPointsOpt; private static OptionItem CollectOwnSoulOpt; private static readonly Dictionary SoulCollectorTarget = new Dictionary(); private static readonly Dictionary SoulCollectorPoints = new Dictionary(); private static readonly Dictionary DidVote = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(15300, TabGroup.NeutralRoles, CustomRoles.SoulCollector); SoulCollectorPointsOpt = IntegerOptionItem.Create(15310, "SoulCollectorPointsToWin", new IntegerValueRule(1, 14, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SoulCollector]).SetValueFormat(OptionFormat.Times); CollectOwnSoulOpt = BooleanOptionItem.Create(15311, "SoulCollector_CollectOwnSoulOpt", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SoulCollector]); } public override void Init() { playerIdList.Clear(); SoulCollectorTarget.Clear(); SoulCollectorPoints.Clear(); DidVote.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); SoulCollectorTarget.TryAdd(playerId, byte.MaxValue); SoulCollectorPoints.TryAdd(playerId, 0); DidVote.TryAdd(playerId, value: false); CustomRoleManager.CheckDeadBodyOthers.Add(OnPlayerDead); } public override string GetProgressText(byte playerId, bool cvooms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SoulCollector).ShadeColor(0.25f)), SoulCollectorPoints.TryGetValue(playerId, out value) ? $"({value}/{SoulCollectorPointsOpt.GetInt()})" : "Invalid"); } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(SoulCollectorPoints[playerId]); val.Write(SoulCollectorTarget[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); byte value2 = reader.ReadByte(); if (SoulCollectorPoints.ContainsKey(key)) { SoulCollectorPoints[key] = value; } else { SoulCollectorPoints.Add(key, 0); } if (SoulCollectorTarget.ContainsKey(key)) { SoulCollectorTarget[key] = value2; } else { SoulCollectorTarget.Add(key, byte.MaxValue); } } public override void OnVote(PlayerControl voter, PlayerControl target) { //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!(DidVote.TryGetValue(voter.PlayerId, out var value) && value) && SoulCollectorTarget[voter.PlayerId] == byte.MaxValue) { DidVote[voter.PlayerId] = true; if (!CollectOwnSoulOpt.GetBool() && voter.PlayerId == target.PlayerId) { Utils.SendMessage(Translator.GetString("SoulCollectorSelfVote"), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SoulCollector)), Translator.GetString("SoulCollectorTitle"))); Logger.Info(voter.GetNameWithRole() + " self vote not allowed", "SoulCollector", escapeCRLF: true, 90, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\SoulCollector.cs"); SoulCollectorTarget[voter.PlayerId] = byte.MaxValue; } else { SoulCollectorTarget.Remove(voter.PlayerId); SoulCollectorTarget.TryAdd(voter.PlayerId, target.PlayerId); Logger.Info(voter.GetNameWithRole() + " predicted the death of " + target.GetNameWithRole(), "SoulCollector", escapeCRLF: true, 97, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\SoulCollector.cs"); Utils.SendMessage(string.Format(Translator.GetString("SoulCollectorTarget"), target.GetRealName()), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SoulCollector)), Translator.GetString("SoulCollectorTitle"))); SendRPC(voter.PlayerId); } } } public override void OnReportDeadBody(PlayerControl ryuk, NetworkedPlayerInfo iscute) { foreach (byte key in SoulCollectorTarget.Keys) { SoulCollectorTarget[key] = byte.MaxValue; DidVote[key] = false; } } private void OnPlayerDead(PlayerControl killer, PlayerControl deadPlayer, bool inMeeting) { foreach (KeyValuePair item in SoulCollectorTarget) { item.Deconstruct(out var key, out var value); byte b = key; byte b2 = value; if (b2 == byte.MaxValue) { continue; } Main.PlayerStates.TryGetValue(b2, out var value2); if (b2 == deadPlayer.PlayerId && value2.IsDead && !value2.Disconnected) { SoulCollectorTarget[b] = byte.MaxValue; Dictionary soulCollectorPoints = SoulCollectorPoints; value = b; soulCollectorPoints[value]++; SendRPC(b); Utils.NotifyRoles(Utils.GetPlayerById(b), null, isForMeeting: false, NoCache: false, ForceLoop: false); } if (SoulCollectorPoints[b] >= SoulCollectorPointsOpt.GetInt()) { SoulCollectorPoints[b] = SoulCollectorPointsOpt.GetInt(); if (!CustomWinnerHolder.CheckForConvertedWinner(b)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.SoulCollector); CustomWinnerHolder.WinnerIds.Add(b); } } } } } internal class Specter : RoleBase { private const int Id = 14900; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem CanVent; public static OptionItem SnatchesWin; public static OptionItem CanGuess; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase { get { if (!CanVent.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override void SetupCustomOption() { Options.SetupRoleOptions(14900, TabGroup.NeutralRoles, CustomRoles.Specter); CanVent = BooleanOptionItem.Create(14902, GeneralOption.CanVent, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Specter]); SnatchesWin = BooleanOptionItem.Create(14903, GeneralOption.SnatchesWin, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Specter]); CanGuess = BooleanOptionItem.Create(14904, GeneralOption.CanGuess, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Specter]); Options.OverrideTasksData.Create(14905, TabGroup.NeutralRoles, CustomRoles.Specter); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (!CanGuess.GetBool()) { Logger.Info($"Guess Disabled for this player {guesser.PlayerId}", "GuessManager", escapeCRLF: true, 52, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Specter.cs"); guesser.ShowInfoMessage(isUI, Translator.GetString("GuessDisabled")); return true; } return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.Specter) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessSpecter")); return true; } return false; } } internal class Spiritcaller : RoleBase { private const int Id = 25200; public static bool HasEnabled = CustomRoles.Spiritcaller.HasEnabled(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem ImpostorVision; private static OptionItem SpiritMax; public static OptionItem SpiritAbilityCooldown; private static OptionItem SpiritFreezeTime; private static OptionItem SpiritProtectTime; private static OptionItem SpiritCauseVision; private static OptionItem SpiritCauseVisionTime; private static readonly Dictionary PlayersHaunted = new Dictionary(); private long? ProtectTimeStamp = 0L; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(25200, TabGroup.NeutralRoles, CustomRoles.Spiritcaller); KillCooldown = FloatOptionItem.Create(25210, GeneralOption.KillCooldown, new FloatValueRule(0f, 60f, 1f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(25211, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]); ImpostorVision = BooleanOptionItem.Create(25212, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]); SpiritMax = IntegerOptionItem.Create(25213, "SpiritcallerSpiritMax", new IntegerValueRule(1, 15, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Times); SpiritAbilityCooldown = FloatOptionItem.Create(25214, "SpiritcallerSpiritAbilityCooldown", new FloatValueRule(5f, 90f, 1f), 35f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Seconds); SpiritFreezeTime = FloatOptionItem.Create(25215, "SpiritcallerFreezeTime", new FloatValueRule(0f, 30f, 1f), 5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Seconds); SpiritProtectTime = FloatOptionItem.Create(25216, "SpiritcallerProtectTime", new FloatValueRule(0f, 30f, 1f), 5f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Seconds); SpiritCauseVision = FloatOptionItem.Create(25217, "SpiritcallerCauseVision", new FloatValueRule(0f, 5f, 0.05f), 0.2f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Multiplier); SpiritCauseVisionTime = FloatOptionItem.Create(25218, "SpiritcallerCauseVisionTime", new FloatValueRule(0f, 45f, 1f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritcaller]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayersHaunted.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = SpiritMax.GetInt(); ProtectTimeStamp = 0L; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateOthers); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } private bool InProtect(PlayerControl player) { if (player.Is(CustomRoles.Spiritcaller)) { return ProtectTimeStamp > Utils.GetTimeStamp(); } return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(ImpostorVision.GetBool()); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!target.GetCustomRole().IsAbleToBeSidekicked() && !target.GetCustomRole().IsImpostor()) { if (base.AbilityLimit < 1f) { return true; } base.AbilityLimit--; SendSkillRPC(); target.RpcSetCustomRole(CustomRoles.EvilSpirit); CustomRpcSender customRpcSender = CustomRpcSender.Create("SpiritCallerSendMessage", (SendOption)0); customRpcSender.StartMessage(target.GetClientId()); customRpcSender.StartRpc(((InnerNetObject)target).NetId, (byte)6).Write(((InnerNetObject)target.Data).NetId).Write(Translator.GetString("SpiritcallerNoticeTitle")) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)target).NetId, (byte)13).Write(Translator.GetString("SpiritcallerNoticeMessage")).EndRpc(); customRpcSender.StartRpc(((InnerNetObject)target).NetId, (byte)6).Write(((InnerNetObject)target.Data).NetId).Write(target.Data.PlayerName) .EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } return true; } private void OnFixedUpdateOthers(PlayerControl pc) { if (pc.Is(CustomRoles.Spiritcaller)) { if (ProtectTimeStamp < Utils.GetTimeStamp() && ProtectTimeStamp != 0) { ProtectTimeStamp = 0L; } } else if (PlayersHaunted.ContainsKey(pc.PlayerId) && PlayersHaunted[pc.PlayerId] < Utils.GetTimeStamp()) { PlayersHaunted.Remove(pc.PlayerId); pc.MarkDirtySettings(); } } public override string GetProgressText(byte PlayerId, bool cooooms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Spiritcaller) : Color.gray), $"({base.AbilityLimit})"); } public static void HauntPlayer(PlayerControl target) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (SpiritCauseVisionTime.GetFloat() > 0f || SpiritFreezeTime.GetFloat() > 0f) { target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Spiritcaller)), Translator.GetString("HauntedByEvilSpirit"))); } if (SpiritCauseVisionTime.GetFloat() > 0f && !PlayersHaunted.ContainsKey(target.PlayerId)) { long value = Utils.GetTimeStamp() + (long)SpiritCauseVisionTime.GetFloat(); PlayersHaunted.Add(target.PlayerId, value); } if (SpiritFreezeTime.GetFloat() > 0f) { float tmpSpeed = Main.AllPlayerSpeed[target.PlayerId]; Main.AllPlayerSpeed[target.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[target.PlayerId] = false; target.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[target.PlayerId] = Main.AllPlayerSpeed[target.PlayerId] - 0.0001f + tmpSpeed; ReportDeadBodyPatch.CanReport[target.PlayerId] = true; target.MarkDirtySettings(); RPC.PlaySoundRPC(target.PlayerId, Sounds.TaskComplete); }, SpiritFreezeTime.GetFloat(), "Spirit UnFreeze"); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (InProtect(target)) { killer.RpcGuardAndKill(target); target.RpcGuardAndKill(); return false; } return true; } public static void ReduceVision(IGameOptions opt, PlayerControl target) { if (PlayersHaunted.ContainsKey(target.PlayerId)) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, SpiritCauseVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, SpiritCauseVision.GetFloat()); } } public void ProtectSpiritcaller() { ProtectTimeStamp = Utils.GetTimeStamp() + (long)SpiritProtectTime.GetFloat(); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!seer.Is(CustomRoles.Spiritcaller) || !target.Is(CustomRoles.EvilSpirit)) { return ""; } return Main.roleColors[CustomRoles.EvilSpirit]; } } internal class Stalker : RoleBase { private const int Id = 18100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem HasImpostorVision; private static OptionItem CanVent; private static OptionItem CanCountNeutralKiller; public static OptionItem SnatchesWin; private static readonly Dictionary CurrentKillCooldown = new Dictionary(); public static readonly Dictionary IsWinKill = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18100, TabGroup.NeutralRoles, CustomRoles.Stalker); KillCooldown = FloatOptionItem.Create(18110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stalker]).SetValueFormat(OptionFormat.Seconds); HasImpostorVision = BooleanOptionItem.Create(18111, GeneralOption.ImpostorVision, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stalker]); CanVent = BooleanOptionItem.Create(18114, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stalker]); CanCountNeutralKiller = BooleanOptionItem.Create(18112, "CanCountNeutralKiller", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stalker]); SnatchesWin = BooleanOptionItem.Create(18113, GeneralOption.SnatchesWin, defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stalker]); } public override void Init() { playerIdList.Clear(); CurrentKillCooldown.Clear(); IsWinKill.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); CurrentKillCooldown.Add(playerId, KillCooldown.GetFloat()); IsWinKill[playerId] = false; DRpcSetKillCount(Utils.GetPlayerById(playerId)); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public static void ReceiveRPC(MessageReader msg) { byte b = msg.ReadByte(); bool value = msg.ReadBoolean(); if (IsWinKill.ContainsKey(b)) { IsWinKill[b] = value; } else { IsWinKill.Add(b, value: false); } Logger.Info($"Player{b}:ReceiveRPC", "Stalker", escapeCRLF: true, 65, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Stalker.cs"); } private static void DRpcSetKillCount(PlayerControl player) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)194, (SendOption)1, -1); val.Write(player.PlayerId); val.Write(IsWinKill[player.PlayerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = CurrentKillCooldown[id]; } public override bool CanUseKillButton(PlayerControl player) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl Ktarget) { bool flag = Ktarget.GetCustomRole().IsImpostor(); if (CanCountNeutralKiller.GetBool() && !Ktarget.Is(CustomRoles.Arsonist) && !Ktarget.Is(CustomRoles.Revolutionist)) { flag = flag || Ktarget.IsNeutralKiller(); } if (flag && SnatchesWin.GetBool()) { IsWinKill[killer.PlayerId] = true; } DRpcSetKillCount(killer); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)ShipStatus.Instance).NetId, (byte)35, (SendOption)1, killer.GetClientId()); val.Write((byte)7); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)killer); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val2 in allPlayerControls) { if (val2.PlayerId != killer.PlayerId && !val2.Data.Disconnected) { val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)ShipStatus.Instance).NetId, (byte)35, (SendOption)1, val2.GetClientId()); val.Write((byte)7); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)val2); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } return true; } } internal class Sunnyboy : RoleBase { private const int Id = 14400; private static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ScientistCooldown = 0f; AURoleOptions.ScientistBatteryCharge = 60f; } public static bool CheckSpawn() { return IRandom.Instance.Next(0, 100) < Jester.SunnyboyChance.GetInt(); } public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return false; } public static bool CheckGameEnd() { if (CustomRoles.Sunnyboy.RoleExist()) { return Main.AllAlivePlayerControls.Length > 1; } return false; } } internal class Taskinator : RoleBase { private const int Id = 13700; private static OptionItem TaskMarkPerRoundOpt; private static readonly Dictionary> taskIndex = new Dictionary>(); private static readonly Dictionary TaskMarkPerRound = new Dictionary(); private static int maxTasksMarkedPerRound = 0; public static bool HasEnabled => CustomRoles.Taskinator.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override void SetupCustomOption() { Options.SetupRoleOptions(13700, TabGroup.NeutralRoles, CustomRoles.Taskinator); TaskMarkPerRoundOpt = IntegerOptionItem.Create(13710, "TasksMarkPerRound", new IntegerValueRule(1, 14, 1), 3, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Taskinator]).SetValueFormat(OptionFormat.Votes); Options.OverrideTasksData.Create(13711, TabGroup.NeutralRoles, CustomRoles.Taskinator); } public override void Init() { taskIndex.Clear(); TaskMarkPerRound.Clear(); maxTasksMarkedPerRound = TaskMarkPerRoundOpt.GetInt(); } public override void Add(byte playerId) { TaskMarkPerRound[playerId] = 0; } private void SendRPC(byte taskinatorID, int taskIndex = -1, bool isKill = false, bool clearAll = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(taskinatorID); val.Write(taskIndex); val.Write(isKill); val.Write(clearAll); if (!isKill) { val.Write(TaskMarkPerRound[taskinatorID]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); int item = reader.ReadInt32(); bool num = reader.ReadBoolean(); bool flag = reader.ReadBoolean(); if (!num) { int value = reader.ReadInt32(); TaskMarkPerRound[key] = value; if (!flag) { if (!taskIndex.ContainsKey(key)) { taskIndex[key] = new List(); } taskIndex[key].Add(item); } } else if (taskIndex.ContainsKey(key)) { taskIndex[key].Remove(item); } if (flag && taskIndex.ContainsKey(key)) { taskIndex[key].Clear(); } } public override string GetProgressText(byte playerId, bool cooms) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!TaskMarkPerRound.ContainsKey(playerId)) { TaskMarkPerRound[playerId] = 0; } int num = TaskMarkPerRound[playerId]; int value = Math.Max(maxTasksMarkedPerRound - num, 0); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Taskinator).ShadeColor(0.25f)), $"({value})"); } public override void AfterMeetingTasks() { foreach (byte key in TaskMarkPerRound.Keys) { TaskMarkPerRound[key] = 0; if (taskIndex.ContainsKey(key)) { taskIndex[key].Clear(); } SendRPC(key, -1, isKill: false, clearAll: true); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } public override void OnOthersTaskComplete(PlayerControl player, PlayerTask task) { if ((Object)(object)player == (Object)null || (Object)(object)base._Player == (Object)null || !player.IsAlive()) { return; } byte playerId = player.PlayerId; if (player.Is(CustomRoles.Taskinator)) { if (!TaskMarkPerRound.ContainsKey(playerId)) { TaskMarkPerRound[playerId] = 0; } if (TaskMarkPerRound[playerId] >= maxTasksMarkedPerRound) { TaskMarkPerRound[playerId] = maxTasksMarkedPerRound; Logger.Info($"Max task per round ({TaskMarkPerRound[playerId]}) reached for {player.GetNameWithRole()}", "Taskinator", escapeCRLF: true, 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Taskinator.cs"); return; } TaskMarkPerRound[playerId]++; if (!taskIndex.ContainsKey(playerId)) { taskIndex[playerId] = new List(); } taskIndex[playerId].Add(task.Index); SendRPC(playerId, task.Index); player.Notify(Translator.GetString("TaskinatorBombPlanted")); } else { if (!base._Player.RpcCheckAndMurder(player, check: true)) { return; } foreach (byte key in taskIndex.Keys) { if (taskIndex[key].Contains(task.Index)) { PlayerControl playerById = Utils.GetPlayerById(key); if (!((Object)(object)playerById == (Object)null)) { player.SetDeathReason(PlayerState.DeathReason.Bombed); player.RpcMurderPlayer(player); player.SetRealKiller(playerById); taskIndex[key].Remove(task.Index); SendRPC(key, task.Index, isKill: true); Logger.Info(player.GetAllRoleName() + " died because of " + playerById.GetNameWithRole(), "Taskinator", escapeCRLF: true, 141, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Taskinator.cs"); } } } } } } internal class Terrorist : RoleBase { private const int id = 15400; private static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled = PlayerIds.Any(); public static OptionItem CanTerroristSuicideWin; public static OptionItem TerroristCanGuess; public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override void SetupCustomOption() { Options.SetupRoleOptions(15400, TabGroup.NeutralRoles, CustomRoles.Terrorist); CanTerroristSuicideWin = BooleanOptionItem.Create(15402, "CanTerroristSuicideWin", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Terrorist]); TerroristCanGuess = BooleanOptionItem.Create(15403, GeneralOption.CanGuess, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Terrorist]); Options.OverrideTasksData.Create(15404, TabGroup.NeutralRoles, CustomRoles.Terrorist); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { object obj; if (target == null) { obj = null; } else { NetworkedPlayerInfo data = target.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.Info((string?)obj + " was Terrorist", "AfterPlayerDeathTasks", escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Terrorist.cs"); CheckTerroristWin(target.Data); } public override void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { CheckTerroristWin(exiled); } private static void CheckTerroristWin(NetworkedPlayerInfo terrorist) { if (!Utils.GetPlayerById(terrorist.PlayerId).GetPlayerTaskState().IsTaskFinished || (Main.PlayerStates[terrorist.PlayerId].IsSuicide && !CanTerroristSuicideWin.GetBool())) { return; } if (!CustomWinnerHolder.CheckForConvertedWinner(terrorist.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Terrorist); CustomWinnerHolder.WinnerIds.Add(terrorist.PlayerId); } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (val.Is(CustomRoles.Terrorist)) { if (Main.PlayerStates[val.PlayerId].deathReason == PlayerState.DeathReason.Vote) { val.SetDeathReason(PlayerState.DeathReason.etc); } else { val.SetDeathReason(PlayerState.DeathReason.Suicide); } } else if (!val.Data.IsDead) { val.SetDeathReason(PlayerState.DeathReason.Bombed); Main.PlayerStates[val.PlayerId].SetDead(); val.RpcMurderPlayer(val); val.SetRealKiller(terrorist.Object); } } } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (!TerroristCanGuess.GetBool()) { Logger.Info($"Guess Disabled for this player {guesser.PlayerId}", "GuessManager", escapeCRLF: true, 92, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Terrorist.cs"); guesser.ShowInfoMessage(isUI, Translator.GetString("GuessDisabled")); return true; } return false; } } internal class Traitor : RoleBase { private const int Id = 18200; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem CanUsesSabotage; private static OptionItem KnowMadmate; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18200, TabGroup.NeutralRoles, CustomRoles.Traitor); KillCooldown = FloatOptionItem.Create(18210, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Traitor]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(18211, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Traitor]); HasImpostorVision = BooleanOptionItem.Create(18213, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Traitor]); CanUsesSabotage = BooleanOptionItem.Create(18215, GeneralOption.CanUseSabotage, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Traitor]); KnowMadmate = BooleanOptionItem.Create(18216, "TraitorKnowMadmate", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Traitor]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool CanUseSabotage(PlayerControl pc) { return CanUsesSabotage.GetBool(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!((Object)(object)target == (Object)(object)killer)) { return !target.Is(Custom_Team.Impostor); } return false; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (target.Is(Custom_Team.Impostor)) { return Main.roleColors[CustomRoles.Impostor]; } if (target.Is(CustomRoles.Madmate) && KnowMadmate.GetBool()) { return "BB0F0F"; } return string.Empty; } } internal class Vector : RoleBase { private const int Id = 15500; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem VectorVentNumWin; private static OptionItem VectorVentCD; private static readonly Dictionary VectorVentCount = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override void SetupCustomOption() { Options.SetupRoleOptions(15500, TabGroup.NeutralRoles, CustomRoles.Vector); VectorVentNumWin = IntegerOptionItem.Create(15502, "VectorVentNumWin", new IntegerValueRule(5, 500, 5), 40, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vector]).SetValueFormat(OptionFormat.Times); VectorVentCD = FloatOptionItem.Create(15503, GeneralOption.EngineerBase_VentCooldown, new FloatValueRule(0f, 180f, 1f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vector]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { VectorVentCount.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { VectorVentCount.Add(playerId, 0); PlayerIds.Add(playerId); } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(VectorVentCount[base._Player.PlayerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { int value = reader.ReadInt32(); VectorVentCount[base._Player.PlayerId] = value; } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Vector).ShadeColor(0.25f)), $"({(VectorVentCount.TryGetValue(playerId, out value) ? value : 0)}/{VectorVentNumWin.GetInt()})"); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VectorVentCD.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override void OnEnterVent(PlayerControl pc, Vent vent) { VectorVentCount.TryAdd(pc.PlayerId, 0); VectorVentCount[pc.PlayerId]++; SendRPC(); Utils.NotifyRoles(pc); if (VectorVentCount[pc.PlayerId] >= VectorVentNumWin.GetInt() && !CustomWinnerHolder.CheckForConvertedWinner(pc.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Vector); CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); } } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Happy"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("VectorVentButtonText")); ((ActionButton)hud.AbilityButton).SetUsesRemaining(VectorVentNumWin.GetInt() - (VectorVentCount.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var value) ? value : 0)); } } internal class Virus : RoleBase { private enum ContagiousCountModeSelectList { Virus_ContagiousCountMode_None, Virus_ContagiousCountMode_Virus, Virus_ContagiousCountMode_Original } private const int Id = 18300; private static OptionItem KillCooldown; private static OptionItem InfectMax; private static OptionItem CanVent; private static OptionItem ImpostorVision; private static OptionItem KnowTargetRole; public static OptionItem TargetKnowOtherTarget; private static OptionItem KillInfectedPlayerAfterMeeting; public static OptionItem ContagiousCountMode; private static readonly HashSet InfectedBodies = new HashSet(); private static readonly HashSet InfectedPlayer = new HashSet(); private static readonly Dictionary VirusNotify = new Dictionary(); public static bool HasEnabled => CustomRoles.Virus.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18300, TabGroup.NeutralRoles, CustomRoles.Virus); KillCooldown = FloatOptionItem.Create(18310, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(18311, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); ImpostorVision = BooleanOptionItem.Create(18316, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); InfectMax = IntegerOptionItem.Create(18319, "VirusInfectMax", new IntegerValueRule(1, 15, 1), 5, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]).SetValueFormat(OptionFormat.Times); KnowTargetRole = BooleanOptionItem.Create(18313, "VirusKnowTargetRole", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); TargetKnowOtherTarget = BooleanOptionItem.Create(18314, "VirusTargetKnowOtherTarget", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); KillInfectedPlayerAfterMeeting = BooleanOptionItem.Create(18315, "VirusKillInfectedPlayerAfterMeeting", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); ContagiousCountMode = StringOptionItem.Create(18318, "Virus_ContagiousCountMode", EnumHelper.GetAllNames(), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Virus]); } public override void Init() { InfectedBodies.Clear(); VirusNotify.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = InfectMax.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void OnOthersMeetingHudStart(PlayerControl pc) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (VirusNotify.ContainsKey(pc.PlayerId)) { MeetingHudStartPatch.AddMsg(VirusNotify[pc.PlayerId], pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Virus)), Translator.GetString("VirusNoticeTitle"))); } } public override void MeetingHudClear() { VirusNotify.Clear(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(ImpostorVision.GetBool()); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (base.AbilityLimit < 1f) { return true; } InfectedBodies.Add(target.PlayerId); return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (!((Object)(object)target == (Object)null) && InfectedBodies.Contains(target.PlayerId) && !((Object)(object)reporter == (Object)null) && reporter.CanBeInfected()) { base.AbilityLimit--; SendSkillRPC(); if (KillInfectedPlayerAfterMeeting.GetBool()) { InfectedPlayer.Add(reporter.PlayerId); VirusNotify.Add(reporter.PlayerId, Translator.GetString("VirusNoticeMessage2")); } else { reporter.RpcSetCustomRole(CustomRoles.Contagious); VirusNotify.Add(reporter.PlayerId, Translator.GetString("VirusNoticeMessage")); } string[] obj = new string[6] { "Setting up a career:", null, null, null, null, null }; object obj2; if (reporter == null) { obj2 = null; } else { NetworkedPlayerInfo data = reporter.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = reporter.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Contagious.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Contagious, escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Virus.cs"); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public static void OnCheckForEndVoting(PlayerState.DeathReason deathReason, params byte[] exileIds) { if (!KillInfectedPlayerAfterMeeting.GetBool()) { return; } PlayerControl val = ((IEnumerable)Main.AllAlivePlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.GetCustomRole() == CustomRoles.Virus)); if ((Object)(object)val == (Object)null || deathReason != PlayerState.DeathReason.Vote) { return; } if (exileIds.Contains(val.PlayerId)) { InfectedPlayer.Clear(); return; } List list = new List(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (!InfectedPlayer.Contains(val2.PlayerId)) { continue; } if (val.IsAlive()) { if (!Main.AfterMeetingDeathPlayers.ContainsKey(val2.PlayerId)) { val2.SetRealKiller(val); list.Add(val2.PlayerId); } } else { Main.AfterMeetingDeathPlayers.Remove(val2.PlayerId); } } int i = 0; byte[] array = new byte[list.Count]; foreach (byte item in list) { array[i] = item; i++; } CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Infected, array); RemoveInfectedPlayer(val); } private static void RemoveInfectedPlayer(PlayerControl virus) { InfectedPlayer.Clear(); } public static bool KnowRole(PlayerControl player, PlayerControl target) { if (player.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Virus)) { return true; } if (KnowTargetRole.GetBool() && player.Is(CustomRoles.Virus) && target.Is(CustomRoles.Contagious)) { return true; } if (TargetKnowOtherTarget.GetBool() && player.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Contagious)) { return true; } return false; } public static string KnowRoleColor(PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Virus)) { return Main.roleColors[CustomRoles.Virus]; } if (seer.Is(CustomRoles.Virus) && target.Is(CustomRoles.Contagious)) { return Main.roleColors[CustomRoles.Contagious]; } if (seer.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Contagious) && TargetKnowOtherTarget.GetBool()) { return Main.roleColors[CustomRoles.Virus]; } return ""; } public override string GetProgressText(byte id, bool coooms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Virus).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } public static class VirusPlayerControls { public static bool CanBeInfected(this PlayerControl pc) { if (!pc.Is(CustomRoles.Virus) && !pc.Is(CustomRoles.Contagious) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Cultist) && !pc.Is(CustomRoles.Infectious) && !pc.Is(CustomRoles.Specter)) { if (pc.GetCustomSubRoles().Contains(CustomRoles.Hurried)) { return Hurried.CanBeConverted.GetBool(); } return true; } return false; } } internal class Vulture : RoleBase { private const int Id = 15600; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ArrowsPointingToDeadBody; private static OptionItem NumberOfReportsToWin; private static OptionItem CanVent; private static OptionItem VultureReportCD; private static OptionItem MaxEaten; private static OptionItem HasImpVision; private static readonly HashSet UnreportablePlayers = new HashSet(); private static readonly Dictionary BodyReportCount = new Dictionary(); private static readonly Dictionary AbilityLeftInRound = new Dictionary(); private static readonly Dictionary LastReport = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase { get { if (!CanVent.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override Sprite ReportButtonSprite => CustomButton.Get("Eat"); public override void SetupCustomOption() { Options.SetupRoleOptions(15600, TabGroup.NeutralRoles, CustomRoles.Vulture); ArrowsPointingToDeadBody = BooleanOptionItem.Create(15610, "VultureArrowsPointingToDeadBody", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]); NumberOfReportsToWin = IntegerOptionItem.Create(15611, "VultureNumberOfReportsToWin", new IntegerValueRule(1, 14, 1), 5, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]); CanVent = BooleanOptionItem.Create(15612, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]); VultureReportCD = FloatOptionItem.Create(15613, "VultureReportCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]).SetValueFormat(OptionFormat.Seconds); MaxEaten = IntegerOptionItem.Create(15614, "VultureMaxEatenInOneRound", new IntegerValueRule(1, 14, 1), 1, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]); HasImpVision = BooleanOptionItem.Create(15615, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vulture]); } public override void Init() { playerIdList.Clear(); UnreportablePlayers.Clear(); BodyReportCount.Clear(); AbilityLeftInRound.Clear(); LastReport.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); BodyReportCount[playerId] = 0; AbilityLeftInRound[playerId] = MaxEaten.GetInt(); LastReport[playerId] = Utils.GetTimeStamp(); if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); new LateTask(delegate { if (GameStates.IsInTask) { if (!Options.DisableShieldAnimations.GetBool()) { Utils.GetPlayerById(playerId).RpcGuardAndKill(Utils.GetPlayerById(playerId)); } Utils.GetPlayerById(playerId).Notify(Translator.GetString("VultureCooldownUp")); } }, VultureReportCD.GetFloat() + 8f, "Vulture Cooldown Up In Start"); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpVision.GetBool()); AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } private static void SendRPC(byte playerId, bool add, Vector3 loc = default(Vector3)) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)185, (SendOption)1, -1); val.Write(playerId); val.Write(add); if (add) { val.Write(loc.x); val.Write(loc.y); val.Write(loc.z); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } private static void SendBodyRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)187, (SendOption)1, -1); val.Write(playerId); val.Write(BodyReportCount[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte seer = reader.ReadByte(); if (reader.ReadBoolean()) { LocateArrow.Add(seer, new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); } else { LocateArrow.RemoveAllTarget(seer); } } public static void ReceiveBodyRPC(MessageReader reader) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); if (!BodyReportCount.ContainsKey(key)) { BodyReportCount.Add(key, value); } else { BodyReportCount[key] = value; } } public override void OnFixedUpdateLowLoad(PlayerControl player) { if (player.IsAlive() && BodyReportCount[player.PlayerId] >= NumberOfReportsToWin.GetInt()) { BodyReportCount[player.PlayerId] = NumberOfReportsToWin.GetInt(); if (!CustomWinnerHolder.CheckForConvertedWinner(player.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Vulture); CustomWinnerHolder.WinnerIds.Add(player.PlayerId); } } } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (UnreportablePlayers.Contains(deadBody.PlayerId)) { return false; } if (reporter.Is(CustomRoles.Vulture)) { byte playerId = reporter.PlayerId; long timeStamp = Utils.GetTimeStamp(); if (AbilityLeftInRound[playerId] > 0 && timeStamp - LastReport[playerId] > (long)VultureReportCD.GetFloat()) { LastReport[playerId] = timeStamp; OnEatDeadBody(reporter, deadBody); reporter.RpcGuardAndKill(reporter); reporter.Notify(Translator.GetString("VultureReportBody")); if (AbilityLeftInRound[playerId] > 0) { new LateTask(delegate { if (GameStates.IsInTask) { if (!Options.DisableShieldAnimations.GetBool()) { reporter.RpcGuardAndKill(reporter); } reporter.Notify(Translator.GetString("VultureCooldownUp")); } }, VultureReportCD.GetFloat(), "Vulture CD"); } Logger.Info(reporter.GetRealName() + " ate " + deadBody.PlayerName + " corpse", "Vulture", escapeCRLF: true, 167, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Vulture.cs"); return false; } } return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (byte playerId in playerIdList) { LocateArrow.RemoveAllTarget(playerId); SendRPC(playerId, add: false); } } private static void OnEatDeadBody(PlayerControl pc, NetworkedPlayerInfo target) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) BodyReportCount[pc.PlayerId]++; AbilityLeftInRound[pc.PlayerId]--; Logger.Msg($"target is null? {(Object)(object)target == (Object)null}", "VultureNull", escapeCRLF: true, 185, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Vulture.cs"); if ((Object)(object)target != (Object)null) { foreach (byte playerId in playerIdList) { LocateArrow.Remove(playerId, ((Component)target.Object).transform.position); SendRPC(playerId, add: false); } } SendBodyRPC(pc.PlayerId); pc.Notify(Translator.GetString("VultureBodyReported")); UnreportablePlayers.Remove(target.PlayerId); UnreportablePlayers.Add(target.PlayerId); } public override void AfterMeetingTasks() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) foreach (byte playerId in playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null)) { if (playerById.IsAlive()) { AbilityLeftInRound[playerId] = MaxEaten.GetInt(); LastReport[playerId] = Utils.GetTimeStamp(); SendRPC(playerId, add: false); } SendBodyRPC(playerById.PlayerId); } } } public override void NotifyAfterMeeting() { foreach (byte apc in playerIdList) { PlayerControl player = Utils.GetPlayerById(apc); if ((Object)(object)player == (Object)null) { continue; } new LateTask(delegate { if (GameStates.IsInTask && player.IsAlive()) { if (!Options.DisableShieldAnimations.GetBool()) { player.RpcGuardAndKill(Utils.GetPlayerById(apc)); } player.Notify(Translator.GetString("VultureCooldownUp")); } }, VultureReportCD.GetFloat(), "Vulture Cooldown Up After Meeting"); SendBodyRPC(player.PlayerId); } } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (inMeeting || target.IsDisconnected() || !ArrowsPointingToDeadBody.GetBool()) { return; } Vector2 val = Vector2.op_Implicit(((Component)target).transform.position); float num = float.MaxValue; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (val2.PlayerId != target.PlayerId) { float num2 = Vector2.Distance(Vector2.op_Implicit(((Component)val2).transform.position), val); if (num2 < num && num2 < 1.5f) { num = num2; } } } byte[] array = playerIdList.ToArray(); foreach (byte b in array) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { LocateArrow.Add(b, ((Component)target).transform.position); SendRPC(b, add: true, ((Component)target).transform.position); } } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seer == (Object)null || isForMeeting) { return string.Empty; } if (!seer.Is(CustomRoles.Vulture)) { return string.Empty; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Color.white), LocateArrow.GetArrows(seer)); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("VultureEatButtonText")); } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Vulture).ShadeColor(0.25f)), $"({(BodyReportCount.TryGetValue(playerId, out value) ? value : 0)}/{NumberOfReportsToWin.GetInt()})"); } } internal class Werewolf : RoleBase { private const int Id = 18400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem MaulRadius; private static OptionItem CanVent; private static OptionItem HasImpostorVision; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18400, TabGroup.NeutralRoles, CustomRoles.Werewolf); KillCooldown = FloatOptionItem.Create(18409, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 35f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Werewolf]).SetValueFormat(OptionFormat.Seconds); MaulRadius = FloatOptionItem.Create(18414, "MaulRadius", new FloatValueRule(0.5f, 1.5f, 0.1f), 1.3f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Werewolf]).SetValueFormat(OptionFormat.Multiplier); CanVent = BooleanOptionItem.Create(18411, GeneralOption.CanVent, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Werewolf]); HasImpostorVision = BooleanOptionItem.Create(18413, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Werewolf]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("WerewolfKillButtonText")); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CanVent.GetBool(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { Logger.Info("Werewolf Kill", "Mauled", escapeCRLF: true, 55, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Werewolf.cs"); new LateTask(delegate { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!((Object)(object)val == (Object)(object)killer) && !((Object)(object)val == (Object)(object)target) && !val.Is(CustomRoles.Pestilence) && ((!val.Is(CustomRoles.NiceMini) && !val.Is(CustomRoles.EvilMini)) || Mini.Age >= 18) && Vector2.Distance(Vector2.op_Implicit(((Component)killer).transform.position), Vector2.op_Implicit(((Component)val).transform.position)) <= MaulRadius.GetFloat()) { val.SetDeathReason(PlayerState.DeathReason.Mauled); val.RpcMurderPlayer(val); val.SetRealKiller(killer); } } }, 0.1f, "Werewolf Maul Bug Fix"); return true; } } internal class Workaholic : RoleBase { private const int Id = 15800; private static readonly HashSet PlayerIds = new HashSet(); public static OptionItem WorkaholicCannotWinAtDeath; public static OptionItem WorkaholicVentCooldown; public static OptionItem WorkaholicVisibleToEveryone; public static OptionItem WorkaholicGiveAdviceAlive; public static OptionItem WorkaholicCanGuess; public static readonly HashSet WorkaholicAlive = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { return !ForRecompute; } public override void SetupCustomOption() { Options.SetupRoleOptions(15700, TabGroup.NeutralRoles, CustomRoles.Workaholic); WorkaholicCannotWinAtDeath = BooleanOptionItem.Create(15702, "WorkaholicCannotWinAtDeath", defaultValue: false, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workaholic]); WorkaholicVentCooldown = FloatOptionItem.Create(15703, GeneralOption.EngineerBase_VentCooldown, new FloatValueRule(0f, 180f, 2.5f), 0f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workaholic]).SetValueFormat(OptionFormat.Seconds); WorkaholicVisibleToEveryone = BooleanOptionItem.Create(15704, "WorkaholicVisibleToEveryone", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workaholic]); WorkaholicGiveAdviceAlive = BooleanOptionItem.Create(15705, "WorkaholicGiveAdviceAlive", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(WorkaholicVisibleToEveryone); WorkaholicCanGuess = BooleanOptionItem.Create(15706, GeneralOption.CanGuess, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workaholic]); Options.OverrideTasksData.Create(15707, TabGroup.NeutralRoles, CustomRoles.Workaholic); } public override void Init() { WorkaholicAlive.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public static bool OthersKnowWorka(PlayerControl target) { if (WorkaholicVisibleToEveryone.GetBool()) { return target.Is(CustomRoles.Workaholic); } return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = WorkaholicVentCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 0f; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { int count = player.Data.Tasks.Count; if (completedTaskCount < count || (WorkaholicCannotWinAtDeath.GetBool() && !player.IsAlive())) { return true; } Logger.Info("The Workaholic task is done", "Workaholic", escapeCRLF: true, 68, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Workaholic.cs"); if (!CustomWinnerHolder.CheckForConvertedWinner(player.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Workaholic); CustomWinnerHolder.WinnerIds.Add(player.PlayerId); } RPC.PlaySoundRPC(player.PlayerId, Sounds.KillSound); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (val.PlayerId != player.PlayerId) { Main.PlayerStates[val.PlayerId].deathReason = ((val.PlayerId == player.PlayerId) ? PlayerState.DeathReason.Overtired : PlayerState.DeathReason.Ashamed); val.RpcMurderPlayer(val); val.SetRealKiller(player); } } return true; } public override void OnMeetingHudStart(PlayerControl player) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Invalid comparison between Unknown and I4 //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (MeetingStates.FirstMeeting && player.IsAlive() && WorkaholicGiveAdviceAlive.GetBool() && !WorkaholicCannotWinAtDeath.GetBool() && !Options.GhostIgnoreTasks.GetBool()) { PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Workaholic)).ToArray(); foreach (PlayerControl val in array) { WorkaholicAlive.Add(val.PlayerId); } List list = new List(); byte[] array2 = WorkaholicAlive.ToArray(); foreach (byte key in array2) { list.Add(Main.AllPlayerNames[key]); } SupportedLangs languageID = DestroyableSingleton.Instance.currentLanguage.languageID; bool flag = (((int)languageID == 0 || (int)languageID == 5) ? true : false); string separator = (flag ? "], [" : "】, 【"); MeetingHudStartPatch.AddMsg(string.Format(Translator.GetString("WorkaholicAdviceAlive"), string.Join(separator, list)), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Workaholic)), Translator.GetString("WorkaholicAliveTitle"))); } } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (WorkaholicVisibleToEveryone.GetBool()) { if (!isUI) { Utils.SendMessage(Translator.GetString("GuessWorkaholic"), pc.PlayerId); } else { pc.ShowPopUp(Translator.GetString("GuessWorkaholic")); } return true; } return false; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (!WorkaholicCanGuess.GetBool()) { Logger.Info($"Guess Disabled for this player {guesser.PlayerId}", "GuessManager", escapeCRLF: true, 122, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Neutral\\Workaholic.cs"); guesser.ShowInfoMessage(isUI, Translator.GetString("GuessDisabled")); return true; } return false; } } internal class Wraith : RoleBase { private const int Id = 18500; private static OptionItem WraithCooldown; private static OptionItem WraithDuration; private static OptionItem WraithVentNormallyOnCooldown; private static OptionItem HasImpostorVision; private static Dictionary InvisTime = new Dictionary(); private static readonly Dictionary lastTime = new Dictionary(); private static readonly Dictionary ventedId = new Dictionary(); private static long lastFixedTime = 0L; public static bool HasEnabled => CustomRoles.Wraith.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(18500, TabGroup.NeutralRoles, CustomRoles.Wraith); WraithCooldown = FloatOptionItem.Create(18502, "WraithCooldown", new FloatValueRule(1f, 180f, 1f), 30f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wraith]).SetValueFormat(OptionFormat.Seconds); WraithDuration = FloatOptionItem.Create(18504, "WraithDuration", new FloatValueRule(1f, 60f, 1f), 15f, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wraith]).SetValueFormat(OptionFormat.Seconds); WraithVentNormallyOnCooldown = BooleanOptionItem.Create(18505, "WraithVentNormallyOnCooldown", defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wraith]); HasImpostorVision = BooleanOptionItem.Create(18506, GeneralOption.ImpostorVision, defaultValue: true, TabGroup.NeutralRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wraith]); } public override void Init() { InvisTime.Clear(); lastTime.Clear(); ventedId.Clear(); } public override void Add(byte playerId) { if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private void SendRPC(PlayerControl pc) { if (!((InnerNetObject)pc).AmOwner) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, pc.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write((InvisTime.TryGetValue(pc.PlayerId, out var value) ? value : (-1)).ToString()); val.Write((lastTime.TryGetValue(pc.PlayerId, out var value2) ? value2 : (-1)).ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { InvisTime.Clear(); lastTime.Clear(); long num = long.Parse(reader.ReadString()); long num2 = long.Parse(reader.ReadString()); if (num > 0) { InvisTime.Add(PlayerControl.LocalPlayer.PlayerId, num); } if (num2 > 0) { lastTime.Add(PlayerControl.LocalPlayer.PlayerId, num2); } } private static bool CanGoInvis(byte id) { if (GameStates.IsInTask && !InvisTime.ContainsKey(id)) { return !lastTime.ContainsKey(id); } return false; } private static bool IsInvis(byte id) { return InvisTime.ContainsKey(id); } public override void OnReportDeadBody(PlayerControl pa, NetworkedPlayerInfo dum) { byte[] array = base._playerIdList.ToArray(); foreach (byte b in array) { if (!IsInvis(b)) { continue; } PlayerControl playerById = Utils.GetPlayerById(b); if ((Object)(object)playerById == (Object)null) { continue; } if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(b, out var value) ? value : Main.LastEnteredVent[b].Id); } } InvisTime.Remove(b); ventedId.Remove(b); SendRPC(playerById); } lastTime.Clear(); InvisTime.Clear(); ventedId.Clear(); } public override void AfterMeetingTasks() { lastTime.Clear(); InvisTime.Clear(); foreach (byte playerId in base._playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (playerById.IsAlive()) { lastTime.Add(playerById.PlayerId, Utils.GetTimeStamp()); SendRPC(playerById); } } } public override void OnFixedUpdateLowLoad(PlayerControl player) { long timeStamp = Utils.GetTimeStamp(); if (lastTime.TryGetValue(player.PlayerId, out var value) && value + (long)WraithCooldown.GetFloat() < timeStamp) { lastTime.Remove(player.PlayerId); if (!player.IsModClient()) { player.Notify(Translator.GetString("WraithCanVent")); } SendRPC(player); } if (lastFixedTime == timeStamp) { return; } lastFixedTime = timeStamp; Dictionary newList = new Dictionary(); List refreshList = new List(); foreach (KeyValuePair item in InvisTime) { PlayerControl playerById = Utils.GetPlayerById(item.Key); if ((Object)(object)playerById == (Object)null) { continue; } long num = item.Value + (long)WraithDuration.GetFloat() - timeStamp; if (num < 0 || !playerById.IsAlive()) { lastTime.Add(playerById.PlayerId, timeStamp); if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(playerById.PlayerId, out var value2) ? value2 : Main.LastEnteredVent[playerById.PlayerId].Id); } } ventedId.Remove(playerById.PlayerId); playerById.Notify(Translator.GetString("WraithInvisStateOut")); SendRPC(playerById); } else { if (num <= 10 && !playerById.IsModClient()) { playerById.Notify(string.Format(Translator.GetString("WraithInvisStateCountdown"), num + 1)); } newList.Add(item.Key, item.Value); } } CollectionExtensions.Do>(InvisTime.Where((KeyValuePair x) => !newList.ContainsKey(x.Key)), (Action>)delegate(KeyValuePair x) { refreshList.Add(x.Key); }); InvisTime = newList; CollectionExtensions.Do((IEnumerable)refreshList, (Action)delegate(byte x) { SendRPC(Utils.GetPlayerById(x)); }); } public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) { PlayerControl pc = __instance.myPlayer; if (!((InnerNetClient)AmongUsClient.Instance).AmHost || IsInvis(pc.PlayerId)) { return; } new LateTask(delegate { if (CanGoInvis(pc.PlayerId)) { ventedId.Remove(pc.PlayerId); ventedId.Add(pc.PlayerId, ventId); __instance.RpcBootFromVentDesync(ventId, pc); InvisTime.Add(pc.PlayerId, Utils.GetTimeStamp()); SendRPC(pc); pc.Notify(Translator.GetString("WraithInvisState"), WraithDuration.GetFloat()); } else if (!WraithVentNormallyOnCooldown.GetBool()) { __instance.myPlayer.MyPhysics.RpcBootFromVent(ventId); pc.Notify(Translator.GetString("WraithInvisInCooldown")); } }, 0.8f, "Wraith Vent"); } public override void ApplyGameOptions(IGameOptions opt, byte id) { opt.SetVision(HasImpostorVision.GetBool()); } public override bool CanUseKillButton(PlayerControl pc) { return pc.IsAlive(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return true; } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (!IsInvis(pc.PlayerId)) { return; } InvisTime.Remove(pc.PlayerId); lastTime.Add(pc.PlayerId, Utils.GetTimeStamp()); SendRPC(pc); if (pc != null) { PlayerPhysics myPhysics = pc.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(vent.Id); } } pc.Notify(Translator.GetString("WraithInvisStateOut")); } public override string GetLowerText(PlayerControl pc, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)pc == (Object)null || !GameStates.IsInTask || !PlayerControl.LocalPlayer.IsAlive()) { return ""; } StringBuilder stringBuilder = new StringBuilder(); long value; if (IsInvis(pc.PlayerId)) { long num = InvisTime[pc.PlayerId] + (long)WraithDuration.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("WraithInvisStateCountdown"), num + 1)); } else if (lastTime.TryGetValue(pc.PlayerId, out value)) { long num2 = value + (long)WraithCooldown.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("WraithInvisCooldownRemain"), num2 + 1)); } else { stringBuilder.Append(Translator.GetString("WraithCanVent")); } return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText")); ((ActionButton)hud.ImpostorVentButton).OverrideText(Translator.GetString(IsInvis(PlayerControl.LocalPlayer.PlayerId) ? "WraithRevertVentButtonText" : "WraithVentButtonText")); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!IsInvis(killer.PlayerId)) { return true; } killer.RpcGuardAndKill(target); killer.SetKillCooldown(); target.RpcMurderPlayer(target); target.SetRealKiller(killer); return false; } public override Sprite ImpostorVentButtonSprite(PlayerControl player) { return CustomButton.Get("invisible"); } } } namespace TOHE.Roles.Impostor { internal class Anonymous : RoleBase { private const int Id = 5300; private static OptionItem HackLimitOpt; private static OptionItem KillCooldown; private static readonly List DeadBodyList = new List(); public static bool HasEnabled => CustomRoles.Anonymous.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Hack"); } public override void SetupCustomOption() { Options.SetupRoleOptions(5300, TabGroup.ImpostorRoles, CustomRoles.Anonymous); KillCooldown = FloatOptionItem.Create(5302, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Anonymous]).SetValueFormat(OptionFormat.Seconds); HackLimitOpt = IntegerOptionItem.Create(5304, "HackLimit", new IntegerValueRule(1, 15, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Anonymous]).SetValueFormat(OptionFormat.Times); } public override void Init() { DeadBodyList.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = HackLimitOpt.GetInt(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = 1f; AURoleOptions.ShapeshifterDuration = 1f; } public override string GetProgressText(byte playerId, bool coomsd) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Anonymous).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); if (base.AbilityLimit > 0f) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("AnonymousShapeshiftText")); ((ActionButton)hud.AbilityButton).SetUsesRemaining((int)base.AbilityLimit); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { DeadBodyList.Clear(); } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!(inMeeting || isSuicide) && (Object)(object)target != (Object)null && !DeadBodyList.Contains(target.PlayerId)) { DeadBodyList.Add(target.PlayerId); } } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl ssTarget, bool IsAnimate, bool shapeshifting) { if (!shapeshifting || base.AbilityLimit <= 0f || (Object)(object)ssTarget == (Object)null || ssTarget.Is(CustomRoles.LazyGuy) || ssTarget.Is(CustomRoles.Lazy) || (ssTarget.Is(CustomRoles.NiceMini) && Mini.Age < 18)) { return; } base.AbilityLimit--; SendSkillRPC(); byte targetId = byte.MaxValue; foreach (byte deadBody in DeadBodyList) { PlayerControl playerById = Utils.GetPlayerById(deadBody); if (!((Object)(object)playerById == (Object)null) && !((Object)(object)playerById.GetRealKiller() == (Object)null) && playerById.GetRealKiller().PlayerId == shapeshifter.PlayerId) { targetId = deadBody; } } if (targetId == byte.MaxValue && DeadBodyList.Any()) { targetId = DeadBodyList[IRandom.Instance.Next(0, DeadBodyList.Count)]; } if (targetId == byte.MaxValue) { new LateTask(delegate { PlayerControl obj2 = ssTarget; if (obj2 != null) { PlayerControl obj3 = ssTarget; obj2.NoCheckStartMeeting((obj3 != null) ? obj3.Data : null); } }, 0.15f, "Anonymous Hacking Report Self"); return; } new LateTask(delegate { PlayerControl obj = ssTarget; if (obj != null) { PlayerControl playerById2 = Utils.GetPlayerById(targetId); obj.NoCheckStartMeeting((playerById2 != null) ? playerById2.Data : null); } }, 0.15f, "Anonymous Hacking Report"); } } internal class AntiAdminer : RoleBase { private const int Id = 2800; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem CanCheckCamera; private static bool IsAdminWatch; private static bool IsVitalWatch; private static bool IsDoorLogWatch; private static bool IsCameraWatch; private static int Count = 0; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(2800, TabGroup.ImpostorRoles, CustomRoles.AntiAdminer); CanCheckCamera = BooleanOptionItem.Create(2810, "CanCheckCamera", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.AntiAdminer]); } public override void Init() { playerIdList.Clear(); IsAdminWatch = false; IsVitalWatch = false; IsDoorLogWatch = false; IsCameraWatch = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public override void OnFixedUpdateLowLoad(PlayerControl player) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) Count--; if (Count > 0) { return; } Count = 3; bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (Pelican.IsEaten(val.PlayerId) || val.inVent || val.GetCustomRole().IsImpostor()) { continue; } try { Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position); byte activeMapId = Utils.GetActiveMapId(); MapNames map = (MapNames)activeMapId; switch (activeMapId) { case 0: if (!Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["SkeldAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableSkeldCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["SkeldCamera"]) <= DisableDevice.UsableDistance(map); } break; case 1: if (!Options.DisableMiraHQAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["MiraHQAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableMiraHQDoorLog.GetBool()) { flag3 |= Vector2.Distance(val2, DisableDevice.DevicePos["MiraHQDoorLog"]) <= DisableDevice.UsableDistance(map); } break; case 2: if (!Options.DisablePolusAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusLeftAdmin"]) <= DisableDevice.UsableDistance(map); flag |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusRightAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisablePolusCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisablePolusVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusVital"]) <= DisableDevice.UsableDistance(map); } break; case 3: if (!Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["DleksAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableSkeldCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["DleksCamera"]) <= DisableDevice.UsableDistance(map); } break; case 4: if (!Options.DisableAirshipCockpitAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipCockpitAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipRecordsAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipRecordsAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipVital"]) <= DisableDevice.UsableDistance(map); } break; case 5: if (!Options.DisableFungleBinoculars.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["FungleCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableFungleVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["FungleVital"]) <= DisableDevice.UsableDistance(map); } break; } } catch (Exception ex) { Logger.Error(ex.ToString(), "AntiAdmin", escapeCRLF: true, 119, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\AntiAdminer.cs"); } } bool flag5 = false; flag5 |= IsAdminWatch != flag; IsAdminWatch = flag; flag5 |= IsVitalWatch != flag4; IsVitalWatch = flag4; flag5 |= IsDoorLogWatch != flag3; IsDoorLogWatch = flag3; if (CanCheckCamera.GetBool()) { flag5 |= IsCameraWatch != flag2; IsCameraWatch = flag2; } if (flag5) { byte[] array = playerIdList.ToArray(); for (int i = 0; i < array.Length; i++) { Utils.NotifyRoles(Utils.GetPlayerById(array[i]), null, isForMeeting: false, NoCache: false, ForceLoop: false); } } } public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (seer.PlayerId != seen.PlayerId || isForMeeting) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (IsAdminWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), "⚠")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), Translator.GetString("AdminWarning"))); } if (IsVitalWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), "⚠")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), Translator.GetString("VitalsWarning"))); } if (IsDoorLogWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), "⚠")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), Translator.GetString("DoorlogWarning"))); } if (IsCameraWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), "⚠")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.AntiAdminer)), Translator.GetString("CameraWarning"))); } return stringBuilder.ToString(); } } internal class Arrogance : RoleBase { private const int Id = 500; public static HashSet playerIdList = new HashSet(); private static OptionItem DefaultKillCooldown; private static OptionItem ReduceKillCooldown; private static OptionItem MinKillCooldown; public static OptionItem BardChance; private static readonly Dictionary NowCooldown = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(500, TabGroup.ImpostorRoles, CustomRoles.Arrogance); DefaultKillCooldown = FloatOptionItem.Create(510, GeneralOption.DefaultKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 65f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arrogance]).SetValueFormat(OptionFormat.Seconds); ReduceKillCooldown = FloatOptionItem.Create(511, GeneralOption.ReduceKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arrogance]).SetValueFormat(OptionFormat.Seconds); MinKillCooldown = FloatOptionItem.Create(512, GeneralOption.MinKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 2.5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arrogance]).SetValueFormat(OptionFormat.Seconds); BardChance = IntegerOptionItem.Create(513, "BardChance", new IntegerValueRule(0, 100, 5), 0, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Arrogance]).SetValueFormat(OptionFormat.Percent); } public override void Init() { playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); NowCooldown.Remove(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = NowCooldown[id]; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { NowCooldown[killer.PlayerId] = Math.Clamp(NowCooldown[killer.PlayerId] - ReduceKillCooldown.GetFloat(), MinKillCooldown.GetFloat(), DefaultKillCooldown.GetFloat()); killer.ResetKillCooldown(); killer.SyncSettings(); return true; } } internal class Bard : RoleBase { public static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public static bool CheckSpawn() { return IRandom.Instance.Next(0, 100) < Arrogance.BardChance.GetInt(); } public override void OnPlayerExiled(PlayerControl bard, NetworkedPlayerInfo exiled) { if ((Object)(object)exiled != (Object)null) { Main.AllPlayerKillCooldown[bard.PlayerId] /= 2f; } } } internal class Berserker : RoleBase { private const int Id = 600; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem BerserkerKillCooldown; private static OptionItem BerserkerMax; private static OptionItem BerserkerOneCanKillCooldown; private static OptionItem BerserkerKillCooldownLevel; private static OptionItem BerserkerOneKillCooldown; private static OptionItem BerserkerTwoCanScavenger; private static OptionItem BerserkerScavengerLevel; private static OptionItem BerserkerThreeCanBomber; private static OptionItem BerserkerBomberLevel; private static OptionItem BerserkerFourCanNotKill; private static OptionItem BerserkerImmortalLevel; private static readonly Dictionary BerserkerKillMax = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(600, TabGroup.ImpostorRoles, CustomRoles.Berserker); BerserkerKillCooldown = FloatOptionItem.Create(602, "BerserkerKillCooldown", new FloatValueRule(25f, 250f, 2.5f), 35f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]).SetValueFormat(OptionFormat.Seconds); BerserkerMax = IntegerOptionItem.Create(603, "BerserkerMax", new IntegerValueRule(1, 10, 1), 4, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]).SetValueFormat(OptionFormat.Level); BerserkerOneCanKillCooldown = BooleanOptionItem.Create(604, "BerserkerOneCanKillCooldown", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]); BerserkerOneKillCooldown = FloatOptionItem.Create(605, "BerserkerOneKillCooldown", new FloatValueRule(10f, 45f, 2.5f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BerserkerOneCanKillCooldown).SetValueFormat(OptionFormat.Seconds); BerserkerKillCooldownLevel = IntegerOptionItem.Create(606, "BerserkerLevelRequirement", new IntegerValueRule(1, 10, 1), 1, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BerserkerOneCanKillCooldown).SetValueFormat(OptionFormat.Level); BerserkerTwoCanScavenger = BooleanOptionItem.Create(607, "BerserkerTwoCanScavenger", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]); BerserkerScavengerLevel = IntegerOptionItem.Create(608, "BerserkerLevelRequirement", new IntegerValueRule(1, 10, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BerserkerTwoCanScavenger).SetValueFormat(OptionFormat.Level); BerserkerThreeCanBomber = BooleanOptionItem.Create(609, "BerserkerThreeCanBomber", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]); BerserkerBomberLevel = IntegerOptionItem.Create(610, "BerserkerLevelRequirement", new IntegerValueRule(1, 10, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BerserkerThreeCanBomber).SetValueFormat(OptionFormat.Level); BerserkerFourCanNotKill = BooleanOptionItem.Create(612, "BerserkerFourCanNotKill", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Berserker]); BerserkerImmortalLevel = IntegerOptionItem.Create(613, "BerserkerLevelRequirement", new IntegerValueRule(1, 10, 1), 4, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BerserkerFourCanNotKill).SetValueFormat(OptionFormat.Level); } public override void Init() { BerserkerKillMax.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { BerserkerKillMax[playerId] = 0; PlayerIds.Add(playerId); } public override void Remove(byte playerId) { BerserkerKillMax.Remove(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = BerserkerKillCooldown.GetFloat(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (BerserkerKillMax[target.PlayerId] >= BerserkerImmortalLevel.GetInt() && BerserkerFourCanNotKill.GetBool()) { killer.RpcTeleport(target.GetCustomPosition()); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); killer.SetKillCooldown(-1f, target, forceAnime: true); return false; } return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) if (BerserkerKillMax[killer.PlayerId] < BerserkerMax.GetInt()) { BerserkerKillMax[killer.PlayerId]++; killer.Notify(string.Format(Translator.GetString("BerserkerLevelChanged"), BerserkerKillMax[killer.PlayerId])); Logger.Info($"Increased the lvl to {BerserkerKillMax[killer.PlayerId]}", "CULTIVATOR", escapeCRLF: true, 93, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Berserker.cs"); } else { killer.Notify(Translator.GetString("BerserkerMaxReached")); Logger.Info($"Max level reached lvl = {BerserkerKillMax[killer.PlayerId]}", "CULTIVATOR", escapeCRLF: true, 98, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Berserker.cs"); } if (BerserkerKillMax[killer.PlayerId] >= BerserkerKillCooldownLevel.GetInt() && BerserkerOneCanKillCooldown.GetBool()) { Main.AllPlayerKillCooldown[killer.PlayerId] = BerserkerOneKillCooldown.GetFloat(); } if (BerserkerKillMax[killer.PlayerId] == BerserkerScavengerLevel.GetInt() && BerserkerTwoCanScavenger.GetBool()) { killer.RpcTeleport(target.GetCustomPosition()); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); target.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); Main.PlayerStates[target.PlayerId].SetDead(); target.RpcMurderPlayer(target); target.SetRealKiller(killer); killer.SetKillCooldownV2(); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Berserker)), Translator.GetString("KilledByBerserker"))); return false; } if (BerserkerKillMax[killer.PlayerId] >= BerserkerBomberLevel.GetInt() && BerserkerThreeCanBomber.GetBool()) { Logger.Info("炸弹爆炸了", "Boom", escapeCRLF: true, 124, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Berserker.cs"); CustomSoundsManager.RPCPlayCustomSoundAll("Boom"); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!val.IsModClient()) { val.KillFlash(); } if (!((Object)(object)val == (Object)(object)killer) && !((Object)(object)val == (Object)(object)target) && Vector2.Distance(Vector2.op_Implicit(((Component)killer).transform.position), Vector2.op_Implicit(((Component)val).transform.position)) <= Bomber.BomberRadius.GetFloat()) { val.SetDeathReason(PlayerState.DeathReason.Bombed); val.RpcMurderPlayer(val); val.SetRealKiller(killer); } } } return true; } } internal class Blackmailer : RoleBase { private const int Id = 24600; private static OptionItem SkillCooldown; private static OptionItem ShowShapeshiftAnimationsOpt; private static readonly HashSet ForBlackmailer = new HashSet(); public static bool HasEnabled => CustomRoles.Blackmailer.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(24600, TabGroup.ImpostorRoles, CustomRoles.Blackmailer); SkillCooldown = FloatOptionItem.Create(24602, "BlackmailerSkillCooldown", new FloatValueRule(2.5f, 900f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Blackmailer]).SetValueFormat(OptionFormat.Seconds); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(24603, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Blackmailer]); } public override void Init() { ForBlackmailer.Clear(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = SkillCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override bool OnCheckShapeshift(PlayerControl blackmailer, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (ShowShapeshiftAnimationsOpt.GetBool() || blackmailer.PlayerId == target.PlayerId) { return true; } DoBlackmaile(blackmailer, target); blackmailer.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); return false; } public override void OnShapeshift(PlayerControl blackmailer, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (shapeshifting && IsAnimate) { DoBlackmaile(blackmailer, target); } } private static void DoBlackmaile(PlayerControl blackmailer, PlayerControl target) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!target.IsAlive()) { blackmailer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(blackmailer.GetCustomRole())), Translator.GetString("NotAssassin"))); return; } ClearBlackmaile(); ForBlackmailer.Add(target.PlayerId); } public override void AfterMeetingTasks() { ClearBlackmaile(); } public override void OnCoEndGame() { ClearBlackmaile(); } private static void ClearBlackmaile() { ForBlackmailer.Clear(); } public static bool CheckBlackmaile(PlayerControl player) { if (HasEnabled && GameStates.IsInGame) { return ForBlackmailer.Contains(player.PlayerId); } return false; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!isForMeeting || !CheckBlackmaile(target)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Blackmailer)), "╳"); } public override void OnOthersMeetingHudStart(PlayerControl pc) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (CheckBlackmaile(pc)) { string arg = pc.GetRealName(isMeeting: true); if (Doppelganger.DoppelVictim.TryGetValue(pc.PlayerId, out var value)) { arg = value; } MeetingHudStartPatch.AddMsg(string.Format(string.Format(Translator.GetString("BlackmailerDead"), arg), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Blackmailer)), Translator.GetString("BlackmaileKillTitle")))); } } } internal class Bomber : RoleBase { private const int Id = 700; private static readonly HashSet Playerids = new HashSet(); public static OptionItem BomberRadius; public static OptionItem BomberCanKill; public static OptionItem BomberKillCD; public static OptionItem BombCooldown; public static OptionItem ImpostorsSurviveBombs; public static OptionItem BomberDiesInExplosion; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Bomb"); } public override void SetupCustomOption() { Options.SetupRoleOptions(700, TabGroup.ImpostorRoles, CustomRoles.Bomber); BomberRadius = FloatOptionItem.Create(702, "BomberRadius", new FloatValueRule(0.5f, 100f, 0.5f), 2f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]).SetValueFormat(OptionFormat.Multiplier); BomberCanKill = BooleanOptionItem.Create(703, GeneralOption.CanKill, defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]); BomberKillCD = FloatOptionItem.Create(704, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(BomberCanKill).SetValueFormat(OptionFormat.Seconds); BombCooldown = FloatOptionItem.Create(705, "BombCooldown", new FloatValueRule(5f, 180f, 2.5f), 60f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]).SetValueFormat(OptionFormat.Seconds); ImpostorsSurviveBombs = BooleanOptionItem.Create(706, "ImpostorsSurviveBombs", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]); BomberDiesInExplosion = BooleanOptionItem.Create(707, "BomberDiesInExplosion", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]); } public override void Init() { Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override bool CanUseKillButton(PlayerControl pc) { if (BomberCanKill.GetBool()) { return pc.IsAlive(); } return false; } public override void SetKillCooldown(byte id) { if (BomberCanKill.GetBool()) { Main.AllPlayerKillCooldown[id] = BomberKillCD.GetFloat(); } else { Main.AllPlayerKillCooldown[id] = 300f; } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = BombCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 2f; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl targetSS, ref bool resetCooldown, ref bool shouldAnimate) { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == targetSS.PlayerId) { return true; } CustomRoles customRole = shapeshifter.GetCustomRole(); Logger.Info("The bomb went off", customRole.ToString(), escapeCRLF: true, 74, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Bomber.cs"); CustomSoundsManager.RPCPlayCustomSoundAll("Boom"); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!val.IsModClient()) { val.KillFlash(); } if (val.PlayerId != shapeshifter.PlayerId && val.IsAlive() && !Medic.ProtectList.Contains(val.PlayerId) && (!val.Is(Custom_Team.Impostor) || !ImpostorsSurviveBombs.GetBool()) && !val.inVent && !val.Is(CustomRoles.Pestilence) && !val.Is(CustomRoles.Solsticer) && !(Vector2.Distance(Vector2.op_Implicit(((Component)shapeshifter).transform.position), Vector2.op_Implicit(((Component)val).transform.position)) > BomberRadius.GetFloat())) { val.SetDeathReason(PlayerState.DeathReason.Bombed); val.RpcMurderPlayer(val); val.SetRealKiller(shapeshifter); } } if (BomberDiesInExplosion.GetBool() && customRole == CustomRoles.Bomber) { new LateTask(delegate { if (Main.AllAlivePlayerControls.Length > 0 && !GameStates.IsEnded) { shapeshifter.SetDeathReason(PlayerState.DeathReason.Bombed); shapeshifter.RpcMurderPlayer(shapeshifter); } Utils.NotifyRoles(); }, 0.3f, $"{customRole} was suicide"); } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("BomberShapeshiftText")); } } internal class BountyHunter : RoleBase { private const int Id = 800; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem OptionTargetChangeTime; private static OptionItem OptionSuccessKillCooldown; private static OptionItem OptionFailureKillCooldown; private static OptionItem OptionShowTargetArrow; private static float TargetChangeTime; private static float SuccessKillCooldown; private static float FailureKillCooldown; private static bool ShowTargetArrow; private static Dictionary Targets = new Dictionary(); public static readonly Dictionary ChangeTimer = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Handoff"); } public override void SetupCustomOption() { Options.SetupRoleOptions(800, TabGroup.ImpostorRoles, CustomRoles.BountyHunter); OptionTargetChangeTime = FloatOptionItem.Create(810, "BountyTargetChangeTime", new FloatValueRule(10f, 180f, 2.5f), 60f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BountyHunter]).SetValueFormat(OptionFormat.Seconds); OptionSuccessKillCooldown = FloatOptionItem.Create(811, "BountySuccessKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 2.5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BountyHunter]).SetValueFormat(OptionFormat.Seconds); OptionFailureKillCooldown = FloatOptionItem.Create(812, "BountyFailureKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 50f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BountyHunter]).SetValueFormat(OptionFormat.Seconds); OptionShowTargetArrow = BooleanOptionItem.Create(813, "BountyShowTargetArrow", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.BountyHunter]); } public override void Init() { playerIdList.Clear(); Targets.Clear(); ChangeTimer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); TargetChangeTime = OptionTargetChangeTime.GetFloat(); SuccessKillCooldown = OptionSuccessKillCooldown.GetFloat(); FailureKillCooldown = OptionFailureKillCooldown.GetFloat(); ShowTargetArrow = OptionShowTargetArrow.GetBool(); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { ResetTarget(Utils.GetPlayerById(playerId)); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } private static void SendRPC(byte bountyId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)127, (SendOption)1, -1); val.Write(bountyId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte b = reader.ReadByte(); byte b2 = reader.ReadByte(); Targets[b] = b2; if (ShowTargetArrow) { TargetArrow.Add(b, b2); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = TargetChangeTime; AURoleOptions.ShapeshifterDuration = 1f; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { resetCooldown = false; return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (GetTarget(killer) == target.PlayerId) { object obj; if (killer == null) { obj = null; } else { NetworkedPlayerInfo data = killer.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.Info((string?)obj + ": kill target", "BountyHunter", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); Main.AllPlayerKillCooldown[killer.PlayerId] = SuccessKillCooldown; killer.SyncSettings(); ResetTarget(killer); } else { object obj2; if (killer == null) { obj2 = null; } else { NetworkedPlayerInfo data2 = killer.Data; obj2 = ((data2 != null) ? data2.PlayerName : null); } Logger.Info((string?)obj2 + ": non-target kills", "BountyHunter", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); Main.AllPlayerKillCooldown[killer.PlayerId] = FailureKillCooldown; killer.SyncSettings(); } return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { ChangeTimer.Clear(); } public override void OnFixedUpdate(PlayerControl player) { if (!ChangeTimer.ContainsKey(player.PlayerId)) { return; } if (!player.IsAlive()) { ChangeTimer.Remove(player.PlayerId); return; } byte target = GetTarget(player); if (target != byte.MaxValue) { if (ChangeTimer[player.PlayerId] >= TargetChangeTime) { ResetTarget(player); Utils.NotifyRoles(player); } if (ChangeTimer[player.PlayerId] >= 0f) { ChangeTimer[player.PlayerId] += Time.fixedDeltaTime; } if (Main.PlayerStates[target].IsDead) { ResetTarget(player); Logger.Info("player " + player.GetNameWithRole() + ": target was invalid, so target was updated", "BountyHunter", escapeCRLF: true, 145, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); Utils.NotifyRoles(player); } } } public static byte GetTarget(PlayerControl player) { if ((Object)(object)player == (Object)null) { return byte.MaxValue; } if (Targets == null) { Targets = new Dictionary(); } if (!Targets.TryGetValue(player.PlayerId, out var value)) { return ResetTarget(player); } return value; } public static PlayerControl GetTargetPC(PlayerControl player) { byte target = GetTarget(player); if (target != byte.MaxValue) { return Utils.GetPlayerById(target); } return null; } private static bool PotentialTarget(PlayerControl player, PlayerControl target) { if ((Object)(object)target == (Object)null || (Object)(object)player == (Object)null) { return false; } if (player.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) { return false; } if (target.Is(CustomRoles.Romantic) && Romantic.BetPlayer.TryGetValue(target.PlayerId, out var value) && value == player.PlayerId) { return false; } if (target.Is(CustomRoles.Lawyer) && Lawyer.Target.TryGetValue(target.PlayerId, out var value2) && value2 == player.PlayerId && Lawyer.TargetKnowLawyer) { return false; } if (player.Is(CustomRoles.Charmed) && (target.Is(CustomRoles.Cultist) || (target.Is(CustomRoles.Charmed) && Cultist.TargetKnowOtherTargets))) { return false; } if (player.Is(CustomRoles.Infected) && (target.Is(CustomRoles.Infectious) || (target.Is(CustomRoles.Infected) && Infectious.TargetKnowOtherTargets))) { return false; } if (player.Is(CustomRoles.Recruit) && (target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick))) { return false; } if ((player.Is(CustomRoles.Contagious) && target.Is(CustomRoles.Virus)) || (target.Is(CustomRoles.Contagious) && Virus.TargetKnowOtherTarget.GetBool())) { return false; } if ((player.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer)) || target.Is(CustomRoles.Admired)) { return false; } if ((player.Is(CustomRoles.Soulless) && target.Is(CustomRoles.CursedSoul)) || target.Is(CustomRoles.Soulless)) { return false; } if (target.GetCustomRole().IsImpostor() || ((target.GetCustomRole().IsMadmate() || target.Is(CustomRoles.Madmate)) && Madmate.ImpKnowWhosMadmate.GetBool())) { return false; } return true; } private static byte ResetTarget(PlayerControl player) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return byte.MaxValue; } byte playerId = player.PlayerId; ChangeTimer[playerId] = 0f; Logger.Info(player.GetNameWithRole() + ": reset target", "BountyHunter", escapeCRLF: true, 208, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); player.RpcResetAbilityCooldown(); List list = new List(Main.AllAlivePlayerControls.Where((PlayerControl pc) => PotentialTarget(player, pc))); if (list.Count >= 2 && Targets.TryGetValue(player.PlayerId, out var nowTarget)) { list.RemoveAll((PlayerControl x) => x.PlayerId == nowTarget); } if (list.Count == 0) { Logger.Warn("Reset target failed: Target candidate does not exist", "BountyHunter", escapeCRLF: true, 218, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); return byte.MaxValue; } _ = IRandom.Instance; PlayerControl val = list.RandomElement(); byte playerId2 = val.PlayerId; Targets[playerId] = playerId2; if (ShowTargetArrow) { TargetArrow.Add(playerId, playerId2); } Logger.Info("Change " + player.GetNameWithRole() + " target to: " + val.GetNameWithRole(), "BountyHunter", escapeCRLF: true, 228, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\BountyHunter.cs"); SendRPC(player.PlayerId, playerId2); return playerId2; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("BountyHunterChangeButtonText")); } public override void AfterMeetingTasks() { byte[] array = playerIdList.ToArray(); foreach (byte b in array) { if (!Main.PlayerStates[b].IsDead) { Utils.GetPlayerById(b)?.RpcResetAbilityCooldown(); ChangeTimer[b] = 0f; } } } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if (isForMeeting) { return string.Empty; } byte target = GetTarget(seer); if (target == byte.MaxValue) { return string.Empty; } return (isForHud ? Translator.GetString("BountyCurrentTarget") : Translator.GetString("Target")) + ": " + Main.AllPlayerNames[target].RemoveHtmlTags().Replace("\r\n", string.Empty); } public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { if ((Object)(object)seer == (Object)null) { return string.Empty; } if (!seer.Is(CustomRoles.BountyHunter)) { return string.Empty; } if ((Object)(object)seen != (Object)null && seer.PlayerId != seen.PlayerId) { return string.Empty; } if (!ShowTargetArrow || isForMeeting) { return string.Empty; } byte target = GetTarget(seer); return TargetArrow.GetArrows(seer, target); } } internal class Butcher : RoleBase { private const int Id = 24300; private static readonly HashSet PlayerIds = new HashSet(); private static Dictionary MurderTargetLateTask = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(24300, TabGroup.ImpostorRoles, CustomRoles.Butcher); } public override void Init() { MurderTargetLateTask = new Dictionary(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("ButcherButtonText")); } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (inMeeting || isSuicide || (Object)(object)target == (Object)null) { return; } target.SetRealKiller(killer); target.SetDeathReason(PlayerState.DeathReason.Dismembered); Main.PlayerStates[target.PlayerId].SetDead(); Main.OverDeadPlayerList.Add(target.PlayerId); _ = IRandom.Instance; if (target.Is(CustomRoles.Avanger)) { CustomSoundsManager.RPCPlayCustomSoundAll("Congrats"); CustomWinnerHolder.ResetAndSetWinner(CustomWinner.None); CollectionExtensions.Do(Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != target.PlayerId), (Action)delegate(PlayerControl x) { x.SetDeathReason(PlayerState.DeathReason.Revenge); target.RpcSpecificMurderPlayer(x, x); x.SetRealKiller(target); Main.PlayerStates[x.PlayerId].SetDead(); }); return; } new LateTask(delegate { for (int i = 0; i <= 19; i++) { if (GameStates.IsMeeting) { break; } if (!((InnerNetObject)target).AmOwner) { target.MurderPlayer(target, (MurderResultFlags)1); } CollectionExtensions.Do(Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != target.PlayerId && !((InnerNetObject)x).AmOwner), (Action)delegate(PlayerControl x) { target.RpcSpecificMurderPlayer(target, x); }); } }, 0.2f, "Butcher Show Bodies"); new LateTask(delegate { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!MurderTargetLateTask.ContainsKey(target.PlayerId)) { MurderTargetLateTask.Add(target.PlayerId, (0, 0, target.GetCustomPosition())); } }, 0.6f, "Butcher Late Kill"); } public override void AfterMeetingTasks() { MurderTargetLateTask = new Dictionary(); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { MurderTargetLateTask.Clear(); } public static void OnFixedUpdateOthers(PlayerControl target) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!MurderTargetLateTask.ContainsKey(target.PlayerId) || (Object)(object)target == (Object)null || !target.Data.IsDead) { return; } Vector2 item = MurderTargetLateTask[target.PlayerId].Item3; if (MurderTargetLateTask[target.PlayerId].Item1 > 19) { if (MurderTargetLateTask[target.PlayerId].Item2 < 5) { IRandom instance = IRandom.Instance; Vector2 position = default(Vector2); ((Vector2)(ref position))..ctor(item.x + (float)(instance.Next(1, 200) - 100) / 100f, item.y + (float)(instance.Next(1, 200) - 100) / 100f); target.RpcTeleport(position); target.RpcMurderPlayer(target); target.SetRealKiller(Utils.GetPlayerById(PlayerIds.First()), NotOverRide: true); MurderTargetLateTask[target.PlayerId] = (0, MurderTargetLateTask[target.PlayerId].Item2 + 1, item); } else { MurderTargetLateTask.Remove(target.PlayerId); } } else { MurderTargetLateTask[target.PlayerId] = (MurderTargetLateTask[target.PlayerId].Item1 + 1, MurderTargetLateTask[target.PlayerId].Item2, item); } } } internal class Camouflager : RoleBase { private const int Id = 2900; public static readonly HashSet Playerids = new HashSet(); private static OptionItem CamouflageCooldownOpt; private static OptionItem CamouflageDurationOpt; private static OptionItem CanUseCommsSabotagOpt; private static OptionItem DisableReportWhenCamouflageIsActiveOpt; private static OptionItem ShowShapeshiftAnimationsOpt; public static bool AbilityActivated = false; private static float CamouflageCooldown; private static float CamouflageDuration; private static bool CanUseCommsSabotage; private static bool DisableReportWhenCamouflageIsActive; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(2900, TabGroup.ImpostorRoles, CustomRoles.Camouflager); CamouflageCooldownOpt = FloatOptionItem.Create(2902, "CamouflageCooldown", new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Camouflager]).SetValueFormat(OptionFormat.Seconds); CamouflageDurationOpt = FloatOptionItem.Create(2904, "CamouflageDuration", new FloatValueRule(1f, 180f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Camouflager]).SetValueFormat(OptionFormat.Seconds); CanUseCommsSabotagOpt = BooleanOptionItem.Create(2906, "CanUseCommsSabotage", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Camouflager]); DisableReportWhenCamouflageIsActiveOpt = BooleanOptionItem.Create(2908, "DisableReportWhenCamouflageIsActive", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Camouflager]); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(2909, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Camouflager]); } public override void Init() { AbilityActivated = false; Playerids.Clear(); } public override void Add(byte playerId) { CamouflageCooldown = CamouflageCooldownOpt.GetFloat(); CamouflageDuration = CamouflageDurationOpt.GetFloat(); CanUseCommsSabotage = CanUseCommsSabotagOpt.GetBool(); DisableReportWhenCamouflageIsActive = DisableReportWhenCamouflageIsActiveOpt.GetBool(); Playerids.Add(playerId); } public override void Remove(byte playerId) { ClearCamouflage(); Playerids.Remove(playerId); } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(AbilityActivated); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { AbilityActivated = reader.ReadBoolean(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = CamouflageCooldown; AURoleOptions.ShapeshifterDuration = CamouflageDuration; } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Camo"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (AbilityActivated) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("CamouflagerShapeshiftTextAfterDisguise")); } else { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("CamouflagerShapeshiftTextBeforeDisguise")); } } public override bool OnCheckShapeshift(PlayerControl camouflager, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (ShowShapeshiftAnimationsOpt.GetBool()) { return true; } shouldAnimate = false; return true; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (!shapeshifting) { ClearCamouflage(); return; } AbilityActivated = true; SendRPC(); float time = (ShowShapeshiftAnimationsOpt.GetBool() ? 1.2f : 0.5f); new LateTask(delegate { if (!Main.MeetingIsStarted && GameStates.IsInTask) { Camouflage.CheckCamouflage(); } }, time, "Camouflager Use Shapeshift"); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { ClearCamouflage(); } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!inMeeting && AbilityActivated) { ClearCamouflage(); } } public static bool CantPressCommsSabotageButton(PlayerControl player) { if (player.Is(CustomRoles.Camouflager)) { return !CanUseCommsSabotage; } return false; } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if ((Object)(object)deadBody.Object != (Object)null && deadBody.Object.Is(CustomRoles.Bait) && Bait.BaitCanBeReportedUnderAllConditions.GetBool()) { return true; } if (DisableReportWhenCamouflageIsActive && AbilityActivated) { if (Utils.IsActive((SystemTypes)14)) { return Options.CommsCamouflage.GetBool(); } return false; } return true; } private void ClearCamouflage() { AbilityActivated = false; SendRPC(); Camouflage.CheckCamouflage(); } } internal class Chronomancer : RoleBase { private const int Id = 900; private int ChargedTime; private long now = Utils.GetTimeStamp(); private int FullCharge; private bool IsInMassacre; public float realcooldown; private float LastNowF; private float countnowF; private string LastCD; private static Color32 OrangeColor = new Color32(byte.MaxValue, (byte)190, (byte)92, byte.MaxValue); private static Color32 GreenColor = new Color32((byte)0, (byte)128, (byte)0, byte.MaxValue); private static int Charges; private static OptionItem KillCooldown; private static OptionItem Dtime; private static OptionItem ReduceVision; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(900, TabGroup.ImpostorRoles, CustomRoles.Chronomancer); KillCooldown = IntegerOptionItem.Create(910, "ChronomancerKillCooldown", new IntegerValueRule(1, 180, 1), 60, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chronomancer]).SetValueFormat(OptionFormat.Seconds); Dtime = FloatOptionItem.Create(911, "ChronomancerDecreaseTime", new FloatValueRule(0.05f, 1f, 0.05f), 0.15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chronomancer]).SetValueFormat(OptionFormat.Seconds); ReduceVision = FloatOptionItem.Create(912, "ChronomancerVisionMassacre", new FloatValueRule(0.25f, 1f, 0.25f), 0.5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chronomancer]).SetValueFormat(OptionFormat.Multiplier); } public override void Add(byte playerId) { FullCharge = KillCooldown.GetInt(); Charges = (int)Math.Round((double)KillCooldown.GetInt() / 10.0); realcooldown = Options.DefaultKillCooldown; LastCD = GetCharge(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { if (IsInMassacre) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)3, ReduceVision.GetFloat()); } else { opt.SetVision(HasImpVision: true); opt.SetFloat((FloatOptionNames)3, Main.DefaultImpostorVision); } } private Color32 GetPercentColor(int val) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((float)val / (float)FullCharge); return Color32.Lerp(OrangeColor, GreenColor, num); } private int GetChargeToColor() { int num = (int)Math.Round((double)ChargedTime / (double)FullCharge * 100.0); return Charges * num / 100; } private string GetCharge() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(Utils.ColorString(GetPercentColor(ChargedTime), $"{(int)Math.Round((double)ChargedTime / (double)FullCharge * 100.0)}% ")); int num = GetChargeToColor(); string text = (IsInMassacre ? "#630303" : "#0cb339"); stringBuilder.Append(""); for (int i = 0; i < Charges; i++) { string value = ((num > 0) ? ("<" + text + ">█ ") : "<#666666>█ "); num--; stringBuilder.Append(value); } stringBuilder.Append(""); return stringBuilder.ToString(); } private string GetModdedCharge() { return new StringBuilder($"{(int)Math.Round((double)ChargedTime / (double)FullCharge * 100.0)}% ").ToString(); } public void SetCooldown() { if (IsInMassacre) { Main.AllPlayerKillCooldown[_state.PlayerId] = 0.1f; } else { Main.AllPlayerKillCooldown[_state.PlayerId] = realcooldown; } base._Player.SyncSettings(); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { ChargedTime = 0; IsInMassacre = false; base._Player?.MarkDirtySettings(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (ChargedTime >= FullCharge) { LastNowF = countnowF + Dtime.GetFloat(); killer.Notify(Translator.GetString("ChronomancerStartMassacre")); IsInMassacre = true; } killer.SetKillCooldown(); return true; } public override void OnFixedUpdate(PlayerControl pc) { if (!GameStates.IsMeeting) { if (LastCD != GetCharge()) { LastCD = GetCharge(); Utils.NotifyRoles(pc, pc); } if (ChargedTime != FullCharge && now + 1 <= Utils.GetTimeStamp() && !IsInMassacre) { now = Utils.GetTimeStamp(); ChargedTime++; } else if (IsInMassacre && ChargedTime > 0 && countnowF >= LastNowF) { LastNowF = countnowF + Dtime.GetFloat(); ChargedTime--; } if (IsInMassacre && ChargedTime < 1) { IsInMassacre = false; pc.MarkDirtySettings(); } countnowF += Time.deltaTime; } } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { bool flag = GameStates.IsMeeting || isForMeeting; if ((Object)(object)seer == (Object)(object)seen && !flag) { if (!seer.IsModClient()) { return GetCharge(); } if (isForHud) { return GetModdedCharge(); } } return ""; } public override float SetModdedLowerText(out Color32? FaceColor) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) FaceColor = GetPercentColor(ChargedTime); return 3.8f; } } internal class Cleaner : RoleBase { private const int Id = 3000; private static readonly HashSet Playerids = new HashSet(); private static OptionItem KillCooldown; private static OptionItem KillCooldownAfterCleaning; private static readonly HashSet CleanerBodies = new HashSet(); public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override Sprite ReportButtonSprite => CustomButton.Get("Clean"); public override void SetupCustomOption() { Options.SetupRoleOptions(3000, TabGroup.ImpostorRoles, CustomRoles.Cleaner); KillCooldown = FloatOptionItem.Create(3002, GeneralOption.KillCooldown, new FloatValueRule(5f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleaner]).SetValueFormat(OptionFormat.Seconds); KillCooldownAfterCleaning = FloatOptionItem.Create(3003, "KillCooldownAfterCleaning", new FloatValueRule(5f, 180f, 2.5f), 60f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleaner]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { CleanerBodies.Clear(); Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (CleanerBodies.Contains(deadBody.PlayerId)) { return false; } if (reporter.Is(CustomRoles.Cleaner)) { CleanerBodies.Remove(deadBody.PlayerId); CleanerBodies.Add(deadBody.PlayerId); reporter.Notify(Translator.GetString("CleanerCleanBody")); reporter.SetKillCooldownV3(KillCooldownAfterCleaning.GetFloat(), null, forceAnime: true); Logger.Info("Cleaner: " + reporter.GetRealName() + " clear body: " + deadBody.PlayerName, "Cleaner", escapeCRLF: true, 57, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Cleaner.cs"); return false; } return true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("CleanerReportButtonText")); } } internal class Consigliere : RoleBase { private const int Id = 3100; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem KillCooldown; private static OptionItem DivinationMaxCount; private static readonly Dictionary DivinationCount = new Dictionary(); private static readonly Dictionary> DivinationTarget = new Dictionary>(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3100, TabGroup.ImpostorRoles, CustomRoles.Consigliere); KillCooldown = FloatOptionItem.Create(3110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Consigliere]).SetValueFormat(OptionFormat.Seconds); DivinationMaxCount = IntegerOptionItem.Create(3111, "ConsigliereDivinationMaxCount", new IntegerValueRule(1, 15, 1), 5, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Consigliere]).SetValueFormat(OptionFormat.Times); } public override void Init() { DivinationCount.Clear(); DivinationTarget.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { DivinationCount.TryAdd(playerId, DivinationMaxCount.GetInt()); DivinationTarget.TryAdd(playerId, new List()); PlayerIds.Add(playerId); Utils.GetPlayerById(playerId).AddDoubleTrigger(); } private static void SendRPC(byte playerId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)164, (SendOption)1, -1); val.Write(playerId); val.Write(DivinationCount[playerId]); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); if (DivinationCount.ContainsKey(key)) { DivinationCount[key] = reader.ReadInt32(); } else { DivinationCount.Add(key, DivinationMaxCount.GetInt()); } if (DivinationCount.ContainsKey(key)) { DivinationTarget[key].Add(reader.ReadByte()); } else { DivinationTarget.Add(key, new List()); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (DivinationCount[killer.PlayerId] > 0) { return killer.CheckDoubleTrigger(target, delegate { SetDivination(killer, target); }); } return true; } private static bool IsDivination(byte seer, byte target) { if (DivinationTarget[seer].Contains(target)) { return true; } return false; } private static void SetDivination(PlayerControl killer, PlayerControl target) { if (!IsDivination(killer.PlayerId, target.PlayerId)) { DivinationCount[killer.PlayerId]--; DivinationTarget[killer.PlayerId].Add(target.PlayerId); Logger.Info($"{killer.GetNameWithRole()}:占った 占い先→{target.GetNameWithRole()} || 残り{DivinationCount[killer.PlayerId]}回", "Consigliere", escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Consigliere.cs"); Utils.NotifyRoles(killer, target); SendRPC(killer.PlayerId, target.PlayerId); killer.SetKillCooldown(); } } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { bool IsWatch = false; CollectionExtensions.Do>>((IEnumerable>>)DivinationTarget, (Action>>)delegate(KeyValuePair> x) { if (x.Value != null && seer.PlayerId == x.Key && x.Value.Contains(target.PlayerId) && Utils.GetPlayerById(x.Key).IsAlive()) { IsWatch = true; } }); return IsWatch; } public override string GetProgressText(byte playerId, bool comms) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit((DivinationCount[playerId] > 0) ? Utils.GetRoleColor(CustomRoles.Consigliere).ShadeColor(0.25f) : Color.gray), DivinationCount.TryGetValue(playerId, out value) ? $"({value})" : "Invalid"); } } internal class Councillor : RoleBase { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { if (PlayerControl.LocalPlayer.Is(CustomRoles.Councillor) && PlayerControl.LocalPlayer.IsAlive()) { CreateCouncillorButton(__instance); } } } private const int Id = 1000; private static OptionItem MurderLimitPerMeeting; private static OptionItem MurderLimitPerGame; private static OptionItem MakeEvilJudgeClear; private static OptionItem TryHideMsg; private static OptionItem CanMurderMadmate; private static OptionItem CanMurderImpostor; private static OptionItem SuicideOnJudgeImpTeam; private static OptionItem CanMurderTaskDoneSnitch; private static OptionItem KillCooldown; private int MurderLimitMeeting; public static bool HasEnabled => CustomRoles.Councillor.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(1000, TabGroup.ImpostorRoles, CustomRoles.Councillor); KillCooldown = FloatOptionItem.Create(1010, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]).SetValueFormat(OptionFormat.Seconds); MurderLimitPerMeeting = IntegerOptionItem.Create(1011, "CouncillorMurderLimitPerMeeting", new IntegerValueRule(1, 15, 1), 1, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]).SetValueFormat(OptionFormat.Times); MurderLimitPerGame = IntegerOptionItem.Create(1012, "CouncillorMurderLimitPerGame", new IntegerValueRule(1, 15, 1), 4, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]).SetValueFormat(OptionFormat.Times); MakeEvilJudgeClear = BooleanOptionItem.Create(1018, "CouncillorMakeEvilJudgeClear", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]); CanMurderMadmate = BooleanOptionItem.Create(1013, "CouncillorCanMurderMadmate", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]); CanMurderImpostor = BooleanOptionItem.Create(1014, "CouncillorCanMurderImpostor", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]); CanMurderTaskDoneSnitch = BooleanOptionItem.Create(1016, "CouncillorCanMurderTaskDoneSnitch", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]); SuicideOnJudgeImpTeam = BooleanOptionItem.Create(1017, "CouncillorSuicideOnJudgeImpTeam", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]); TryHideMsg = BooleanOptionItem.Create(1015, "CouncillorTryHideMsg", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]).SetColor(Color.green); } public override void Add(byte playerId) { MurderLimitMeeting = MurderLimitPerMeeting.GetInt(); base.AbilityLimit = MurderLimitPerGame.GetInt(); } public override void AfterMeetingTasks() { MurderLimitMeeting = MurderLimitPerMeeting.GetInt(); } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!IsForMeeting || !seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Councillor)), target.PlayerId.ToString()) + " " + TargetPlayerName; } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Councillor)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public bool MurderMsg(PlayerControl pc, string msg, bool isUI = false) { //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)base._Player == (Object)null || GameStates.IsExilling) { return false; } int num = 0; msg = msg.ToLower().TrimStart().TrimEnd(); if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id")) { num = 1; } else { if (!CheckCommond(ref msg, "sp|jj|tl|Murder|审判|判|审", exact: false)) { return false; } num = 2; } if (!pc.IsAlive()) { Utils.SendMessage(Translator.GetString("CouncillorDead"), pc.PlayerId); return true; } switch (num) { case 1: Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId); return true; case 2: { if (TryHideMsg.GetBool()) { GuessManager.TryHideMsg(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var id, out var error)) { Utils.SendMessage(error, pc.PlayerId); return true; } PlayerControl playerById = Utils.GetPlayerById(id); if (!((Object)(object)playerById != (Object)null)) { break; } Logger.Info(pc.GetNameWithRole() + " trialed => " + playerById.GetNameWithRole(), "Councillor", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Councillor.cs"); bool flag = true; if (MurderLimitMeeting <= 0) { pc.ShowInfoMessage(isUI, Translator.GetString("CouncillorMurderMaxMeeting")); return true; } if (base.AbilityLimit <= 0f) { pc.ShowInfoMessage(isUI, Translator.GetString("CouncillorMurderMaxGame")); return true; } if (Jailer.IsTarget(playerById.PlayerId)) { pc.ShowInfoMessage(isUI, Translator.GetString("CanNotTrialJailed"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), Translator.GetString("JailerTitle"))); return true; } if (pc.PlayerId == playerById.PlayerId) { pc.ShowInfoMessage(isUI, Translator.GetString("Councillor_LaughToWhoMurderSelf"), Utils.ColorString(Color32.op_Implicit(Color.cyan), Translator.GetString("MessageFromKPD"))); flag = true; } else { if (playerById.Is(CustomRoles.NiceMini) && Mini.Age < 18) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessMini")); return true; } if (playerById.Is(CustomRoles.PunchingBag)) { pc.ShowInfoMessage(isUI, Translator.GetString("EradicatePunchingBag")); return true; } if (playerById.Is(CustomRoles.Rebound)) { Logger.Info(pc.GetNameWithRole() + " judged " + playerById.GetNameWithRole() + ", councillor sucide = true because target rebound", "CouncillorTrialMsg", escapeCRLF: true, 150, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Councillor.cs"); flag = true; } else { if (playerById.Is(CustomRoles.Solsticer)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSolsticer")); return true; } if (playerById.Is(CustomRoles.Pestilence)) { flag = true; } else if (playerById.Is(CustomRoles.Trickster)) { flag = true; } else { if (Medic.ProtectList.Contains(playerById.PlayerId) && !Medic.GuesserIgnoreShield.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessShielded")); return true; } if (Guardian.CannotBeKilled(playerById)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessGuardianTask")); return true; } if (playerById.Is(CustomRoles.Merchant) && Merchant.IsBribedKiller(pc, playerById)) { pc.ShowInfoMessage(isUI, Translator.GetString("BribedByMerchant2")); return true; } if (playerById.Is(CustomRoles.Snitch) && playerById.AllTasksCompleted() && !CanMurderTaskDoneSnitch.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("EGGuessSnitchTaskDone")); return true; } if (playerById.Is(CustomRoles.Madmate) || playerById.Is(CustomRoles.Refugee) || playerById.Is(CustomRoles.Parasite) || playerById.Is(CustomRoles.Crewpostor)) { if (pc.Is(CustomRoles.Admired) || (pc.IsAnySubRole((CustomRoles x) => x.IsConverted()) && !pc.Is(CustomRoles.Madmate))) { flag = false; } else if (CanMurderMadmate.GetBool()) { flag = false; } else { if (!SuicideOnJudgeImpTeam.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("Councillor_CannotMurderImpTeam")); return true; } pc.ShowInfoMessage(isUI, Translator.GetString("Councillor_SuicideForMurderImps")); flag = true; } } else if (playerById.GetCustomRole().IsImpostor()) { if (pc.Is(CustomRoles.Admired) || (pc.IsAnySubRole((CustomRoles x) => x.IsConverted()) && !pc.Is(CustomRoles.Madmate))) { flag = false; } else if (CanMurderImpostor.GetBool()) { flag = false; } else { if (!SuicideOnJudgeImpTeam.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("Councillor_CannotMurderImpTeam")); return true; } pc.ShowInfoMessage(isUI, Translator.GetString("Councillor_SuicideForMurderImps")); flag = true; } } else if (playerById.GetCustomRole().IsCrewmate()) { flag = false; } else if (playerById.GetCustomRole().IsNeutral()) { flag = false; } else { Logger.Warn("Impossibe to reach here!", "CouncillorTrial", escapeCRLF: true, 227, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Councillor.cs"); flag = true; } } } } PlayerControl dp = (flag ? pc : playerById); playerById = dp; string Name = dp.GetRealName(); MurderLimitMeeting--; base.AbilityLimit--; SendSkillRPC(); if (GameStates.IsProceeding) { break; } new LateTask(delegate { dp.SetDeathReason(PlayerState.DeathReason.Trialed); dp.SetRealKiller(pc); dp.RpcGuesserMurderPlayer(); Main.PlayersDiedInMeeting.Add(dp.PlayerId); MurderPlayerPatch.AfterPlayerDeathTasks(pc, dp, inMeeting: true); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); new LateTask(delegate { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!MakeEvilJudgeClear.GetBool()) { Utils.SendMessage(string.Format(Translator.GetString("Judge_TrialKill"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Judge)), Translator.GetString("Judge_TrialKillTitle")), logforChatManager: true); } else { Utils.SendMessage(string.Format(Translator.GetString("Councillor_MurderKill"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Councillor)), Translator.GetString("Councillor_MurderKillTitle")), logforChatManager: true); } }, 0.6f, "Guess Msg"); }, 0.2f, "Murder Kill"); break; } } return true; } private static bool MsgToPlayerAndRole(string msg, out byte id, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } MatchCollection matchCollection = new Regex("\\d+").Matches(msg); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { text += matchCollection[i]; } if (int.TryParse(text, out var result)) { id = Convert.ToByte(result); PlayerControl playerById = Utils.GetPlayerById(id); if ((Object)(object)playerById == (Object)null || playerById.Data.IsDead) { error = Translator.GetString("Councillor_MurderNull"); return false; } error = string.Empty; return true; } id = byte.MaxValue; error = Translator.GetString("Councillor_MurderHelp"); return false; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } private static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); for (int i = 0; i < array.Length; i++) { if (exact) { if (msg == "/" + array[i]) { return true; } } else if (msg.StartsWith("/" + array[i])) { msg = msg.Replace("/" + array[i], string.Empty); return true; } } return false; } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)120, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC_Custom(MessageReader reader, PlayerControl pc) { int value = reader.ReadByte(); if (pc.GetRoleClass() is Councillor councillor) { councillor.MurderMsg(pc, $"/tl {value}", isUI: true); } } private static void CouncillorOnClick(byte playerId) { Logger.Msg($"Click: ID {playerId}", "Councillor UI", escapeCRLF: true, 343, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Councillor.cs"); PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && GameStates.IsVoting) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && PlayerControl.LocalPlayer.GetRoleClass() is Councillor councillor) { councillor.MurderMsg(PlayerControl.LocalPlayer, $"/tl {playerId}", isUI: true); } else { SendRPC(playerId); } } } private static void CreateCouncillorButton(MeetingHud __instance) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) foreach (PlayerVoteArea pva in (Il2CppArrayBase)(object)__instance.playerStates) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); obj.GetComponent().sprite = CustomButton.Get("MeetingKillButton"); PassiveButton component = obj.GetComponent(); ((UnityEventBase)component.OnClick).RemoveAllListeners(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { CouncillorOnClick(pva.TargetPlayerId); })); } } } public override string GetProgressText(byte playerId, bool coooms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit <= 0f) ? Color.gray : Utils.GetRoleColor(CustomRoles.Councillor)), $"({base.AbilityLimit})") ?? "Invalid"; } } internal class Crewpostor : RoleBase { private const int Id = 5800; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem CanKillAllies; private static OptionItem KnowsAllies; private static OptionItem AlliesKnowCrewpostor; private static OptionItem LungeKill; private static OptionItem KillAfterTask; private static Dictionary TasksDone = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; public override void SetupCustomOption() { Options.SetupRoleOptions(5800, TabGroup.ImpostorRoles, CustomRoles.Crewpostor); CanKillAllies = BooleanOptionItem.Create(5802, GeneralOption.CanKillImpostors, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crewpostor]); KnowsAllies = BooleanOptionItem.Create(5803, "CrewpostorKnowsAllies", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crewpostor]); AlliesKnowCrewpostor = BooleanOptionItem.Create(5804, "AlliesKnowCrewpostor", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crewpostor]); LungeKill = BooleanOptionItem.Create(5805, "CrewpostorLungeKill", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crewpostor]); KillAfterTask = IntegerOptionItem.Create(5806, "CrewpostorKillAfterTask", new IntegerValueRule(1, 50, 1), 1, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crewpostor]); Options.OverrideTasksData.Create(5807, TabGroup.ImpostorRoles, CustomRoles.Crewpostor); } public override void Init() { TasksDone = new Dictionary(); PlayerIds.Clear(); } public override void Add(byte playerId) { TasksDone[playerId] = 0; PlayerIds.Add(playerId); } public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) { if (ForRecompute & !player.IsDead) { return false; } if (player.IsDead) { return false; } return true; } private static void SendRPC(byte cpID, int tasksDone) { if (PlayerControl.LocalPlayer.PlayerId == cpID) { if (TasksDone.ContainsKey(cpID)) { TasksDone[cpID] = tasksDone; } else { TasksDone[cpID] = 0; } } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)150, (SendOption)1, -1); val.Write(cpID); val.WritePacked(tasksDone); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); int value = reader.ReadInt32(); if (TasksDone.ContainsKey(key)) { TasksDone[key] = value; } else { TasksDone.Add(key, 0); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 0f; AURoleOptions.EngineerInVentMaxTime = 0f; } public override bool CanUseKillButton(PlayerControl pc) { return false; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return KnowRoleTarget(seer, target); } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { if (!AlliesKnowCrewpostor.GetBool() || !seer.Is(Custom_Team.Impostor) || !target.Is(CustomRoles.Crewpostor)) { if (KnowsAllies.GetBool() && seer.Is(CustomRoles.Crewpostor)) { return target.Is(Custom_Team.Impostor); } return false; } return true; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (!player.IsAlive()) { return true; } if (TasksDone.ContainsKey(player.PlayerId)) { TasksDone[player.PlayerId]++; } else { TasksDone[player.PlayerId] = 0; } SendRPC(player.PlayerId, TasksDone[player.PlayerId]); List source = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != player.PlayerId && (CanKillAllies.GetBool() || !x.GetCustomRole().IsImpostorTeam())).ToList(); if (!source.Any()) { Logger.Info("No target to kill", "Crewpostor", escapeCRLF: true, 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } else if (TasksDone[player.PlayerId] % KillAfterTask.GetInt() != 0 && TasksDone[player.PlayerId] != 0) { Logger.Info($"Crewpostor task done but kill skipped, tasks completed {TasksDone[player.PlayerId]}, but it kills after {KillAfterTask.GetInt()} tasks", "Crewpostor", escapeCRLF: true, 121, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } else { List list = new List(); foreach (PlayerControl item in source.OrderBy((PlayerControl x) => Vector2.Distance(Vector2.op_Implicit(((Component)player).transform.position), Vector2.op_Implicit(((Component)x).transform.position)))) { list.Add(item); } source = list; PlayerControl val = source[0]; if (!val.Is(CustomRoles.Pestilence)) { if (!LungeKill.GetBool()) { val.RpcCheckAndMurder(val); val.SetRealKiller(player); player.RpcGuardAndKill(); Logger.Info("No lunge mode kill", "Crewpostor", escapeCRLF: true, 135, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } else { player.RpcMurderPlayer(val); val.SetRealKiller(player); player.RpcGuardAndKill(); Logger.Info("lunge mode kill", "Crewpostor", escapeCRLF: true, 142, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } Logger.Info("Crewpostor completed task to kill:" + player.GetNameWithRole().RemoveHtmlTags() + " => " + val.GetNameWithRole().RemoveHtmlTags(), "Crewpostor", escapeCRLF: true, 144, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } else { val.RpcMurderPlayer(player); val.SetRealKiller(player); player.RpcGuardAndKill(); Logger.Info("Crewpostor tried to kill pestilence (reflected back):" + val.GetNameWithRole().RemoveHtmlTags() + " => " + player.GetNameWithRole().RemoveHtmlTags(), "Pestilence Reflect", escapeCRLF: true, 151, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Crewpostor.cs"); } } return true; } } internal class CursedWolf : RoleBase { private const int Id = 1100; private static OptionItem GuardSpellTimes; private static OptionItem KillAttacker; public static bool HasEnabled => CustomRoles.CursedWolf.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1100, TabGroup.ImpostorRoles, CustomRoles.CursedWolf); GuardSpellTimes = IntegerOptionItem.Create(1102, "CursedWolfGuardSpellTimes", new IntegerValueRule(1, 15, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedWolf]).SetValueFormat(OptionFormat.Times); KillAttacker = BooleanOptionItem.Create(1103, GeneralOption.KillAttackerWhenAbilityRemaining, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CursedWolf]); } public override void Add(byte playerId) { base.AbilityLimit = GuardSpellTimes.GetInt(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)(object)target || base.AbilityLimit <= 0f) { return true; } if (killer.Is(CustomRoles.Pestilence)) { return true; } killer.RpcGuardAndKill(target); target.RpcGuardAndKill(target); base.AbilityLimit -= 1f; SendSkillRPC(); if (KillAttacker.GetBool() && target.RpcCheckAndMurder(killer, check: true)) { Logger.Info($"{target.GetNameWithRole()} Spell Count: {base.AbilityLimit}", "Cursed Wolf", escapeCRLF: true, 45, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\CursedWolf.cs"); killer.SetDeathReason(PlayerState.DeathReason.Curse); killer.RpcMurderPlayer(killer); killer.SetRealKiller(target); } return false; } public override string GetProgressText(byte PlayerId, bool comms) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.CursedWolf)), $"({base.AbilityLimit})"); } } internal class Dazzler : RoleBase { private const int Id = 5400; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem KillCooldown; private static OptionItem ShapeshiftCooldown; private static OptionItem CauseVision; private static OptionItem DazzleLimit; private static OptionItem ResetDazzledVisionOnDeath; private static OptionItem ShowShapeshiftAnimationsOpt; private static Dictionary> PlayersDazzled = new Dictionary>(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(5400, TabGroup.ImpostorRoles, CustomRoles.Dazzler); KillCooldown = FloatOptionItem.Create(5410, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(5411, "DazzleCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]).SetValueFormat(OptionFormat.Seconds); CauseVision = FloatOptionItem.Create(5413, "DazzlerCauseVision", new FloatValueRule(0f, 5f, 0.05f), 0.65f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]).SetValueFormat(OptionFormat.Multiplier); DazzleLimit = IntegerOptionItem.Create(5414, "DazzlerDazzleLimit", new IntegerValueRule(1, 15, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]).SetValueFormat(OptionFormat.Times); ResetDazzledVisionOnDeath = BooleanOptionItem.Create(5415, "DazzlerResetDazzledVisionOnDeath", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(5416, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dazzler]); } public override void Init() { PlayersDazzled = new Dictionary>(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayersDazzled.TryAdd(playerId, new List()); PlayerIds.Add(playerId); } public override void Remove(byte playerId) { PlayersDazzled.Remove(playerId); PlayerIds.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (ShowShapeshiftAnimationsOpt.GetBool() || shapeshifter.PlayerId == target.PlayerId) { return true; } DoDazzled(shapeshifter, target); shapeshifter.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); return false; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (shapeshifting) { DoDazzled(shapeshifter, target); } } private static void DoDazzled(PlayerControl shapeshifter, PlayerControl target) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!PlayersDazzled[shapeshifter.PlayerId].Contains(target.PlayerId) && PlayersDazzled[shapeshifter.PlayerId].Count < DazzleLimit.GetInt()) { Tired.Remove(shapeshifter.PlayerId); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Dazzler)), Translator.GetString("DazzlerDazzled"))); PlayersDazzled[shapeshifter.PlayerId].Add(target.PlayerId); Utils.MarkEveryoneDirtySettings(); } } public static void SetDazzled(PlayerControl player, IGameOptions opt) { if (PlayersDazzled.Any((KeyValuePair> a) => a.Value.Contains(player.PlayerId) && (!ResetDazzledVisionOnDeath.GetBool() || Main.AllAlivePlayerControls.Any((PlayerControl b) => b.PlayerId == a.Key)))) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, CauseVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, CauseVision.GetFloat()); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("DazzleButtonText")); } } internal class Deathpact : RoleBase { private const int Id = 1200; private static readonly HashSet Playerids = new HashSet(); private static OptionItem KillCooldown; private static OptionItem ShapeshiftCooldown; private static OptionItem DeathpactDuration; private static OptionItem NumberOfPlayersInPact; private static OptionItem ShowArrowsToOtherPlayersInPact; private static OptionItem ReduceVisionWhileInPact; private static OptionItem VisionWhileInPact; private static OptionItem KillDeathpactPlayersOnMeeting; private static OptionItem PlayersInDeathpactCanCallMeeting; private static OptionItem ShowShapeshiftAnimationsOpt; private static readonly HashSet ActiveDeathpacts = new HashSet(); private static readonly Dictionary> PlayersInDeathpact = new Dictionary>(); private static readonly Dictionary DeathpactTime = new Dictionary(); public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1200, TabGroup.ImpostorRoles, CustomRoles.Deathpact); KillCooldown = FloatOptionItem.Create(1210, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(1211, "DeathPactCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]).SetValueFormat(OptionFormat.Seconds); DeathpactDuration = FloatOptionItem.Create(1213, "DeathpactDuration", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]).SetValueFormat(OptionFormat.Seconds); NumberOfPlayersInPact = IntegerOptionItem.Create(1214, "DeathpactNumberOfPlayersInPact", new IntegerValueRule(2, 5, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]).SetValueFormat(OptionFormat.Times); ShowArrowsToOtherPlayersInPact = BooleanOptionItem.Create(1215, "DeathpactShowArrowsToOtherPlayersInPact", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]); ReduceVisionWhileInPact = BooleanOptionItem.Create(1216, "DeathpactReduceVisionWhileInPact", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]); VisionWhileInPact = FloatOptionItem.Create(1217, "DeathpactVisionWhileInPact", new FloatValueRule(0f, 5f, 0.05f), 0.65f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(ReduceVisionWhileInPact).SetValueFormat(OptionFormat.Multiplier); KillDeathpactPlayersOnMeeting = BooleanOptionItem.Create(1218, "DeathpactKillPlayersInDeathpactOnMeeting", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]); PlayersInDeathpactCanCallMeeting = BooleanOptionItem.Create(1219, "DeathpactPlayersInDeathpactCanCallMeeting", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(1220, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deathpact]); } public override void Init() { PlayersInDeathpact.Clear(); DeathpactTime.Clear(); ActiveDeathpacts.Clear(); Playerids.Clear(); } public override void Add(byte playerId) { PlayersInDeathpact.TryAdd(playerId, new HashSet()); DeathpactTime.TryAdd(playerId, 0L); Playerids.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (ShowShapeshiftAnimationsOpt.GetBool() || shapeshifter.PlayerId == target.PlayerId) { return true; } DoDeathpact(shapeshifter, target); return false; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (shapeshifting) { DoDeathpact(shapeshifter, target); } } private static void DoDeathpact(PlayerControl shapeshifter, PlayerControl target) { if (!target.IsAlive() || Pelican.IsEaten(target.PlayerId)) { shapeshifter.Notify(Translator.GetString("DeathpactCouldNotAddTarget")); return; } if (!PlayersInDeathpact[shapeshifter.PlayerId].Any((PlayerControl b) => b.PlayerId == target.PlayerId)) { PlayersInDeathpact[shapeshifter.PlayerId].Add(target); } if (PlayersInDeathpact[shapeshifter.PlayerId].Count < NumberOfPlayersInPact.GetInt()) { return; } if (ReduceVisionWhileInPact.GetBool()) { Utils.MarkEveryoneDirtySettings(); } shapeshifter.Notify(Translator.GetString("DeathpactComplete")); DeathpactTime[shapeshifter.PlayerId] = Utils.GetTimeStamp() + DeathpactDuration.GetInt(); ActiveDeathpacts.Add(shapeshifter.PlayerId); foreach (PlayerControl player in PlayersInDeathpact[shapeshifter.PlayerId]) { if (ShowArrowsToOtherPlayersInPact.GetBool()) { PlayerControl[] array = PlayersInDeathpact[shapeshifter.PlayerId].Where((PlayerControl a) => a.PlayerId != player.PlayerId).ToArray(); foreach (PlayerControl val in array) { TargetArrow.Add(player.PlayerId, val.PlayerId); } } } } public static void SetDeathpactVision(PlayerControl player, IGameOptions opt) { if (ReduceVisionWhileInPact.GetBool() && PlayersInDeathpact.Any((KeyValuePair> a) => a.Value.Any((PlayerControl b) => b.PlayerId == player.PlayerId) && a.Value.Count == NumberOfPlayersInPact.GetInt())) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, VisionWhileInPact.GetFloat()); opt.SetFloat((FloatOptionNames)3, VisionWhileInPact.GetFloat()); } } public override void OnFixedUpdate(PlayerControl player) { if (!ActiveDeathpacts.Contains(player.PlayerId) || CheckCancelDeathpact(player) || DeathpactTime[player.PlayerId] >= Utils.GetTimeStamp() || DeathpactTime[player.PlayerId] == 0L) { return; } foreach (PlayerControl item in PlayersInDeathpact[player.PlayerId]) { KillPlayerInDeathpact(player, item); } ClearDeathpact(player.PlayerId); player.Notify(Translator.GetString("DeathpactExecuted")); } public override bool OnCheckStartMeeting(PlayerControl reporter) { if (PlayersInDeathpactCanCallMeeting.GetBool()) { return true; } return !IsInActiveDeathpact(reporter); } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (PlayersInDeathpactCanCallMeeting.GetBool()) { return true; } return !IsInActiveDeathpact(reporter); } private static bool CheckCancelDeathpact(PlayerControl deathpact) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if (PlayersInDeathpact[deathpact.PlayerId].Any((PlayerControl a) => a.Data.Disconnected || a.Data.IsDead)) { ClearDeathpact(deathpact.PlayerId); deathpact.Notify(Translator.GetString("DeathpactAverted")); return true; } bool flag = true; foreach (PlayerControl player in PlayersInDeathpact[deathpact.PlayerId]) { float num = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(player.Is(Reach.IsReach) ? 2 : Main.NormalOptions.KillDistance, 0, 2)] + 0.5f; PlayerControl[] array = PlayersInDeathpact[deathpact.PlayerId].Where((PlayerControl a) => a.PlayerId != player.PlayerId).ToArray(); foreach (PlayerControl val in array) { float num2 = Vector2.Distance(Vector2.op_Implicit(((Component)player).transform.position), Vector2.op_Implicit(((Component)val).transform.position)); flag = flag && num2 <= num; } } if (flag) { ClearDeathpact(deathpact.PlayerId); deathpact.Notify(Translator.GetString("DeathpactAverted")); } return flag; } private static void KillPlayerInDeathpact(PlayerControl deathpact, PlayerControl target) { if (!((Object)(object)deathpact == (Object)null) && !((Object)(object)target == (Object)null) && !target.Data.Disconnected && target.IsAlive()) { target.SetDeathReason(PlayerState.DeathReason.Suicide); target.RpcMurderPlayer(target); target.SetRealKiller(deathpact); } } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!seer.Is(CustomRoles.Deathpact) || !IsInDeathpact(seer.PlayerId, seen)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed), "◀"); } public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || !ShowArrowsToOtherPlayersInPact.GetBool()) { return string.Empty; } if (seen == null) { seen = seer; } if (seer.PlayerId != seen.PlayerId) { return string.Empty; } if (!IsInActiveDeathpact(seer)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); KeyValuePair>[] array = PlayersInDeathpact.Where((KeyValuePair> a) => ActiveDeathpacts.Contains(a.Key) && a.Value.Any((PlayerControl b) => b.PlayerId == seer.PlayerId)).ToArray(); foreach (KeyValuePair> keyValuePair in array) { PlayerControl[] array2 = keyValuePair.Value.Where((PlayerControl a) => a.PlayerId != seer.PlayerId).ToArray(); foreach (PlayerControl val in array2) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.CrewmateTOHE)), TargetArrow.GetArrows(seer, val.PlayerId))); } } return stringBuilder.ToString(); } public static bool IsInActiveDeathpact(PlayerControl player) { if (ActiveDeathpacts.Count == 0) { return false; } if (PlayersInDeathpact.Any((KeyValuePair> a) => ActiveDeathpacts.Contains(a.Key) && a.Value.Any((PlayerControl b) => b.PlayerId == player.PlayerId))) { return true; } return false; } private static bool IsInDeathpact(byte deathpactId, PlayerControl target) { if (deathpactId != target.PlayerId && PlayersInDeathpact.TryGetValue(deathpactId, out var value)) { return value.Any((PlayerControl a) => a.PlayerId == target.PlayerId); } return false; } public static string GetDeathpactString(PlayerControl player) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) string text = string.Empty; KeyValuePair>[] array = PlayersInDeathpact.Where((KeyValuePair> a) => ActiveDeathpacts.Contains(a.Key) && a.Value.Any((PlayerControl b) => b.PlayerId == player.PlayerId)).ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair> keyValuePair = array[i]; string text2 = string.Empty; PlayerControl[] array2 = keyValuePair.Value.Where((PlayerControl a) => a.PlayerId != player.PlayerId).ToArray(); foreach (PlayerControl val in array2) { text2 = text2 + ((Object)val).name.ToUpper() + ","; } text2 = text2.Remove(text2.Length - 1); int num = (int)(DeathpactTime[keyValuePair.Key] - Utils.GetTimeStamp()); text += Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), string.Format(Translator.GetString("DeathpactActiveDeathpact"), text2, num)); } return text; } private static void ClearDeathpact(byte deathpact) { if (ShowArrowsToOtherPlayersInPact.GetBool()) { foreach (PlayerControl player in PlayersInDeathpact[deathpact]) { PlayerControl[] array = PlayersInDeathpact[deathpact].Where((PlayerControl a) => a.PlayerId != player.PlayerId).ToArray(); foreach (PlayerControl val in array) { TargetArrow.Remove(player.PlayerId, val.PlayerId); } } } DeathpactTime[deathpact] = 0L; ActiveDeathpacts.Remove(deathpact); PlayersInDeathpact[deathpact].Clear(); if (ReduceVisionWhileInPact.GetBool()) { Utils.MarkEveryoneDirtySettings(); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { byte[] array = ActiveDeathpacts.ToArray(); foreach (byte deathpact in array) { if (KillDeathpactPlayersOnMeeting.GetBool()) { PlayerControl val = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.PlayerId == deathpact)); if ((Object)(object)val == (Object)null || val.Data.IsDead) { continue; } foreach (PlayerControl item in PlayersInDeathpact[deathpact]) { KillPlayerInDeathpact(val, item); } } ClearDeathpact(deathpact); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("DeathpactButtonText")); } } internal class Devourer : RoleBase { private static readonly PlayerOutfit ConsumedOutfit = PlayerOutfitExtension.Set(new PlayerOutfit(), "", 15, "", "", "visor_Crack", "", ""); private static readonly Dictionary OriginalPlayerSkins = new Dictionary(); private const int Id = 5500; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem DefaultKillCooldown; private static OptionItem ReduceKillCooldown; private static OptionItem MinKillCooldown; private static OptionItem ShapeshiftCooldown; private static OptionItem HideNameOfConsumedPlayer; private static OptionItem ShowShapeshiftAnimationsOpt; private static readonly Dictionary NowCooldown = new Dictionary(); private static readonly Dictionary> PlayerSkinsCosumed = new Dictionary>(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(5500, TabGroup.ImpostorRoles, CustomRoles.Devourer); DefaultKillCooldown = FloatOptionItem.Create(5510, GeneralOption.DefaultKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]).SetValueFormat(OptionFormat.Seconds); ReduceKillCooldown = FloatOptionItem.Create(5511, GeneralOption.ReduceKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]).SetValueFormat(OptionFormat.Seconds); MinKillCooldown = FloatOptionItem.Create(5512, GeneralOption.MinKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(5514, "DevourCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]).SetValueFormat(OptionFormat.Seconds); HideNameOfConsumedPlayer = BooleanOptionItem.Create(5516, "DevourerHideNameConsumed", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(5517, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Devourer]); } public override void Init() { PlayerSkinsCosumed.Clear(); OriginalPlayerSkins.Clear(); NowCooldown.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerSkinsCosumed.TryAdd(playerId, new List()); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); PlayerIds.Add(playerId); } public override void Remove(byte playerId) { OnDevourerDied(Utils.GetPlayerById(playerId)); PlayerSkinsCosumed.Remove(playerId); NowCooldown.Remove(playerId); PlayerIds.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = NowCooldown[id]; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (ShowShapeshiftAnimationsOpt.GetBool() || shapeshifter.PlayerId == target.PlayerId) { return true; } DoEatSkin(shapeshifter, target); return false; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (shapeshifting) { DoEatSkin(shapeshifter, target); } } private static void DoEatSkin(PlayerControl shapeshifter, PlayerControl target) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!PlayerSkinsCosumed[shapeshifter.PlayerId].Contains(target.PlayerId)) { if (!Camouflage.IsCamouflage) { target.SetNewOutfit(ConsumedOutfit, setName: false, setNamePlate: false); } PlayerSkinsCosumed[shapeshifter.PlayerId].Add(target.PlayerId); shapeshifter.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Devourer)), Translator.GetString("DevourerEatenSkin"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Devourer)), Translator.GetString("EatenByDevourer"))); OriginalPlayerSkins.Add(target.PlayerId, Camouflage.PlayerSkins[target.PlayerId]); Camouflage.PlayerSkins[target.PlayerId] = ConsumedOutfit; float num = ReduceKillCooldown.GetFloat() * (float)PlayerSkinsCosumed[shapeshifter.PlayerId].Count; float num2 = DefaultKillCooldown.GetFloat() - num; NowCooldown[shapeshifter.PlayerId] = ((num2 < MinKillCooldown.GetFloat()) ? MinKillCooldown.GetFloat() : num2); } } public static bool HideNameOfTheDevoured(byte targetId) { if (HideNameOfConsumedPlayer.GetBool()) { return PlayerSkinsCosumed.Any((KeyValuePair> a) => a.Value.Contains(targetId)); } return false; } private static void OnDevourerDied(PlayerControl devourer) { if ((Object)(object)devourer == (Object)null) { return; } byte playerId = devourer.PlayerId; foreach (byte player in PlayerSkinsCosumed[playerId]) { Camouflage.PlayerSkins[player] = OriginalPlayerSkins[player]; if (!Camouflage.IsCamouflage) { PlayerControl val = ((IEnumerable)Main.AllAlivePlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.PlayerId == player)); if (!((Object)(object)val == (Object)null)) { val.SetNewOutfit(OriginalPlayerSkins[player], setName: false, setNamePlate: false); } } } PlayerSkinsCosumed[playerId].Clear(); } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl devourer, bool inMeeting, bool isSuicide) { OnDevourerDied(devourer); } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { if ((Object)(object)exiled != (Object)null && exiled.Object.Is(CustomRoles.Devourer)) { OnDevourerDied(exiled.Object); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("DevourerButtonText")); } } internal class Disperser : RoleBase { private const int Id = 24400; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem DisperserShapeshiftCooldown; private static OptionItem DisperserShapeshiftDuration; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(24400, TabGroup.ImpostorRoles, CustomRoles.Disperser); DisperserShapeshiftCooldown = FloatOptionItem.Create(24405, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disperser]).SetValueFormat(OptionFormat.Seconds); DisperserShapeshiftDuration = FloatOptionItem.Create(24407, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 60f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Disperser]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = DisperserShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = DisperserShapeshiftDuration.GetFloat(); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!val.CanBeTeleported()) { val.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Disperser)), Translator.GetString("ErrorTeleport"))); continue; } val.RPCPlayCustomSound("Teleport"); val.RpcRandomVentTeleport(); val.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Disperser)), Translator.GetString("TeleportedInRndVentByDisperser"))); } return false; } } internal class DollMaster : RoleBase { private const int Id = 28500; private static readonly HashSet ReducedVisionPlayers = new HashSet(); public static bool IsControllingPlayer = false; private static bool ResetPlayerSpeed = false; private static bool WaitToUnPossess = false; public static PlayerControl controllingTarget = null; public static PlayerControl DollMasterTarget = null; private static float originalSpeed = float.MinValue; private static Vector2 controllingTargetPos = new Vector2(0f, 0f); private static Vector2 DollMasterPos = new Vector2(0f, 0f); private static OptionItem DefaultKillCooldown; private static OptionItem ShapeshiftCooldown; private static OptionItem ShapeshiftDuration; public static OptionItem CanKillAsMainBody; public static OptionItem TargetDiesAfterPossession; public static bool HasEnabled => CustomRoles.DollMaster.HasEnabled(); public override bool IsExperimental => true; public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(28500, TabGroup.ImpostorRoles, CustomRoles.DollMaster); DefaultKillCooldown = FloatOptionItem.Create(28510, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DollMaster]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(28511, "DollMasterPossessionCooldown", new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DollMaster]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDuration = FloatOptionItem.Create(28512, "DollMasterPossessionDuration", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DollMaster]).SetValueFormat(OptionFormat.Seconds); CanKillAsMainBody = BooleanOptionItem.Create(28513, "DollMasterCanKillAsMainBody", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DollMaster]); TargetDiesAfterPossession = BooleanOptionItem.Create(28514, "DollMasterTargetDiesAfterPossession", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DollMaster]); } public override void Init() { ReducedVisionPlayers.Clear(); DollMasterTarget = null; controllingTarget = null; } public override void Add(byte playerId) { DollMasterTarget = Utils.GetPlayerById(playerId); IsControllingPlayer = false; CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(CheckIfPlayerDC); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetFloat() + 0.35f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = DefaultKillCooldown.GetFloat(); } public static bool IsDoll(byte id) { return ReducedVisionPlayers.Contains(id); } public static void ApplySettingsToDoll(IGameOptions opt, PlayerControl target) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, 0f); opt.SetFloat((FloatOptionNames)3, 0f); } public override void OnFixedUpdate(PlayerControl pc) { if ((Object)(object)controllingTarget != (Object)null && (Object)(object)DollMasterTarget != (Object)null) { WaitToUnPossessUpdate(DollMasterTarget, controllingTarget); } } private static void OnFixedUpdateOthers(PlayerControl target) { if ((Object)(object)controllingTarget != (Object)null && (Object)(object)target == (Object)(object)controllingTarget) { BootPossessedPlayerFromVentUpdate(target); if (IsControllingPlayer && Main.AllPlayerSpeed[target.PlayerId] >= 0.0001f) { Main.AllPlayerSpeed[target.PlayerId] = 0.0001f; target.MarkDirtySettings(); } else if (ResetPlayerSpeed) { Main.AllPlayerSpeed[target.PlayerId] = originalSpeed; target.MarkDirtySettings(); } } } private static void BootPossessedPlayerFromVentUpdate(PlayerControl target) { if (!IsControllingPlayer || !target.inVent || target.walkingToVent) { return; } new LateTask(delegate { if (target.inVent && !target.walkingToVent) { target.MyPhysics.RpcBootFromVent(target.GetPlayerVentId()); } }, 0.25f, "Boot Possessed Player from vent: " + target.GetPlayerVentId()); } private static void WaitToUnPossessUpdate(PlayerControl pc, PlayerControl target) { if (!IsControllingPlayer || !WaitToUnPossess) { return; } if (pc.inVent && !pc.walkingToVent && !pc.MyPhysics.Animations.IsPlayingEnterVentAnimation()) { new LateTask(delegate { if (pc.inVent && !pc.walkingToVent && !pc.MyPhysics.Animations.IsPlayingEnterVentAnimation()) { pc.MyPhysics.RpcBootFromVent(pc.GetPlayerVentId()); } }, 0.3f, "Boot DollMaster from vent: " + pc.GetPlayerVentId()); } if (!pc.CanBeTeleported() || !target.CanBeTeleported()) { return; } new LateTask(delegate { if (WaitToUnPossess) { UnPossess(pc, target); GetPlayersPositions(pc); SwapPlayersPositions(pc); } }, 0.15f, "UnPossess"); } public override void OnReportDeadBody(PlayerControl pc, NetworkedPlayerInfo target) { if (IsControllingPlayer && (Object)(object)controllingTarget != (Object)null && (Object)(object)DollMasterTarget != (Object)null) { UnPossess(DollMasterTarget, controllingTarget); Main.AllPlayerSpeed[controllingTarget.PlayerId] = originalSpeed; ReducedVisionPlayers.Clear(); } } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if ((Object)(object)controllingTarget == (Object)null || (Object)(object)DollMasterTarget == (Object)null) { return true; } if (IsControllingPlayer && IsDoll(reporter.PlayerId)) { return false; } if (IsControllingPlayer && reporter.Is(CustomRoles.DollMaster)) { UnPossess(DollMasterTarget, controllingTarget); GetPlayersPositions(DollMasterTarget); SwapPlayersPositions(DollMasterTarget); controllingTarget.CmdReportDeadBody(deadBody); return false; } return true; } public override bool OnCheckStartMeeting(PlayerControl reporter) { if ((Object)(object)controllingTarget == (Object)null || (Object)(object)DollMasterTarget == (Object)null) { return true; } if (IsControllingPlayer && IsDoll(reporter.PlayerId)) { return false; } if (IsControllingPlayer && reporter.Is(CustomRoles.DollMaster)) { UnPossess(DollMasterTarget, controllingTarget); GetPlayersPositions(DollMasterTarget); SwapPlayersPositions(DollMasterTarget); controllingTarget.CmdReportDeadBody((NetworkedPlayerInfo)null); return false; } return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (IsControllingPlayer) { return !((Object)(object)target == (Object)(object)DollMasterTarget); } return true; } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (IsControllingPlayer && (Object)(object)DollMasterTarget != (Object)null && (Object)(object)controllingTarget != (Object)null) { if (!CanKillerUseAbility(killer)) { return true; } if (killer.GetCustomRole().IsImpostorTeam() && (Object)(object)target == (Object)(object)controllingTarget) { return true; } if (killer.Is(CustomRoles.Sheriff) && (Object)(object)killer != (Object)(object)DollMasterTarget && (Object)(object)target == (Object)(object)DollMasterTarget) { CheckMurderAsPossessed(killer, target); return true; } } return false; } private static bool CanKillerUseAbility(PlayerControl player) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) bool flag = true; CustomRoles customRole = player.GetCustomRole(); player.GetCustomSubRoles(); switch (customRole) { case CustomRoles.Pelican: flag = false; break; case CustomRoles.Penguin: flag = false; break; } if (!flag) { player.Notify(Utils.ColorString(Color32.op_Implicit(player.GetRoleColor()), Translator.GetString("DollMaster_UnableToUseAbility"))); } return flag; } public static void CheckMurderAsPossessed(PlayerControl killer, PlayerControl target) { if (IsControllingPlayer && !((Object)(object)controllingTarget == (Object)null) && !((Object)(object)DollMasterTarget == (Object)null)) { if ((Object)(object)target == (Object)(object)controllingTarget) { target.RpcSetPet(""); UnPossess(DollMasterTarget, controllingTarget); GetPlayersPositions(DollMasterTarget); SwapPlayersPositions(DollMasterTarget); killer.RpcMurderPlayer(controllingTarget); } else if ((Object)(object)target == (Object)(object)DollMasterTarget) { DollMasterTarget.RpcSetPet(""); UnPossess(DollMasterTarget, controllingTarget); GetPlayersPositions(DollMasterTarget); SwapPlayersPositions(DollMasterTarget); killer.RpcMurderPlayer(DollMasterTarget); } } } public override bool CanUseKillButton(PlayerControl pc) { if (!CanKillAsMainBody.GetBool()) { return IsControllingPlayer; } return true; } public override bool OnCheckShapeshift(PlayerControl pc, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (WaitToUnPossess) { return false; } if ((Object)(object)target == (Object)null) { return false; } shouldAnimate = false; resetCooldown = false; if (!pc.CanBeTeleported() && IsControllingPlayer) { WaitToUnPossess = true; return false; } if ((Object)(object)controllingTarget != (Object)null && !controllingTarget.CanBeTeleported() && IsControllingPlayer) { WaitToUnPossess = true; return false; } if (!IsControllingPlayer && target.GetCustomRole().IsImpostorTeam()) { AURoleOptions.ShapeshifterCooldown = 0f; pc.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.DollMaster)), Translator.GetString("DollMaster_CannotPossessImpTeammate"))); return false; } if (!target.CanBeTeleported() || Pelican.IsEaten(pc.PlayerId) || Pelican.IsEaten(target.PlayerId)) { AURoleOptions.ShapeshifterCooldown = 0f; pc.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.DollMaster)), target.IsAlive() ? Translator.GetString("DollMaster_CouldNotSwapWithTarget") : Translator.GetString("DollMaster_CanNotSwapWithDeadTarget"))); return false; } ReducedVisionPlayers.Add(target.PlayerId); if (!IsControllingPlayer) { if ((Object)(object)target != (Object)null) { controllingTarget = target; } originalSpeed = Main.AllPlayerSpeed[target.PlayerId]; IsControllingPlayer = true; new LateTask(delegate { if (GameStates.IsMeeting || GameStates.IsExilling) { IsControllingPlayer = false; } else { Possess(pc, target); GetPlayersPositions(pc); SwapPlayersPositions(pc); } }, 0.35f); return false; } if ((Object)(object)controllingTarget != (Object)null) { UnPossess(pc, controllingTarget); GetPlayersPositions(pc); SwapPlayersPositions(pc); } return false; } public static void CheckIfPlayerDC(PlayerControl player) { if (IsControllingPlayer && ((Object)(object)controllingTarget == (Object)null || (Object)(object)DollMasterTarget == (Object)null)) { ReducedVisionPlayers.Clear(); if ((Object)(object)controllingTarget != (Object)null) { Main.AllPlayerSpeed[controllingTarget.PlayerId] = originalSpeed; controllingTarget.MarkDirtySettings(); } PlayerControl dollMasterTarget = DollMasterTarget; if (dollMasterTarget != null) { dollMasterTarget.RpcShapeshift(DollMasterTarget, false); } controllingTarget?.ResetPlayerOutfit(); IsControllingPlayer = false; ResetPlayerSpeed = true; } } private static void Possess(PlayerControl pc, PlayerControl target, bool shouldAnimate = false) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) PlayerPhysics myPhysics = target.MyPhysics; PlayerPhysics myPhysics2 = pc.MyPhysics; bool flipX = pc.MyPhysics.FlipX; bool flipX2 = target.MyPhysics.FlipX; myPhysics.FlipX = flipX; myPhysics2.FlipX = flipX2; if (pc != null) { pc.RpcShapeshift(target, false); } RpcChangeSkin(pc, target); RpcChangeSkin(target, pc); RPC.SyncAllPlayerNames(); pc?.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.DollMaster)), Translator.GetString("DollMaster_PossessedTarget"))); } private static void UnPossess(PlayerControl pc, PlayerControl target, bool shouldAnimate = false) { PlayerPhysics myPhysics = target.MyPhysics; PlayerPhysics myPhysics2 = pc.MyPhysics; bool flipX = pc.MyPhysics.FlipX; bool flipX2 = target.MyPhysics.FlipX; myPhysics.FlipX = flipX; myPhysics2.FlipX = flipX2; if (pc != null) { pc.RpcShapeshift(pc, false); } RpcChangeSkin(pc); RpcChangeSkin(target); IsControllingPlayer = false; ResetPlayerSpeed = true; new LateTask(delegate { ReducedVisionPlayers.Clear(); if (TargetDiesAfterPossession.GetBool() && !GameStates.IsMeeting) { target.RpcMurderPlayer(target); } }, 0.45f); } public static PlayerControl SwapPlayerInfo(PlayerControl player) { if (IsControllingPlayer && HasEnabled && (Object)(object)DollMasterTarget != (Object)null && (Object)(object)controllingTarget != (Object)null) { if ((Object)(object)player == (Object)(object)DollMasterTarget) { return controllingTarget; } if ((Object)(object)player == (Object)(object)controllingTarget) { return DollMasterTarget; } } return player; } private static void GetPlayersPositions(PlayerControl pc) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)controllingTarget == (Object)null)) { controllingTargetPos = controllingTarget.GetCustomPosition(); DollMasterPos = pc.GetCustomPosition(); } } private static void SwapPlayersPositions(PlayerControl pc) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)controllingTarget == (Object)null)) { controllingTarget?.RpcTeleport(DollMasterPos); pc?.RpcTeleport(controllingTargetPos); } } private static void RpcChangeSkin(PlayerControl player, PlayerControl target = null, PlayerOutfit Outfit = null) { if (target == null) { target = player; } if (Outfit == null) { Outfit = Main.PlayerStates[target.PlayerId].NormalOutfit; } if (player.CheckCamoflague()) { Main.LateOutfits[target.PlayerId] = Setoutfit; } else { Setoutfit(); } void Setoutfit() { //IL_039b: Unknown result type (might be due to invalid IL or missing references) CustomRpcSender customRpcSender = CustomRpcSender.Create("Reset PlayerOufit for 『" + player.Data.PlayerName + "』", (SendOption)0); player.SetName(Outfit.PlayerName); player.Data.DefaultOutfit.PlayerName = Main.PlayerStates[player.PlayerId].NormalOutfit.PlayerName; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 6).Write(((InnerNetObject)player.Data).NetId).Write(Outfit.PlayerName) .EndRpc(); Main.AllPlayerNames[player.PlayerId] = Outfit.PlayerName; player.SetColor(Outfit.ColorId); player.Data.DefaultOutfit.ColorId = Main.PlayerStates[player.PlayerId].NormalOutfit.ColorId; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 8).Write(((InnerNetObject)player.Data).NetId).Write((byte)Outfit.ColorId) .EndRpc(); player.SetHat(Outfit.HatId, Outfit.ColorId); player.Data.DefaultOutfit.HatId = Main.PlayerStates[player.PlayerId].NormalOutfit.HatId; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 39).Write(Outfit.HatId).Write(player.GetNextRpcSequenceId((RpcCalls)39)) .EndRpc(); player.SetSkin(Outfit.SkinId, Outfit.ColorId); player.Data.DefaultOutfit.SkinId = Main.PlayerStates[player.PlayerId].NormalOutfit.SkinId; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 40).Write(Outfit.SkinId).Write(player.GetNextRpcSequenceId((RpcCalls)40)) .EndRpc(); player.SetVisor(Outfit.VisorId, Outfit.ColorId); player.Data.DefaultOutfit.VisorId = Main.PlayerStates[player.PlayerId].NormalOutfit.VisorId; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 42).Write(Outfit.VisorId).Write(player.GetNextRpcSequenceId((RpcCalls)42)) .EndRpc(); player.SetPet(Outfit.PetId); player.Data.DefaultOutfit.PetId = Main.PlayerStates[player.PlayerId].NormalOutfit.PetId; customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 41).Write(Outfit.PetId).Write(player.GetNextRpcSequenceId((RpcCalls)41)) .EndRpc(); customRpcSender.SendMessage(); _ = player.CurrentOutfitType; _ = 1; Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { ((InnerNetObject)enumerator.Current).SetDirtyBit(uint.MaxValue); } } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { if (!IsControllingPlayer || GameStates.IsMeeting || isForMeeting) { return string.Empty; } if ((Object)(object)controllingTarget == (Object)null || (Object)(object)DollMasterTarget == (Object)null || (Object)(object)target == (Object)null) { return string.Empty; } if (seer.PlayerId != target.PlayerId && target.PlayerId == controllingTarget.PlayerId) { return "" + Translator.GetString("DollMaster_MainBody") + ""; } if (seer.PlayerId == target.PlayerId && target.PlayerId == DollMasterTarget.PlayerId) { return "" + Translator.GetString("DollMaster_Doll") + ""; } return string.Empty; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString(IsControllingPlayer ? "DollMasterUnPossessionButtonText" : "DollMasterPossessionButtonText")); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Puttpuer"); } } internal class Eraser : RoleBase { private const int Id = 24200; private static OptionItem EraseLimitOpt; public static OptionItem HideVoteOpt; private static readonly HashSet didVote = new HashSet(); private static readonly HashSet PlayerToErase = new HashSet(); private static int TempEraseLimit; public static readonly Dictionary ErasedRoleStorage = new Dictionary(); public static bool HasEnabled => CustomRoles.Eraser.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(24200, TabGroup.ImpostorRoles, CustomRoles.Eraser); EraseLimitOpt = IntegerOptionItem.Create(24210, "EraseLimit", new IntegerValueRule(1, 15, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]).SetValueFormat(OptionFormat.Times); HideVoteOpt = BooleanOptionItem.Create(24211, "EraserHideVote", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Eraser]); } public override void Init() { PlayerToErase.Clear(); didVote.Clear(); ErasedRoleStorage.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = EraseLimitOpt.GetInt(); } public override string GetProgressText(byte playerId, bool comms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Eraser) : Color.gray), $"({base.AbilityLimit})"); } public override bool HideVote(PlayerVoteArea votedPlayer) { if (HideVoteOpt.GetBool()) { return TempEraseLimit > 0; } return false; } public override void OnVote(PlayerControl player, PlayerControl target) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) if (!HasEnabled || (Object)(object)player == (Object)null || (Object)(object)target == (Object)null || target.Is(CustomRoles.Eraser) || base.AbilityLimit < 1f || didVote.Contains(player.PlayerId)) { return; } didVote.Add(player.PlayerId); Logger.Info($"{player.GetCustomRole()} votes for {target.GetCustomRole()}", "Vote Eraser", escapeCRLF: true, 60, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Eraser.cs"); if (target.PlayerId == player.PlayerId) { Utils.SendMessage(Translator.GetString("EraserEraseSelf"), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Eraser)), Translator.GetString("EraserEraseMsgTitle"))); return; } CustomRoles customRole = target.GetCustomRole(); if (customRole.IsTasklessCrewmate() || customRole.IsNeutral() || Main.TasklessCrewmate.Contains(target.PlayerId) || CopyCat.playerIdList.Contains(target.PlayerId) || target.Is(CustomRoles.Stubborn)) { Logger.Info("Cannot erase role because is Impostor Based or Neutral or ect", "Eraser", escapeCRLF: true, 71, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Eraser.cs"); Utils.SendMessage(string.Format(Translator.GetString("EraserEraseBaseImpostorOrNeutralRoleNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Eraser)), Translator.GetString("EraserEraseMsgTitle"))); return; } base.AbilityLimit--; SendSkillRPC(); if (!PlayerToErase.Contains(target.PlayerId)) { PlayerToErase.Add(target.PlayerId); } Utils.SendMessage(string.Format(Translator.GetString("EraserEraseNotice"), target.GetRealName()), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Eraser)), Translator.GetString("EraserEraseMsgTitle"))); Utils.NotifyRoles(player); } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (PlayerToErase.Contains(target.PlayerId) && !role.IsAdditionRole()) { guesser.ShowInfoMessage(isUI, Translator.GetString("EraserTryingGuessErasedPlayer")); return true; } return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { TempEraseLimit = (int)base.AbilityLimit; didVote.Clear(); } public override void NotifyAfterMeeting() { byte[] array = PlayerToErase.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!((Object)(object)playerById == (Object)null)) { playerById.RPCPlayCustomSound("Oiiai"); playerById.Notify(Translator.GetString("LostRoleByEraser")); } } } public override void AfterMeetingTasks() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) byte[] array = PlayerToErase.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!((Object)(object)playerById == (Object)null)) { if (ErasedRoleStorage.ContainsKey(playerById.PlayerId)) { Logger.Info("Canceled " + playerById.GetNameWithRole() + " Eraser bcz already erased.", "Eraser", escapeCRLF: true, 124, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Eraser.cs"); return; } ErasedRoleStorage.Add(playerById.PlayerId, playerById.GetCustomRole()); Logger.Info("Added " + playerById.GetNameWithRole() + " to ErasedRoleStorage", "Eraser", escapeCRLF: true, 120, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Eraser.cs"); playerById.RpcSetCustomRole(GetErasedRole(playerById.GetCustomRole().GetRoleTypes(), playerById.GetCustomRole())); playerById.ResetKillCooldown(); playerById.SetKillCooldown(); Logger.Info(playerById.GetNameWithRole() + " Erase by Eraser", "Eraser", escapeCRLF: true, 130, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Eraser.cs"); } } Utils.MarkEveryoneDirtySettings(); } public static CustomRoles GetErasedRole(RoleTypes roleType, CustomRoles role) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected I4, but got Unknown if (role.IsVanilla()) { return role; } return (int)roleType switch { 0 => CustomRoles.CrewmateTOHE, 2 => CustomRoles.ScientistTOHE, 3 => CustomRoles.EngineerTOHE, 1 => CustomRoles.ImpostorTOHE, 5 => CustomRoles.ShapeshifterTOHE, _ => role, }; } } internal class Escapist : RoleBase { private const int Id = 4000; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem ShapeshiftDuration; private static OptionItem ShapeshiftCooldown; private static readonly Dictionary EscapeLocation = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("abscond"); } public override void SetupCustomOption() { Options.SetupRoleOptions(4000, TabGroup.ImpostorRoles, CustomRoles.Escapist); ShapeshiftDuration = FloatOptionItem.Create(4002, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Escapist]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(4003, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Escapist]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { EscapeLocation.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetFloat(); AURoleOptions.ShapeshifterCooldown = (EscapeLocation.ContainsKey(playerId) ? ShapeshiftCooldown.GetFloat() : 1f); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } if (EscapeLocation.TryGetValue(shapeshifter.PlayerId, out var value)) { EscapeLocation.Remove(shapeshifter.PlayerId); Logger.Info($"{shapeshifter.GetNameWithRole()}:{value}", "Escapist Teleport", escapeCRLF: true, 58, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Escapist.cs"); shapeshifter.RpcTeleport(value); shapeshifter.RPCPlayCustomSound("Teleport"); } else { EscapeLocation.Add(shapeshifter.PlayerId, shapeshifter.GetCustomPosition()); shapeshifter.SyncSettings(); shapeshifter.Notify(Translator.GetString("EscapisMtarkedPosition")); } return false; } } internal class EvilGuesser : RoleBase { private const int Id = 1300; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem EGCanGuessTime; private static OptionItem EGCanGuessImp; private static OptionItem EGCanGuessAdt; private static OptionItem EGTryHideMsg; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(1300, TabGroup.ImpostorRoles, CustomRoles.EvilGuesser); EGCanGuessTime = IntegerOptionItem.Create(1302, "GuesserCanGuessTimes", new IntegerValueRule(1, 15, 1), 15, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilGuesser]).SetValueFormat(OptionFormat.Times); EGCanGuessImp = BooleanOptionItem.Create(1303, "EGCanGuessImp", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilGuesser]); EGCanGuessAdt = BooleanOptionItem.Create(1304, "EGCanGuessAdt", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilGuesser]); EGTryHideMsg = BooleanOptionItem.Create(1306, "GuesserTryHideMsg", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilGuesser]).SetColor(Color.green); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.EvilGuesser)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public static bool NeedHideMsg(PlayerControl pc) { if (pc.Is(CustomRoles.EvilGuesser)) { return EGTryHideMsg.GetBool(); } return false; } public static bool HideTabInGuesserUI(int TabId) { if (!EGCanGuessImp.GetBool() && TabId == 1) { return true; } if (!EGCanGuessAdt.GetBool() && TabId == 3) { return true; } return false; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (GuessManager.GuesserGuessed[guesser.PlayerId] >= EGCanGuessTime.GetInt()) { guesser.ShowInfoMessage(isUI, Translator.GetString("EGGuessMax")); return true; } if (role.IsAdditionRole() && !EGCanGuessAdt.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } if (role.IsImpostor() && !EGCanGuessImp.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessImpRole")); return true; } return false; } } internal class EvilHacker : RoleBase { public enum OptionName { EvilHackerCanSeeDeadMark, EvilHackerCanSeeImpostorMark, EvilHackerCanSeeKillFlash, EvilHackerCanSeeMurderRoom } private readonly struct MurderNotify { public DateTime CreatedAt { get; init; } public SystemTypes Room { get; init; } } private const int Id = 28400; private static OptionItem OptionCanSeeDeadMark; private static OptionItem OptionCanSeeImpostorMark; private static OptionItem OptionCanSeeKillFlash; private static OptionItem OptionCanSeeMurderRoom; private static byte player = 0; private static bool canSeeDeadMark; private static bool canSeeImpostorMark; private static bool canSeeKillFlash; private static bool canSeeMurderRoom; private static PlayerControl evilHackerPlayer = null; private static readonly HashSet activeNotifies = new HashSet(2); private static readonly TimeSpan NotifyDuration = TimeSpan.FromSeconds(10.0); public static bool HasEnabled => CustomRoles.EvilHacker.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(28400, TabGroup.ImpostorRoles, CustomRoles.EvilHacker); OptionCanSeeDeadMark = BooleanOptionItem.Create(28410, OptionName.EvilHackerCanSeeDeadMark, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilHacker]); OptionCanSeeImpostorMark = BooleanOptionItem.Create(28411, OptionName.EvilHackerCanSeeImpostorMark, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilHacker]); OptionCanSeeKillFlash = BooleanOptionItem.Create(28412, OptionName.EvilHackerCanSeeKillFlash, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilHacker]); OptionCanSeeMurderRoom = BooleanOptionItem.Create(28413, OptionName.EvilHackerCanSeeMurderRoom, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(OptionCanSeeKillFlash); } public override void Init() { evilHackerPlayer = null; canSeeDeadMark = OptionCanSeeDeadMark.GetBool(); canSeeImpostorMark = OptionCanSeeImpostorMark.GetBool(); canSeeKillFlash = OptionCanSeeKillFlash.GetBool(); canSeeMurderRoom = OptionCanSeeMurderRoom.GetBool(); } public override void Add(byte playerId) { player = playerId; evilHackerPlayer = Utils.GetPlayerById(playerId); CustomRoleManager.CheckDeadBodyOthers.Add(HandleMurderRoomNotify); } private void HandleMurderRoomNotify(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (canSeeMurderRoom && !(!evilHackerPlayer.IsAlive() || inMeeting) && CheckKillFlash(killer, target) && killer.PlayerId != evilHackerPlayer.PlayerId) { PlainShipRoom plainShipRoom = target.GetPlainShipRoom(); RpcCreateMurderNotify((SystemTypes)((plainShipRoom != null) ? ((int)plainShipRoom.RoomId) : 0)); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!evilHackerPlayer.IsAlive()) { return; } SortedDictionary sortedDictionary = AdminProvider.CalculateAdmin(); StringBuilder stringBuilder = new StringBuilder(512); foreach (KeyValuePair item in sortedDictionary) { AdminProvider.AdminEntry value = item.Value; if (value.TotalPlayers > 0) { if (canSeeImpostorMark && value.NumImpostors > 0) { string value2 = StringExtensions.Color("★", Palette.ImpostorRed); stringBuilder.Append(value2); } stringBuilder.Append(DestroyableSingleton.Instance.GetString(value.Room)); stringBuilder.Append(": "); stringBuilder.Append(value.TotalPlayers); if (canSeeDeadMark && value.NumDeadBodies > 0) { stringBuilder.Append(' ').Append('(').Append(Translator.GetString("EvilHackerDeadbody")); stringBuilder.Append('×').Append(value.NumDeadBodies).Append(')'); } stringBuilder.Append('\n'); } } string message = stringBuilder.ToString(); string title = Utils.ColorString(Color32.op_Implicit(Color.green), Translator.GetString("EvilHackerLastAdminInfoTitle")); new LateTask(delegate { if (GameStates.IsInGame) { Utils.SendMessage(message, evilHackerPlayer.PlayerId, title); } }, 5f, "EvilHacker Admin Message"); } public override bool KillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { if (CheckKillFlash(killer, target)) { return killer.PlayerId != seer.PlayerId; } return false; } private static void RpcCreateMurderNotify(SystemTypes room) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) CreateMurderNotify(room); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { SendRPC(0, room); } } private static void SendRPC(byte RpcTypeId, SystemTypes room) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected I4, but got Unknown MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)Utils.GetPlayerById(player)); val.Write(RpcTypeId); val.Write((byte)(int)room); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) byte b = reader.ReadByte(); SystemTypes room = (SystemTypes)reader.ReadByte(); switch (b) { case 0: CreateMurderNotify(room); break; case 1: { foreach (MurderNotify activeNotify in activeNotifies) { if (DateTime.Now - activeNotify.CreatedAt > NotifyDuration) { activeNotifies.Remove(activeNotify); } } break; } } } private static void CreateMurderNotify(SystemTypes room) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) activeNotifies.Add(new MurderNotify { CreatedAt = DateTime.Now, Room = room }); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Utils.NotifyRoles(evilHackerPlayer); } } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if (!activeNotifies.Any()) { return; } bool flag = false; foreach (MurderNotify activeNotify in activeNotifies) { if (DateTime.Now - activeNotify.CreatedAt > NotifyDuration) { activeNotifies.Remove(activeNotify); flag = true; } } if (flag) { Utils.NotifyRoles(evilHackerPlayer); SendRPC(1, (SystemTypes)0); } } public override string GetSuffix(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!canSeeMurderRoom || seer.PlayerId != seen.PlayerId || isForMeeting || !activeNotifies.Any()) { return string.Empty; } IEnumerable values = activeNotifies.Select((MurderNotify notify) => DestroyableSingleton.Instance.GetString(notify.Room)); return Utils.ColorString(Color32.op_Implicit(Color.green), Translator.GetString("EvilHackerMurderNotify") + ": " + string.Join(", ", values)); } public static bool CheckKillFlash(PlayerControl killer, PlayerControl target) { if (canSeeKillFlash) { return killer.PlayerId != target.PlayerId; } return false; } } internal class EvilTracker : RoleBase { private enum TargetMode { Never, OnceInGame, EveryMeeting, Always } private const int Id = 1400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem OptionCanSeeKillFlash; private static OptionItem OptionTargetMode; private static OptionItem OptionCanSeeLastRoomInMeeting; private static bool CanSeeKillFlash; private static TargetMode CurrentTargetMode; private static bool CanSeeLastRoomInMeeting; private static readonly Dictionary Target = new Dictionary(); private static readonly Dictionary CanSetTarget = new Dictionary(); private static readonly Dictionary> ImpostorsId = new Dictionary>(); private static readonly string[] TargetModeText = new string[4] { "EvilTrackerTargetMode.Never", "EvilTrackerTargetMode.OnceInGame", "EvilTrackerTargetMode.EveryMeeting", "EvilTrackerTargetMode.Always" }; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase { get { if (OptionTargetMode.GetValue() != 0) { return CustomRoles.Shapeshifter; } return CustomRoles.Impostor; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Track"); } public override void SetupCustomOption() { Options.SetupRoleOptions(1400, TabGroup.ImpostorRoles, CustomRoles.EvilTracker); OptionCanSeeKillFlash = BooleanOptionItem.Create(1410, "EvilTrackerCanSeeKillFlash", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilTracker]); OptionTargetMode = StringOptionItem.Create(1411, "EvilTrackerTargetMode", TargetModeText, 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilTracker]); OptionCanSeeLastRoomInMeeting = BooleanOptionItem.Create(1412, "EvilTrackerCanSeeLastRoomInMeeting", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilTracker]); } public override void Init() { playerIdList.Clear(); Target.Clear(); CanSetTarget.Clear(); ImpostorsId.Clear(); CanSeeKillFlash = OptionCanSeeKillFlash.GetBool(); CurrentTargetMode = (TargetMode)OptionTargetMode.GetValue(); CanSeeLastRoomInMeeting = OptionCanSeeLastRoomInMeeting.GetBool(); } public override void Add(byte playerId) { playerIdList.Add(playerId); Target.Add(playerId, byte.MaxValue); CanSetTarget.Add(playerId, CurrentTargetMode != TargetMode.Never); ImpostorsId[playerId] = new HashSet(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { byte playerId2 = val.PlayerId; if (playerId2 != playerId && val.Is(Custom_Team.Impostor)) { ImpostorsId[playerId].Add(playerId2); TargetArrow.Add(playerId, playerId2); } } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = (CanTarget(playerId) ? 1f : 255f); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.AbilityButton).ToggleVisible(CanTarget(id)); ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("EvilTrackerChangeButtonText")); } public override bool KillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { if (CanSeeKillFlash) { return killer.PlayerId != seer.PlayerId; } return false; } private static bool CanTarget(byte playerId) { bool value = default(bool); return !Main.PlayerStates[playerId].IsDead && CanSetTarget.TryGetValue(playerId, out value) && value; } private static byte GetTargetId(byte playerId) { if (!Target.TryGetValue(playerId, out var value)) { return byte.MaxValue; } return value; } public static bool IsTrackTarget(PlayerControl seer, PlayerControl target) { if (seer.IsAlive() && playerIdList.Contains(seer.PlayerId) && target.IsAlive() && (Object)(object)seer != (Object)(object)target) { if (!target.Is(Custom_Team.Impostor)) { return GetTargetId(seer.PlayerId) == target.PlayerId; } return true; } return false; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (target.Is(Custom_Team.Impostor) || !CanTarget(shapeshifter.PlayerId)) { return false; } SetTarget(shapeshifter.PlayerId, target.PlayerId); shapeshifter.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); shapeshifter.SyncSettings(); Logger.Info(shapeshifter.GetNameWithRole() + " target to " + target.GetNameWithRole(), "EvilTrackerTarget", escapeCRLF: true, 121, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\EvilTracker.cs"); Utils.NotifyRoles(shapeshifter, target); return false; } public override void AfterMeetingTasks() { if (CurrentTargetMode == TargetMode.EveryMeeting) { SetTarget(); Utils.MarkEveryoneDirtySettings(); } foreach (byte playerId in playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); PlayerControl playerById2 = Utils.GetPlayerById(GetTargetId(playerId)); if (!playerById.IsAlive() || !playerById2.IsAlive()) { SetTarget(playerId); } playerById?.SyncSettings(); playerById?.RpcResetAbilityCooldown(); } } private static void SetTarget(byte trackerId = byte.MaxValue, byte targetId = byte.MaxValue) { if (trackerId == byte.MaxValue) { foreach (byte playerId in playerIdList) { CanSetTarget[playerId] = true; } } else if (targetId == byte.MaxValue) { Target[trackerId] = byte.MaxValue; } else { Target[trackerId] = targetId; if (CurrentTargetMode != TargetMode.Always) { CanSetTarget[trackerId] = false; } TargetArrow.Add(trackerId, targetId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { SendRPC(trackerId, targetId); } } private static void SendRPC(byte trackerId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)148, (SendOption)1, -1); val.Write(trackerId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte trackerId = reader.ReadByte(); byte targetId = reader.ReadByte(); SetTarget(trackerId, targetId); } public override string GetProgressText(byte PlayerId, bool comms) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!CanTarget(PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed.ShadeColor(0.5f)), "◁"); } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!Target.ContainsValue(seen.PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed.ShadeColor(0.5f)), "◀"); } public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { if (seen == null) { seen = seer; } if (isForMeeting) { if (IsTrackTarget(seer, seen) && CanSeeLastRoomInMeeting) { string arrowAndLastRoom = GetArrowAndLastRoom(seer, seen); if (arrowAndLastRoom.Length != 0) { return "" + arrowAndLastRoom + ""; } return string.Empty; } return string.Empty; } return GetTargetArrow(seer, seen); } private static string GetTargetArrow(PlayerControl seer, PlayerControl target) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsInTask || !target.Is(CustomRoles.EvilTracker)) { return string.Empty; } byte playerId = target.PlayerId; if (seer.PlayerId != playerId) { return string.Empty; } ImpostorsId[playerId].RemoveWhere((byte id) => Main.PlayerStates[id].IsDead); StringBuilder stringBuilder = new StringBuilder(80); if (ImpostorsId[playerId].Any()) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(8, 1, stringBuilder2); handler.AppendLiteral(""); stringBuilder2.Append(ref handler); foreach (byte item in ImpostorsId[playerId]) { stringBuilder.Append(TargetArrow.GetArrows(target, item)); } stringBuilder.Append(""); } byte b = Target[playerId]; if (b != byte.MaxValue) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Color.white), TargetArrow.GetArrows(target, b))); } return stringBuilder.ToString(); } private static string GetArrowAndLastRoom(PlayerControl seer, PlayerControl target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) string text = Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed), TargetArrow.GetArrows(seer, target.PlayerId)); PlainShipRoom lastRoom = Main.PlayerStates[target.PlayerId].LastRoom; if ((Object)(object)lastRoom == (Object)null) { return text + Utils.ColorString(Color32.op_Implicit(Color.gray), "@" + Translator.GetString("FailToTrack")); } string text2 = text; Color32 color = Color32.op_Implicit(Palette.ImpostorRed); SystemTypes roomId = lastRoom.RoomId; return text2 + Utils.ColorString(color, "@" + Translator.GetString(((object)(SystemTypes)(ref roomId)).ToString())); } } internal class Fireworker : RoleBase { private enum FireworkerState { Initial = 1, SettingFireworker = 2, WaitTime = 4, ReadyFire = 8, FireEnd = 16, CanUseKill = 17 } private const int Id = 3200; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem FireworkerCount; private static OptionItem FireworkerRadius; private static OptionItem CanKill; private static readonly Dictionary nowFireworkerCount = new Dictionary(); private static readonly Dictionary> FireworkerPosition = new Dictionary>(); private static readonly Dictionary state = new Dictionary(); private static readonly Dictionary FireworkerBombKill = new Dictionary(); private static int fireworkerCount = 1; private static float fireworkerRadius = 1f; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { if (nowFireworkerCount[player.PlayerId] != 0) { return CustomButton.Get("FireworkP"); } return CustomButton.Get("FireworkD"); } public override void SetupCustomOption() { Options.SetupRoleOptions(3200, TabGroup.ImpostorRoles, CustomRoles.Fireworker); FireworkerCount = IntegerOptionItem.Create(3210, "FireworkerMaxCount", new IntegerValueRule(1, 20, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]).SetValueFormat(OptionFormat.Pieces); FireworkerRadius = FloatOptionItem.Create(3211, "FireworkerRadius", new FloatValueRule(0.5f, 5f, 0.5f), 2f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]).SetValueFormat(OptionFormat.Multiplier); CanKill = BooleanOptionItem.Create(3212, GeneralOption.CanKill, defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]); } public override void Init() { PlayerIds.Clear(); nowFireworkerCount.Clear(); FireworkerPosition.Clear(); state.Clear(); FireworkerBombKill.Clear(); fireworkerCount = FireworkerCount.GetInt(); fireworkerRadius = FireworkerRadius.GetFloat(); } public override void Add(byte playerId) { nowFireworkerCount[playerId] = fireworkerCount; FireworkerPosition[playerId] = new List(); state.TryAdd(playerId, FireworkerState.Initial); FireworkerBombKill[playerId] = 0; PlayerIds.Add(playerId); } private static void SendRPC(byte playerId) { Logger.Info($"Player{playerId}:SendRPC", "Fireworker", escapeCRLF: true, 73, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)146, (SendOption)1, -1); val.Write(playerId); val.Write(nowFireworkerCount[playerId]); val.Write((int)state[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader msg) { byte b = msg.ReadByte(); nowFireworkerCount[b] = msg.ReadInt32(); state[b] = (FireworkerState)msg.ReadInt32(); Logger.Info($"Player{b}:ReceiveRPC", "Fireworker", escapeCRLF: true, 86, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterDuration = ((state[playerId] != FireworkerState.FireEnd) ? 1f : 30f); AURoleOptions.ShapeshifterLeaveSkin = true; } public override bool CanUseKillButton(PlayerControl pc) { if (!state.ContainsKey(pc.PlayerId) || !pc.IsAlive()) { return false; } bool result = false; if ((state[pc.PlayerId] & FireworkerState.CanUseKill) != 0) { result = true; } if (CanKill.GetBool()) { result = true; } return result; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) Logger.Info("Fireworker ShapeShift", "Fireworker", escapeCRLF: true, 113, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); if (shapeshifter.PlayerId == target.PlayerId) { return false; } byte playerId = shapeshifter.PlayerId; switch (state[playerId]) { case FireworkerState.Initial: case FireworkerState.SettingFireworker: Logger.Info("One firework set up", "Fireworker", escapeCRLF: true, 121, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); FireworkerPosition[playerId].Add(((Component)shapeshifter).transform.position); nowFireworkerCount[playerId]--; state[playerId] = ((nowFireworkerCount[playerId] != 0) ? FireworkerState.SettingFireworker : ((Main.AliveImpostorCount <= 1) ? FireworkerState.ReadyFire : FireworkerState.WaitTime)); shapeshifter.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); break; case FireworkerState.ReadyFire: { Logger.Info("Blowing up fireworks", "Fireworker", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); bool flag = false; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { Vector3[] array = FireworkerPosition[playerId].ToArray(); for (int j = 0; j < array.Length; j++) { if (!(Vector2.Distance(Vector2.op_Implicit(array[j]), Vector2.op_Implicit(((Component)val).transform.position)) > fireworkerRadius)) { if ((Object)(object)val == (Object)(object)shapeshifter) { flag = true; continue; } val.SetDeathReason(PlayerState.DeathReason.Bombed); val.RpcMurderPlayer(val); val.SetRealKiller(shapeshifter); } } } if (flag) { if (Main.AllAlivePlayerControls.Length != 1) { playerId.SetDeathReason(PlayerState.DeathReason.Misfire); shapeshifter.RpcMurderPlayer(shapeshifter); } shapeshifter.MarkDirtySettings(); } state[playerId] = FireworkerState.FireEnd; break; } } SendRPC(playerId); Utils.NotifyRoles(); return false; } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { string result = string.Empty; byte playerId = seer.PlayerId; if ((Object)(object)seer == (Object)null || !seer.IsAlive()) { return result; } if (!state.ContainsKey(playerId)) { return result; } if (state[seer.PlayerId] == FireworkerState.WaitTime && Main.AliveImpostorCount <= 1) { Logger.Info("Ready to blow up", "Fireworker", escapeCRLF: true, 182, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Fireworker.cs"); state[playerId] = FireworkerState.ReadyFire; SendRPC(playerId); Utils.NotifyRoles(seer); } switch (state[playerId]) { case FireworkerState.Initial: case FireworkerState.SettingFireworker: result = string.Format(Translator.GetString("FireworkerPutPhase"), nowFireworkerCount[playerId]); break; case FireworkerState.WaitTime: result = Translator.GetString("FireworkerWaitPhase"); break; case FireworkerState.ReadyFire: result = Translator.GetString("FireworkerReadyFirePhase"); break; } return result; } public override void SetAbilityButtonText(HudManager hud, byte id) { if (state[id] == FireworkerState.ReadyFire) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("FireworkerExplosionButtonText")); } else { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("FireworkerInstallAtionButtonText")); } } } internal class Gangster : RoleBase { private const int Id = 3300; private static OptionItem RecruitLimitOpt; private static OptionItem KillCooldown; public static OptionItem SheriffCanBeMadmate; public static OptionItem MayorCanBeMadmate; public static OptionItem NGuesserCanBeMadmate; public static OptionItem JudgeCanBeMadmate; public static OptionItem RetributionistCanBeMadmate; public static OptionItem MarshallCanBeMadmate; public static OptionItem OverseerCanBeMadmate; public static bool HasEnabled => CustomRoles.Gangster.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { if (!CanRecruit(player.PlayerId)) { return null; } return CustomButton.Get("Sidekick"); } public override void SetupCustomOption() { Options.SetupRoleOptions(3300, TabGroup.ImpostorRoles, CustomRoles.Gangster); KillCooldown = FloatOptionItem.Create(3310, "GangsterRecruitCooldown", new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]).SetValueFormat(OptionFormat.Seconds); RecruitLimitOpt = IntegerOptionItem.Create(3312, "GangsterRecruitLimit", new IntegerValueRule(1, 15, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]).SetValueFormat(OptionFormat.Times); SheriffCanBeMadmate = BooleanOptionItem.Create(3314, "GanSheriffCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); MayorCanBeMadmate = BooleanOptionItem.Create(3315, "GanMayorCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); NGuesserCanBeMadmate = BooleanOptionItem.Create(3316, "GanNGuesserCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); JudgeCanBeMadmate = BooleanOptionItem.Create(3317, "GanJudgeCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); MarshallCanBeMadmate = BooleanOptionItem.Create(3318, "GanMarshallCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); RetributionistCanBeMadmate = BooleanOptionItem.Create(3320, "GanRetributionistCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); OverseerCanBeMadmate = BooleanOptionItem.Create(3319, "GanOverseerCanBeMadmate", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gangster]); } public override void Add(byte playerId) { base.AbilityLimit = RecruitLimitOpt.GetInt(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CanRecruit(id) ? KillCooldown.GetFloat() : Options.DefaultKillCooldown); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (CanRecruit(playerId)) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("GangsterButtonText")); } else { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText")); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0629: Unknown result type (might be due to invalid IL or missing references) //IL_062e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_0555: Unknown result type (might be due to invalid IL or missing references) if (!CanRecruit(killer.PlayerId)) { return true; } if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("CantRecruit"))); return true; } if (CanBeGansterRecruit(target)) { if (!killer.Is(CustomRoles.Admired) && !killer.Is(CustomRoles.Recruit) && !killer.Is(CustomRoles.Charmed) && !killer.Is(CustomRoles.Infected) && !killer.Is(CustomRoles.Contagious) && target.CanBeMadmate(forAdmirer: false, forGangster: true)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Madmate, "Ganster Assign", escapeCRLF: true, 80, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Madmate); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("BeRecruitedByGangster"))); } else if (killer.Is(CustomRoles.Admired) && Admirer.CanBeAdmired(target, killer)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Admired, "Ganster Assign", escapeCRLF: true, 87, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Admired); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Admired)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Admired)), Translator.GetString("BeRecruitedByGangster"))); Admirer.AdmiredList[killer.PlayerId].Add(target.PlayerId); Admirer.SendRPC(killer.PlayerId, target.PlayerId); } else if (killer.Is(CustomRoles.Recruit) && Jackal.CanBeSidekick(target)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Recruit, "Ganster Assign", escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Recruit); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Recruit)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Recruit)), Translator.GetString("BeRecruitedByGangster"))); } else if (killer.Is(CustomRoles.Charmed) && Cultist.CanBeCharmed(target)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Charmed, "Ganster Assign", escapeCRLF: true, 103, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Charmed); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Charmed)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Charmed)), Translator.GetString("BeRecruitedByGangster"))); } else if (killer.Is(CustomRoles.Infected) && Infectious.CanBeBitten(target)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Infected, "Ganster Assign", escapeCRLF: true, 110, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Infected); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infected)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infected)), Translator.GetString("BeRecruitedByGangster"))); } else { if (!killer.Is(CustomRoles.Contagious) || !target.CanBeInfected()) { goto IL_0626; } Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Contagious, "Ganster Assign", escapeCRLF: true, 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); target.RpcSetCustomRole(CustomRoles.Contagious); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Contagious)), Translator.GetString("GangsterSuccessfullyRecruited"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Contagious)), Translator.GetString("BeRecruitedByGangster"))); } base.AbilityLimit--; killer.RpcGuardAndKill(target); target.RpcGuardAndKill(killer); killer.ResetKillCooldown(); killer.SetKillCooldown(-1f, null, forceAnime: true); target.ResetKillCooldown(); target.SetKillCooldown(-1f, null, forceAnime: true); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次招募机会", "Gangster", escapeCRLF: true, 134, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); SendSkillRPC(); return false; } goto IL_0626; IL_0626: killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("GangsterRecruitmentFailure"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次招募机会", "Gangster", escapeCRLF: true, 141, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Gangster.cs"); SendSkillRPC(); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); return true; } public override string GetProgressText(byte playerId, bool comms) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CanRecruit(playerId) ? Utils.GetRoleColor(CustomRoles.Gangster).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } private bool CanRecruit(byte id) { return base.AbilityLimit >= 1f; } private static bool CanBeGansterRecruit(PlayerControl pc) { if ((Object)(object)pc != (Object)null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor()) && !pc.Is(CustomRoles.Soulless) && !pc.Is(CustomRoles.Lovers) && !pc.Is(CustomRoles.Loyal) && ((!pc.Is(CustomRoles.NiceMini) && !pc.Is(CustomRoles.EvilMini)) || Mini.Age >= 18)) { if (pc.GetCustomSubRoles().Contains(CustomRoles.Hurried)) { return Hurried.CanBeConverted.GetBool(); } return true; } return false; } } internal class Godfather : RoleBase { private enum GodfatherChangeModeList { GodfatherCount_Refugee, GodfatherCount_Madmate } private const int Id = 3400; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem GodfatherChangeOpt; private static readonly HashSet GodfatherTarget = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3400, TabGroup.ImpostorRoles, CustomRoles.Godfather); GodfatherChangeOpt = StringOptionItem.Create(3402, "GodfatherTargetCountMode", EnumHelper.GetAllNames(), 0, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Godfather]); } public override void Init() { PlayerIds.Clear(); GodfatherTarget.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { GodfatherTarget.Clear(); } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (GodfatherTarget.Contains(target.PlayerId) && !killer.GetCustomRole().IsImpostor() && !killer.GetCustomRole().IsMadmate() && !killer.Is(CustomRoles.Madmate)) { if (GodfatherChangeOpt.GetValue() == 0) { killer.RpcSetCustomRole(CustomRoles.Refugee); } else { killer.RpcSetCustomRole(CustomRoles.Madmate); } } } public override void OnVote(PlayerControl votePlayer, PlayerControl voteTarget) { if (!((Object)(object)votePlayer == (Object)null) && !((Object)(object)voteTarget == (Object)null)) { GodfatherTarget.Add(voteTarget.PlayerId); } } } internal class Greedy : RoleBase { private const int Id = 1500; public static HashSet playerIdList = new HashSet(); private static OptionItem OddKillCooldown; private static OptionItem EvenKillCooldown; private static readonly Dictionary IsOdd = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1500, TabGroup.ImpostorRoles, CustomRoles.Greedy); OddKillCooldown = FloatOptionItem.Create(1510, "GreedyOddKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedy]).SetValueFormat(OptionFormat.Seconds); EvenKillCooldown = FloatOptionItem.Create(1511, "GreedyEvenKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Greedy]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); IsOdd.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); IsOdd.Add(playerId, value: true); } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)165, (SendOption)1, -1); val.Write(playerId); val.Write(IsOdd[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); IsOdd[key] = reader.ReadBoolean(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = OddKillCooldown.GetFloat(); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { byte[] array = playerIdList.ToArray(); foreach (byte b in array) { IsOdd[b] = true; SendRPC(b); SetKillCooldown(b); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (IsOdd[killer.PlayerId]) { object obj; if (killer == null) { obj = null; } else { NetworkedPlayerInfo data = killer.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.Info((string?)obj + ": Odd kill cooldown", "Greedier", escapeCRLF: true, 72, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Greedy.cs"); Main.AllPlayerKillCooldown[killer.PlayerId] = EvenKillCooldown.GetFloat(); } else { object obj2; if (killer == null) { obj2 = null; } else { NetworkedPlayerInfo data2 = killer.Data; obj2 = ((data2 != null) ? data2.PlayerName : null); } Logger.Info((string?)obj2 + ": Even kill cooldown", "Greedier", escapeCRLF: true, 76, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Greedy.cs"); Main.AllPlayerKillCooldown[killer.PlayerId] = OddKillCooldown.GetFloat(); } IsOdd[killer.PlayerId] = !IsOdd[killer.PlayerId]; SendRPC(killer.PlayerId); killer.SyncSettings(); return true; } } internal class Hangman : RoleBase { private const int Id = 24500; private static OptionItem ShapeshiftCooldown; private static OptionItem ShapeshiftDuration; public static bool HasEnabled => CustomRoles.Hangman.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(24500, TabGroup.ImpostorRoles, CustomRoles.Hangman); ShapeshiftCooldown = FloatOptionItem.Create(24502, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hangman]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDuration = FloatOptionItem.Create(24504, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hangman]).SetValueFormat(OptionFormat.Seconds); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetFloat(); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (target.Is(CustomRoles.Pestilence)) { return true; } if (target.Is(CustomRoles.Madmate) && !Madmate.ImpCanKillMadmate.GetBool()) { return false; } if (Main.CheckShapeshift.TryGetValue(killer.PlayerId, out var value) && value) { target.SetDeathReason(PlayerState.DeathReason.LossOfHead); target.RpcExileV2(); Main.PlayerStates[target.PlayerId].SetDead(); target.Data.IsDead = true; target.SetRealKiller(killer); killer.SetKillCooldown(); return false; } return true; } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { if (!shapeshifting) { return null; } return CustomButton.Get("Hangman"); } } internal class Inhibitor : RoleBase { private const int Id = 1600; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem InhibitorCD; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1600, TabGroup.ImpostorRoles, CustomRoles.Inhibitor); InhibitorCD = FloatOptionItem.Create(1602, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inhibitor]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = InhibitorCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return !Utils.AnySabotageIsActive(); } } internal class Instigator : RoleBase { private const int Id = 1700; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem AbilityLimitt; private static OptionItem KillsPerAbilityUse; private static readonly IRandom rd = IRandom.Instance; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1700, TabGroup.ImpostorRoles, CustomRoles.Instigator); KillCooldown = FloatOptionItem.Create(1710, GeneralOption.KillCooldown, new FloatValueRule(20f, 180f, 1f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Instigator]).SetValueFormat(OptionFormat.Seconds); AbilityLimitt = IntegerOptionItem.Create(1711, "InstigatorAbilityLimit", new IntegerValueRule(1, 15, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Instigator]).SetValueFormat(OptionFormat.Times); KillsPerAbilityUse = IntegerOptionItem.Create(1712, "InstigatorKillsPerAbilityUse", new IntegerValueRule(1, 15, 1), 1, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Instigator]).SetValueFormat(OptionFormat.Times); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); base.AbilityLimit = AbilityLimitt.GetInt(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void OnPlayerExiled(PlayerControl instigator, NetworkedPlayerInfo exiled) { if ((Object)(object)exiled == (Object)null || !exiled.GetCustomRole().IsCrewmate() || base.AbilityLimit <= 0f) { return; } PlayerControl player = base._Player; if (!player.IsAlive()) { return; } List list = new List(); PlayerVoteArea[] array = ((IEnumerable)MeetingHud.Instance.playerStates).Where((PlayerVoteArea a) => a.VotedFor == exiled.PlayerId && a.TargetPlayerId != exiled.PlayerId).ToArray(); foreach (PlayerVoteArea playerVote in array) { PlayerControl val = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.PlayerId == playerVote.TargetPlayerId)); if ((Object)(object)val == (Object)null || !val.GetCustomRole().IsCrewmate()) { return; } list.Add(val); } if (list.Count == 0) { return; } List list2 = new List(); for (int j = 0; j < KillsPerAbilityUse.GetInt(); j++) { if (list.Count == 0) { break; } PlayerControl val2 = list.RandomElement(); val2.SetRealKiller(player); list2.Add(val2.PlayerId); list.Remove(val2); } int i = 0; byte[] array2 = new byte[list2.Count]; foreach (byte item in list2) { array2[i] = item; i++; } CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Retribution, array2); base.AbilityLimit--; SendSkillRPC(); } } internal class Kamikaze : RoleBase { private const int Id = 26900; private static OptionItem KillCooldown; private static OptionItem OptMaxMarked; private readonly HashSet KamikazedList = new HashSet(); public static bool HasEnabled => CustomRoles.Kamikaze.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(26900, TabGroup.ImpostorRoles, CustomRoles.Kamikaze); KillCooldown = FloatOptionItem.Create(26910, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Kamikaze]).SetValueFormat(OptionFormat.Seconds); OptMaxMarked = IntegerOptionItem.Create(26911, "KamikazeMaxMarked", new IntegerValueRule(1, 14, 1), 14, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Kamikaze]).SetValueFormat(OptionFormat.Times); } public override void Add(byte playerId) { base.AbilityLimit = OptMaxMarked.GetInt(); Utils.GetPlayerById(playerId).AddDoubleTrigger(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!KamikazedList.Contains(seen.PlayerId)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Kamikaze)), "∇"); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Kamikaze)), Translator.GetString("KamikazeHostage"))); return false; } return killer.CheckDoubleTrigger(target, delegate { if (base.AbilityLimit >= 1f && !KamikazedList.Contains(target.PlayerId)) { KamikazedList.Add(target.PlayerId); killer.RpcGuardAndKill(killer); killer.SetKillCooldown(KillCooldown.GetFloat()); Utils.NotifyRoles(killer); float abilityLimit = base.AbilityLimit; base.AbilityLimit = abilityLimit - 1f; SendSkillRPC(); } else { killer.RpcMurderPlayer(target); } }); } public override void OnSelfReducedToAtoms(bool IsAfterMeeting) { foreach (byte kamikazed in KamikazedList) { PlayerControl playerById = Utils.GetPlayerById(kamikazed); if (playerById.IsAlive()) { playerById.SetDeathReason(PlayerState.DeathReason.Targeted); if (!IsAfterMeeting) { playerById.RpcMurderPlayer(playerById); } else { playerById.RpcExileV2(); Main.PlayerStates[playerById.PlayerId].SetDead(); playerById.Data.IsDead = true; } playerById.SetRealKiller(base._Player); } } KamikazedList.Clear(); } public override string GetProgressText(byte playerId, bool comms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Kamikaze).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class KillingMachine : RoleBase { private const int Id = 23800; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem MNKillCooldown; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(23800, TabGroup.ImpostorRoles, CustomRoles.KillingMachine); MNKillCooldown = FloatOptionItem.Create(23805, GeneralOption.KillCooldown, new FloatValueRule(2.5f, 180f, 2.5f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.KillingMachine]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return false; } public override bool CanUseSabotage(PlayerControl pc) { return false; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = MNKillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, 0.2f); opt.SetFloat((FloatOptionNames)3, 0.2f); } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { return !reporter.Is(CustomRoles.KillingMachine); } public override bool OnCheckStartMeeting(PlayerControl reporter) { return !reporter.Is(CustomRoles.KillingMachine); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.RpcMurderPlayer(target); killer.ResetKillCooldown(); return false; } } internal class Lightning : RoleBase { private const int Id = 24100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem ConvertTime; private static OptionItem KillerConvertGhost; private static readonly List GhostPlayer = new List(); private static readonly Dictionary RealKiller = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(24100, TabGroup.ImpostorRoles, CustomRoles.Lightning); KillCooldown = FloatOptionItem.Create(24110, "LightningKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lightning]).SetValueFormat(OptionFormat.Seconds); ConvertTime = FloatOptionItem.Create(24112, "LightningConvertTime", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lightning]).SetValueFormat(OptionFormat.Seconds); KillerConvertGhost = BooleanOptionItem.Create(24114, "LightningKillerConvertGhost", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lightning]); } public override void Init() { playerIdList.Clear(); GhostPlayer.Clear(); RealKiller.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)162, (SendOption)1, -1); val.Write(playerId); val.Write(IsGhost(playerId)); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte b = reader.ReadByte(); bool flag = reader.ReadBoolean(); if (b == byte.MaxValue) { GhostPlayer.Clear(); } else if (flag) { if (!GhostPlayer.Contains(b)) { GhostPlayer.Add(b); } } else if (GhostPlayer.Contains(b)) { GhostPlayer.Remove(b); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public static bool IsGhost(PlayerControl player) { return IsGhost(player.PlayerId); } private static bool IsGhost(byte id) { return GhostPlayer.Contains(id); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || !killer.Is(CustomRoles.Lightning)) { return false; } if (IsGhost(target)) { return false; } killer.RpcGuardAndKill(); target.RpcGuardAndKill(); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Shield"); StartConvertCountDown(killer, target); return false; } private static void StartConvertCountDown(PlayerControl killer, PlayerControl target) { new LateTask(delegate { if (GameStates.IsInGame && GameStates.IsInTask && !GameStates.IsMeeting && target.IsAlive() && !Pelican.IsEaten(target.PlayerId)) { GhostPlayer.Add(target.PlayerId); SendRPC(target.PlayerId); RealKiller.TryAdd(target.PlayerId, killer); if (!killer.inVent) { killer.RpcGuardAndKill(killer); } Utils.NotifyRoles(); Logger.Info(target.GetNameWithRole() + " transformed into a quantum ghost", "Lightning", escapeCRLF: true, 109, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Lightning.cs"); } }, ConvertTime.GetFloat(), "Lightning Convert Player To Ghost"); } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!(inMeeting || isSuicide) && !((Object)(object)killer == (Object)null) && !((Object)(object)target == (Object)null) && KillerConvertGhost.GetBool() && !IsGhost(killer)) { RealKiller.TryAdd(killer.PlayerId, target); StartConvertCountDown(target, killer); } } public override void OnFixedUpdateLowLoad(PlayerControl lightning) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (!GhostPlayer.Any()) { return; } List list = new List(); byte[] array = GhostPlayer.ToArray(); foreach (byte playerId in array) { PlayerControl gs = Utils.GetPlayerById(playerId); if ((Object)(object)gs == (Object)null || !gs.IsAlive() || gs.Data.Disconnected) { list.Add(gs.PlayerId); continue; } PlayerControl[] array2 = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != gs.PlayerId && x.IsAlive() && !x.Is(CustomRoles.Lightning) && !IsGhost(x) && !Pelican.IsEaten(x.PlayerId)).ToArray(); foreach (PlayerControl val in array2) { if (!(Vector2.Distance(Vector2.op_Implicit(((Component)gs).transform.position), Vector2.op_Implicit(((Component)val).transform.position)) > 0.3f)) { list.Add(gs.PlayerId); gs.SetDeathReason(PlayerState.DeathReason.Quantization); gs.RpcMurderPlayer(gs); gs.SetRealKiller(RealKiller[gs.PlayerId]); Logger.Info(gs.GetNameWithRole() + " As a quantum ghost dying from a collision", "Lightning", escapeCRLF: true, 148, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Lightning.cs"); break; } } } if (list.Any()) { GhostPlayer.RemoveAll(list.Contains); array = list.ToArray(); for (int i = 0; i < array.Length; i++) { SendRPC(array[i]); } Utils.NotifyRoles(); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { byte[] array = GhostPlayer.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!((Object)(object)playerById == (Object)null)) { CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Quantization, playerById.PlayerId); playerById.SetRealKiller(RealKiller[playerById.PlayerId]); Logger.Info(playerById.GetNameWithRole() + " is quantum ghost - dead on start meeting", "Lightning", escapeCRLF: true, 167, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Lightning.cs"); } } GhostPlayer.Clear(); SendRPC(byte.MaxValue); Utils.NotifyRoles(); } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting) { return string.Empty; } if (target == null) { target = seer; } if ((seer.IsAlive() || !((Object)(object)seer != (Object)(object)target) || !IsGhost(target)) && !IsGhost(target)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lightning)), "■"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("LightningButtonText")); } } internal class Ludopath : RoleBase { private const int Id = 1800; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem LudopathRandomKillCD; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1800, TabGroup.ImpostorRoles, CustomRoles.Ludopath); LudopathRandomKillCD = IntegerOptionItem.Create(1802, "LudopathRandomKillCD", new IntegerValueRule(1, 100, 1), 45, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ludopath]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = LudopathRandomKillCD.GetFloat(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { int num = IRandom.Instance.Next(1, LudopathRandomKillCD.GetInt()); Main.AllPlayerKillCooldown[killer.PlayerId] = num; return true; } } internal class Lurker : RoleBase { private const int Id = 1900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem DefaultKillCooldown; private static OptionItem ReduceKillCooldown; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(1900, TabGroup.ImpostorRoles, CustomRoles.Lurker); DefaultKillCooldown = FloatOptionItem.Create(1910, GeneralOption.DefaultKillCooldown, new FloatValueRule(20f, 180f, 1f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lurker]).SetValueFormat(OptionFormat.Seconds); ReduceKillCooldown = FloatOptionItem.Create(1911, GeneralOption.ReduceKillCooldown, new FloatValueRule(0f, 10f, 1f), 2f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lurker]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = DefaultKillCooldown.GetFloat(); } public override void OnEnterVent(PlayerControl pc, Vent vent) { float num = Main.AllPlayerKillCooldown[pc.PlayerId] - ReduceKillCooldown.GetFloat(); if (!(num <= 0f)) { Main.AllPlayerKillCooldown[pc.PlayerId] = num; pc.SyncSettings(); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.ResetKillCooldown(); killer.SyncSettings(); return true; } } internal class Mastermind : RoleBase { private const int Id = 4100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem TimeLimit; private static OptionItem Delay; private static readonly Dictionary ManipulatedPlayers = new Dictionary(); private static readonly Dictionary ManipulateDelays = new Dictionary(); private static readonly Dictionary TempKCDs = new Dictionary(); private static float ManipulateCD; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(4100, TabGroup.ImpostorRoles, CustomRoles.Mastermind); KillCooldown = FloatOptionItem.Create(4110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mastermind]).SetValueFormat(OptionFormat.Seconds); TimeLimit = FloatOptionItem.Create(4112, "MastermindTimeLimit", new FloatValueRule(1f, 60f, 1f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mastermind]).SetValueFormat(OptionFormat.Seconds); Delay = FloatOptionItem.Create(4113, "MastermindDelay", new FloatValueRule(0f, 30f, 1f), 7f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mastermind]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); ManipulatedPlayers.Clear(); ManipulateDelays.Clear(); TempKCDs.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); ManipulateCD = KillCooldown.GetFloat() + TimeLimit.GetFloat() / 2f + Delay.GetFloat() / 2f; Utils.GetPlayerById(playerId).AddDoubleTrigger(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public static bool PlayerIsManipulated(PlayerControl pc) { return ManipulatedPlayers.ContainsKey(pc.PlayerId); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } return killer.CheckDoubleTrigger(target, delegate { killer.SetKillCooldown(ManipulateCD); if (target.HasKillButton() || CopyCat.playerIdList.Contains(target.PlayerId) || Main.TasklessCrewmate.Contains(target.PlayerId)) { ManipulateDelays.TryAdd(target.PlayerId, Utils.GetTimeStamp()); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); } }); } public override void OnFixedUpdateLowLoad(PlayerControl mastermind) { if (ManipulatedPlayers.Count == 0 && ManipulateDelays.Count == 0) { return; } foreach (KeyValuePair manipulateDelay in ManipulateDelays) { PlayerControl playerById = Utils.GetPlayerById(manipulateDelay.Key); if (!playerById.IsAlive()) { ManipulateDelays.Remove(manipulateDelay.Key); } else if (manipulateDelay.Value + Delay.GetInt() < Utils.GetTimeStamp()) { ManipulateDelays.Remove(manipulateDelay.Key); ManipulatedPlayers.TryAdd(manipulateDelay.Key, Utils.GetTimeStamp()); TempKCDs.TryAdd(playerById.PlayerId, playerById.killTimer); playerById.SetKillCooldown(1f); Utils.NotifyRoles(mastermind); } } foreach (KeyValuePair manipulatedPlayer in ManipulatedPlayers) { PlayerControl playerById2 = Utils.GetPlayerById(manipulatedPlayer.Key); if (!playerById2.IsAlive()) { ManipulatedPlayers.Remove(manipulatedPlayer.Key); TempKCDs.Remove(manipulatedPlayer.Key); continue; } if (manipulatedPlayer.Value + TimeLimit.GetInt() < Utils.GetTimeStamp()) { ManipulatedPlayers.Remove(manipulatedPlayer.Key); TempKCDs.Remove(manipulatedPlayer.Key); playerById2.SetDeathReason(PlayerState.DeathReason.Suicide); playerById2.RpcMurderPlayer(playerById2); playerById2.SetRealKiller(mastermind); RPC.PlaySoundRPC(mastermind.PlayerId, Sounds.KillSound); } long num = TimeLimit.GetInt() - (Utils.GetTimeStamp() - manipulatedPlayer.Value); playerById2.Notify(string.Format(Translator.GetString("ManipulateNotify"), num), 1.1f); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { foreach (KeyValuePair manipulatedPlayer in ManipulatedPlayers) { PlayerControl playerById = Utils.GetPlayerById(manipulatedPlayer.Key); if (playerById.IsAlive()) { playerById.SetDeathReason(PlayerState.DeathReason.Suicide); playerById.RpcMurderPlayer(playerById); playerById.SetRealKiller(Utils.GetPlayerById(playerIdList.First())); } } ManipulateDelays.Clear(); ManipulatedPlayers.Clear(); TempKCDs.Clear(); } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return true; } if (!PlayerIsManipulated(killer)) { return false; } ManipulatedPlayers.Remove(killer.PlayerId); PlayerControl playerById = Utils.GetPlayerById(playerIdList.First()); playerById?.Notify(string.Format(Translator.GetString("ManipulatedKilled"), killer.GetRealName())); playerById?.SetKillCooldown(KillCooldown.GetFloat()); killer.Notify(Translator.GetString("SurvivedManipulation")); if (target.Is(CustomRoles.Pestilence) || target.Is(CustomRoles.Mastermind)) { target.RpcMurderPlayer(killer); TempKCDs.Remove(killer.PlayerId); return true; } killer.RpcMurderPlayer(target); new LateTask(delegate { killer.SetKillCooldown(TempKCDs[killer.PlayerId] + Main.AllPlayerKillCooldown[killer.PlayerId]); TempKCDs.Remove(killer.PlayerId); }, 0.1f, "Set KCD for Manipulated Kill"); return true; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (ManipulateDelays.ContainsKey(target.PlayerId)) { return "#00ffa5"; } if (PlayerIsManipulated(target)) { return Main.roleColors[CustomRoles.Arsonist]; } return string.Empty; } } internal class Mercenary : RoleBase { private const int Id = 2000; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem TimeLimit; private static readonly Dictionary SuicideTimer = new Dictionary(); private static float OptTimeLimit; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2000, TabGroup.ImpostorRoles, CustomRoles.Mercenary); KillCooldown = FloatOptionItem.Create(2010, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mercenary]).SetValueFormat(OptionFormat.Seconds); TimeLimit = FloatOptionItem.Create(2011, "MercenaryLimit", new FloatValueRule(5f, 180f, 5f), 60f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mercenary]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); SuicideTimer.Clear(); } public override void Add(byte serial) { playerIdList.Add(serial); OptTimeLimit = TimeLimit.GetFloat(); } private static bool HasKilled(PlayerControl pc) { if ((Object)(object)pc != (Object)null && pc.Is(CustomRoles.Mercenary) && pc.IsAlive()) { return Main.PlayerStates[pc.PlayerId].GetKillCount(ExcludeSelfKill: true) > 0; } return false; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = (HasKilled(Utils.GetPlayerById(playerId)) ? OptTimeLimit : 255f); AURoleOptions.ShapeshifterDuration = 1f; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { resetCooldown = false; return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { SuicideTimer.Remove(killer.PlayerId); killer.MarkDirtySettings(); return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { ClearSuicideTimer(); } public static void ClearSuicideTimer() { SuicideTimer.Clear(); } public override void OnFixedUpdate(PlayerControl player) { float value; if (!HasKilled(player)) { SuicideTimer.Remove(player.PlayerId); } else if (!SuicideTimer.TryGetValue(player.PlayerId, out value)) { SuicideTimer[player.PlayerId] = 0f; player.RpcResetAbilityCooldown(); } else if (value >= OptTimeLimit) { player.SetDeathReason(PlayerState.DeathReason.Suicide); player.RpcMurderPlayer(player); SuicideTimer.Remove(player.PlayerId); } else { SuicideTimer[player.PlayerId] += Time.fixedDeltaTime; } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("MercenarySuicideButtonText")); } public override void AfterMeetingTasks() { foreach (byte playerId in playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById != (Object)null && playerById.IsAlive()) { playerById.RpcResetAbilityCooldown(); if (HasKilled(playerById)) { SuicideTimer[playerId] = 0f; } } } } } internal class Miner : RoleBase { private const int Id = 4200; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem MinerSSDuration; private static OptionItem MinerSSCD; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4200, TabGroup.ImpostorRoles, CustomRoles.Miner); MinerSSDuration = FloatOptionItem.Create(4202, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Miner]).SetValueFormat(OptionFormat.Seconds); MinerSSCD = FloatOptionItem.Create(4203, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Miner]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = MinerSSCD.GetFloat(); AURoleOptions.ShapeshifterDuration = MinerSSDuration.GetFloat(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("MinerTeleButtonText")); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } if (Main.LastEnteredVent.ContainsKey(shapeshifter.PlayerId)) { Vector2 val = Main.LastEnteredVentLocation[shapeshifter.PlayerId]; Logger.Info($"Miner - {shapeshifter.GetNameWithRole()}:{val}", "MinerTeleport", escapeCRLF: true, 56, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Miner.cs"); shapeshifter.RpcTeleport(val); shapeshifter.RPCPlayCustomSound("Teleport"); } return false; } } internal class Morphling : RoleBase { private const int Id = 3500; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem ShapeshiftCD; private static OptionItem ShapeshiftDur; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3500, TabGroup.ImpostorRoles, CustomRoles.Morphling); KillCooldown = FloatOptionItem.Create(3514, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Morphling]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCD = FloatOptionItem.Create(3515, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Morphling]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDur = FloatOptionItem.Create(3516, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Morphling]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override bool CanUseKillButton(PlayerControl player) { if ((Object)(object)player == (Object)null || !player.IsAlive()) { return false; } Main.CheckShapeshift.TryGetValue(player.PlayerId, out var value); return value; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCD.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDur.GetFloat(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } } internal class Nemesis : RoleBase { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { if (PlayerControl.LocalPlayer.Is(CustomRoles.Nemesis) && !PlayerControl.LocalPlayer.IsAlive()) { CreateJudgeButton(__instance); } } } private const int Id = 3600; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem NemesisCanKillNum; public static OptionItem LegacyNemesis; private static OptionItem NemesisShapeshiftCD; private static OptionItem NemesisShapeshiftDur; private static readonly Dictionary NemesisRevenged = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase { get { if (!LegacyNemesis.GetBool()) { return CustomRoles.Impostor; } return CustomRoles.Shapeshifter; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3600, TabGroup.ImpostorRoles, CustomRoles.Nemesis); NemesisCanKillNum = IntegerOptionItem.Create(3610, "NemesisCanKillNum", new IntegerValueRule(0, 15, 1), 1, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Nemesis]).SetValueFormat(OptionFormat.Players); LegacyNemesis = BooleanOptionItem.Create(3611, "LegacyNemesis", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Nemesis]); NemesisShapeshiftCD = FloatOptionItem.Create(3612, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(LegacyNemesis).SetValueFormat(OptionFormat.Seconds); NemesisShapeshiftDur = FloatOptionItem.Create(3613, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(LegacyNemesis).SetValueFormat(OptionFormat.Seconds); } public override void Init() { NemesisRevenged.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = NemesisShapeshiftCD.GetFloat(); AURoleOptions.ShapeshifterDuration = NemesisShapeshiftDur.GetFloat(); } public override void OnMeetingHudStart(PlayerControl player) { if (!player.IsAlive()) { MeetingHudStartPatch.AddMsg(Translator.GetString("NemesisDeadMsg"), player.PlayerId); } } public static bool NemesisMsgCheck(PlayerControl pc, string msg, bool isUI = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsInGame || (Object)(object)pc == (Object)null) { return false; } if (!pc.Is(CustomRoles.Nemesis)) { return false; } msg = msg.Trim().ToLower(); if (msg.Length < 3 || msg.Substring(0, 3) != "/rv") { return false; } if (NemesisCanKillNum.GetInt() < 1) { pc.ShowInfoMessage(isUI, Translator.GetString("NemesisKillDisable")); return true; } if (pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("NemesisAliveKill")); return true; } if (msg == "/rv") { string text = Translator.GetString("PlayerIdList"); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { text = text + "\n" + val.PlayerId + " → (" + val.GetDisplayRoleAndSubName(val) + ") " + val.GetRealName(); } Utils.SendMessage(text, pc.PlayerId); return true; } if (NemesisRevenged.TryGetValue(pc.PlayerId, out var value) && value >= NemesisCanKillNum.GetInt()) { pc.ShowInfoMessage(isUI, Translator.GetString("NemesisKillMax")); return true; } NemesisRevenged.Add(pc.PlayerId, 0); PlayerControl target; try { int playerId = int.Parse(msg.Replace("/rv", string.Empty)); target = Utils.GetPlayerById(playerId); } catch { pc.ShowInfoMessage(isUI, Translator.GetString("NemesisKillDead")); return true; } if ((Object)(object)target == (Object)null || !target.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("NemesisKillDead")); return true; } if (target.Is(CustomRoles.Pestilence)) { pc.ShowInfoMessage(isUI, Translator.GetString("PestilenceImmune")); return true; } if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessMini")); return true; } if (target.Is(CustomRoles.Solsticer)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSolsticer")); return true; } if (target.Is(CustomRoles.Jinx) || target.Is(CustomRoles.CursedWolf)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessImmune")); return true; } if (!pc.RpcCheckAndMurder(target, check: true)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessImmune")); return true; } Logger.Info(pc.GetNameWithRole() + " revenge " + target.GetNameWithRole(), "Nemesis", escapeCRLF: true, 152, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Nemesis.cs"); string Name = target.GetRealName(); NemesisRevenged[pc.PlayerId]++; CustomSoundsManager.RPCPlayCustomSoundAll("AWP"); new LateTask(delegate { target.SetDeathReason(PlayerState.DeathReason.Revenge); if (GameStates.IsMeeting) { Main.PlayersDiedInMeeting.Add(target.PlayerId); target.RpcGuesserMurderPlayer(); MurderPlayerPatch.AfterPlayerDeathTasks(pc, target, inMeeting: true); } else { target.RpcMurderPlayer(target); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); } target.SetRealKiller(pc); new LateTask(delegate { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("NemesisKillSucceed"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Nemesis)), Translator.GetString("NemesisRevengeTitle")), logforChatManager: true); }, 0.6f, "Nemesis Kill"); }, 0.2f, "Nemesis Start Kill"); return true; } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)121, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC_Custom(MessageReader reader, PlayerControl pc) { int value = reader.ReadByte(); NemesisMsgCheck(pc, $"/rv {value}", isUI: true); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CheckCanUseKillButton() ? Options.DefaultKillCooldown : 300f); } public override bool CanUseKillButton(PlayerControl pc) { return CheckCanUseKillButton(); } public static bool CheckCanUseKillButton() { if (Main.PlayerStates == null) { return false; } int num = 0; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; for (int i = 0; i < allAlivePlayerControls.Length; i++) { CustomRoles customRole = allAlivePlayerControls[i].GetCustomRole(); if (customRole != CustomRoles.Nemesis && customRole.IsImpostor()) { num++; } } return num <= 0; } private static void NemesisOnClick(byte playerId) { Logger.Msg($"Click: ID {playerId}", "Nemesis UI", escapeCRLF: true, 213, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Nemesis.cs"); PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && GameStates.IsVoting) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { NemesisMsgCheck(PlayerControl.LocalPlayer, $"/rv {playerId}", isUI: true); } else { SendRPC(playerId); } } } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!seer.IsAlive() && seen.IsAlive()) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Nemesis)), " " + seen.PlayerId) + " "; } return string.Empty; } public static void CreateJudgeButton(MeetingHud __instance) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) PlayerVoteArea[] array = ((IEnumerable)__instance.playerStates).ToArray(); foreach (PlayerVoteArea pva in array) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); obj.GetComponent().sprite = CustomButton.Get("MeetingKillButton"); PassiveButton component = obj.GetComponent(); ((UnityEventBase)component.OnClick).RemoveAllListeners(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { NemesisOnClick(pva.TargetPlayerId); })); } } } } internal class Ninja : RoleBase { private const int Id = 2100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem MarkCooldown; private static OptionItem AssassinateCooldownOpt; private static OptionItem ShapeshiftDurationOpt; private static readonly Dictionary MarkedPlayer = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2100, TabGroup.ImpostorRoles, CustomRoles.Ninja); MarkCooldown = FloatOptionItem.Create(2110, "NinjaMarkCooldown", new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ninja]).SetValueFormat(OptionFormat.Seconds); AssassinateCooldownOpt = FloatOptionItem.Create(2111, "NinjaAssassinateCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ninja]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDurationOpt = FloatOptionItem.Create(2113, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ninja]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); MarkedPlayer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); Utils.GetPlayerById(playerId).AddDoubleTrigger(); } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)168, (SendOption)1, -1); val.Write(playerId); val.Write(MarkedPlayer.ContainsKey(playerId) ? MarkedPlayer[playerId] : byte.MaxValue); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); byte b = reader.ReadByte(); MarkedPlayer.Remove(key); if (b != byte.MaxValue) { MarkedPlayer.Add(key, b); } } private static bool Shapeshifting(byte id) { bool value; return Main.CheckShapeshift.TryGetValue(id, out value) && value; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (Shapeshifting(id) ? Options.DefaultKillCooldown : MarkCooldown.GetFloat()); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = AssassinateCooldownOpt.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDurationOpt.GetFloat(); AURoleOptions.ShapeshifterLeaveSkin = false; } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("CantMark"))); return true; } return killer.CheckDoubleTrigger(target, delegate { MarkedPlayer.Remove(killer.PlayerId); MarkedPlayer.Add(killer.PlayerId, target.PlayerId); SendRPC(killer.PlayerId); killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.SyncSettings(); killer.RPCPlayCustomSound("Clothe"); }); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { if (shouldAnimate && Shapeshifting(shapeshifter.PlayerId)) { shouldAnimate = false; } return true; } if (!MarkedPlayer.ContainsKey(shapeshifter.PlayerId)) { resetCooldown = false; return false; } if (MarkedPlayer.TryGetValue(shapeshifter.PlayerId, out var value)) { PlayerControl playerById = Utils.GetPlayerById(value); MarkedPlayer.Remove(shapeshifter.PlayerId); SendRPC(shapeshifter.PlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && !playerById.inVent && !GameStates.IsMeeting && shapeshifter.RpcCheckAndMurder(playerById, check: true)) { shapeshifter.RpcTeleport(playerById.GetCustomPosition()); shapeshifter.ResetKillCooldown(); shapeshifter.RpcMurderPlayer(playerById); shouldAnimate = false; Logger.Info("Was kill market target", "Ninja", escapeCRLF: true, 140, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Ninja.cs"); return true; } } return false; } public override string GetLowerText(PlayerControl witch, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if (isForMeeting) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(Translator.GetString("NinjaModeDouble")); return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte playerid) { if (!Shapeshifting(playerid)) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("NinjaMarkButtonText")); } else { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText")); } if (MarkedPlayer.ContainsKey(playerid) && !Shapeshifting(playerid)) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("NinjaShapeshiftText")); } } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { if (shapeshifting) { return null; } return CustomButton.Get("Mark"); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { if (shapeshifting || !MarkedPlayer.ContainsKey(player.PlayerId)) { return null; } return CustomButton.Get("Assassinate"); } } internal class Parasite : RoleBase { private const int Id = 5900; private static readonly HashSet Playerids = new HashSet(); private static OptionItem ParasiteCD; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(5900, TabGroup.ImpostorRoles, CustomRoles.Parasite); ParasiteCD = FloatOptionItem.Create(5902, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Parasite]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: true); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ParasiteCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return true; } } internal class Penguin : RoleBase { private const int Id = 27500; private static OptionItem OptionAbductTimerLimit; private static OptionItem OptionMeetingKill; public PlayerControl AbductVictim; private float AbductTimer; private float AbductTimerLimit; private bool stopCount; private bool MeetingKill; public static bool HasEnabled => CustomRoles.Penguin.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(27500, TabGroup.ImpostorRoles, CustomRoles.Penguin); OptionAbductTimerLimit = FloatOptionItem.Create(27511, "PenguinAbductTimerLimit", new FloatValueRule(1f, 20f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Penguin]).SetValueFormat(OptionFormat.Seconds); OptionMeetingKill = BooleanOptionItem.Create(27512, "PenguinMeetingKill", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Penguin]); } public override void Add(byte playerId) { AbductTimerLimit = OptionAbductTimerLimit.GetFloat(); MeetingKill = OptionMeetingKill.GetBool(); AbductTimer = 255f; stopCount = false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = (((Object)(object)AbductVictim != (Object)null) ? AbductTimer : AbductTimerLimit); AURoleOptions.ShapeshifterDuration = 1f; } private void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); PlayerControl abductVictim = AbductVictim; val.Write((abductVictim != null) ? abductVictim.PlayerId : byte.MaxValue); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte b = reader.ReadByte(); if (b == byte.MaxValue) { AbductVictim = null; AbductTimer = 255f; } else { AbductVictim = Utils.GetPlayerById(b); AbductTimer = AbductTimerLimit; } } private void AddVictim(PlayerControl penguin, PlayerControl target) { AbductVictim = target; AbductTimer = AbductTimerLimit; penguin?.MarkDirtySettings(); penguin?.RpcResetAbilityCooldown(); SendRPC(); } private void RemoveVictim() { if ((Object)(object)AbductVictim != (Object)null) { AbductVictim = null; } AbductTimer = 255f; base._Player?.MarkDirtySettings(); base._Player?.RpcResetAbilityCooldown(); SendRPC(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { bool result = true; if ((Object)(object)AbductVictim != (Object)null) { if ((Object)(object)target != (Object)(object)AbductVictim) { killer?.RpcMurderPlayer(AbductVictim); killer?.ResetKillCooldown(); result = false; } RemoveVictim(); } else { result = false; AddVictim(killer, target); } return result; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { resetCooldown = false; return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(((Object)(object)AbductVictim != (Object)null) ? Translator.GetString("KillButtonText") : Translator.GetString("PenguinKillButtonText")); } AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString("PenguinTimerText")); } AbilityButton abilityButton2 = hud.AbilityButton; if (abilityButton2 != null) { ((ActionButton)abilityButton2).ToggleVisible((Object)(object)AbductVictim != (Object)null); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { stopCount = true; if ((Object)(object)AbductVictim != (Object)null && AbductTimer <= 0f) { base._Player?.RpcMurderPlayer(AbductVictim); } if (MeetingKill && ((InnerNetClient)AmongUsClient.Instance).AmHost && !((Object)(object)AbductVictim == (Object)null)) { base._Player?.RpcMurderPlayer(AbductVictim); RemoveVictim(); } } public override void AfterMeetingTasks() { if (!GameStates.AirshipIsActive) { RestartAbduct(); } } public void OnSpawnAirship() { RestartAbduct(); } private void RestartAbduct() { if (HasEnabled && (Object)(object)AbductVictim != (Object)null) { base._Player?.MarkDirtySettings(); base._Player?.RpcResetAbilityCooldown(); stopCount = false; } } public override void OnCoEnterVent(PlayerPhysics physics, int ventId) { if ((Object)(object)AbductVictim != (Object)null) { physics.RpcBootFromVent(ventId); } } public override bool OnCoEnterVentOthers(PlayerPhysics physics, int ventId) { if ((Object)(object)AbductVictim != (Object)null && physics.myPlayer.PlayerId == AbductVictim.PlayerId) { physics.RpcBootFromVent(ventId); return true; } return false; } public override void OnFixedUpdate(PlayerControl penguin) { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsMeeting) { return; } if (!stopCount) { AbductTimer -= Time.fixedDeltaTime; } if ((Object)(object)AbductVictim != (Object)null) { if (!penguin.IsAlive() || !AbductVictim.IsAlive()) { RemoveVictim(); } else if (AbductTimer <= 0f && !penguin.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { AbductVictim.Data.IsDead = true; AbductVictim.Data.MarkDirty(); if (!AbductVictim.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { PlayerControl abductVictim = AbductVictim; new LateTask(delegate { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) int num = abductVictim.NetTransform.lastSequenceId + 5; abductVictim.NetTransform.SnapTo(Vector2.op_Implicit(((Component)penguin).transform.position), (ushort)num); penguin.MurderPlayer(abductVictim, (MurderResultFlags)1); CustomRpcSender customRpcSender = CustomRpcSender.Create("PenguinMurder", (SendOption)0); customRpcSender.AutoStartRpc(((InnerNetObject)abductVictim.NetTransform).NetId, 21); NetHelpers.WriteVector2(Vector2.op_Implicit(((Component)penguin).transform.position), customRpcSender.stream); customRpcSender.Write(abductVictim.NetTransform.lastSequenceId); customRpcSender.EndRpc(); customRpcSender.AutoStartRpc(((InnerNetObject)penguin).NetId, 12); customRpcSender.WriteNetObject((InnerNetObject)(object)abductVictim); customRpcSender.Write(1); customRpcSender.EndRpc(); customRpcSender.SendMessage(); }, 0.3f, "PenguinMurder"); RemoveVictim(); } } else { if (AbductVictim.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { return; } Vector3 position = ((Component)penguin).transform.position; if (!((InnerNetObject)(object)penguin).OwnedByHost()) { AbductVictim.RpcTeleport(Vector2.op_Implicit(position), isRandomSpawn: false, sendInfoInLogs: false); return; } new LateTask(delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) AbductVictim?.RpcTeleport(Vector2.op_Implicit(position), isRandomSpawn: false, sendInfoInLogs: false); }, 0.25f, ""); } } else if (AbductTimer <= 100f) { AbductTimer = 255f; penguin.RpcResetAbilityCooldown(); } } } internal class Pitfall : RoleBase { private const int Id = 5600; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ShapeshiftCooldown; private static OptionItem MaxTrapCount; private static OptionItem TrapMaxPlayerCountOpt; private static OptionItem TrapDurationOpt; private static OptionItem TrapRadius; private static OptionItem TrapFreezeTime; private static OptionItem TrapCauseVision; private static OptionItem TrapCauseVisionTime; private static HashSet Traps = new HashSet(); private static readonly HashSet ReducedVisionPlayers = new HashSet(); private static float DefaultSpeed = 0f; public static float TrapMaxPlayerCount = 0f; public static float TrapDuration = 0f; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(5600, TabGroup.ImpostorRoles, CustomRoles.Pitfall); ShapeshiftCooldown = FloatOptionItem.Create(5610, "PitfallTrapCooldown", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Seconds); MaxTrapCount = FloatOptionItem.Create(5611, "PitfallMaxTrapCount", new FloatValueRule(1f, 5f, 1f), 1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Times); TrapMaxPlayerCountOpt = FloatOptionItem.Create(5612, "PitfallTrapMaxPlayerCount", new FloatValueRule(1f, 15f, 1f), 3f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Times); TrapDurationOpt = FloatOptionItem.Create(5613, "PitfallTrapDuration", new FloatValueRule(5f, 180f, 1f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Seconds); TrapRadius = FloatOptionItem.Create(5614, "PitfallTrapRadius", new FloatValueRule(0.5f, 5f, 0.5f), 2f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Multiplier); TrapFreezeTime = FloatOptionItem.Create(5615, "PitfallTrapFreezeTime", new FloatValueRule(0f, 30f, 1f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Seconds); TrapCauseVision = FloatOptionItem.Create(5616, "PitfallTrapCauseVision", new FloatValueRule(0f, 5f, 0.05f), 0.2f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Multiplier); TrapCauseVisionTime = FloatOptionItem.Create(5617, "PitfallTrapCauseVisionTime", new FloatValueRule(0f, 45f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pitfall]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); Traps.Clear(); ReducedVisionPlayers.Clear(); DefaultSpeed = 0f; TrapMaxPlayerCount = 0f; TrapDuration = 0f; } public override void Add(byte playerId) { playerIdList.Add(playerId); DefaultSpeed = Main.AllPlayerSpeed[playerId]; TrapMaxPlayerCount = TrapMaxPlayerCountOpt.GetFloat(); TrapDuration = TrapDurationOpt.GetFloat(); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateOthers); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } Traps = Traps.Where((PitfallTrap a) => a.IsActive).ToHashSet(); Vector2 location = Vector2.op_Implicit(((Component)shapeshifter).transform.position); PitfallTrap[] array = Traps.Where((PitfallTrap a) => a.PitfallPlayerId == shapeshifter.PlayerId).ToArray(); if (array.Length >= MaxTrapCount.GetInt()) { PitfallTrap pitfallTrap = array.First(); pitfallTrap.Location = location; pitfallTrap.PlayersTrapped = new List(); pitfallTrap.Timer = 0f; } else { Traps.Add(new PitfallTrap { PitfallPlayerId = shapeshifter.PlayerId, Location = location, PlayersTrapped = new List(), Timer = 0f }); } shapeshifter.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); return false; } private void OnFixedUpdateOthers(PlayerControl player) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if (Pelican.IsEaten(player.PlayerId) || !player.IsAlive()) { return; } PitfallTrap[] array; if (player.GetCustomRole().IsImpostor()) { array = Traps.Where((PitfallTrap a) => a.PitfallPlayerId == player.PlayerId && a.IsActive).ToArray(); for (int i = 0; i < array.Length; i++) { array[i].Timer += Time.fixedDeltaTime; } return; } Vector2 val = Vector2.op_Implicit(((Component)player).transform.position); array = Traps.Where((PitfallTrap a) => a.IsActive).ToArray(); foreach (PitfallTrap pitfallTrap in array) { if (!pitfallTrap.PlayersTrapped.Contains(player.PlayerId) && !(Vector2.Distance(pitfallTrap.Location, val) > TrapRadius.GetFloat())) { if (TrapFreezeTime.GetFloat() > 0f) { TrapPlayer(player); } if (TrapCauseVisionTime.GetFloat() > 0f) { ReducePlayerVision(player); } pitfallTrap.PlayersTrapped.Add(player.PlayerId); player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pitfall)), Translator.GetString("PitfallTrap"))); } } } public static void SetPitfallTrapVision(IGameOptions opt, PlayerControl target) { if (ReducedVisionPlayers.Contains(target.PlayerId)) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, TrapCauseVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, TrapCauseVision.GetFloat()); } } private static void TrapPlayer(PlayerControl player) { Main.AllPlayerSpeed[player.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[player.PlayerId] = false; player.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[player.PlayerId] = DefaultSpeed; ReportDeadBodyPatch.CanReport[player.PlayerId] = true; player.MarkDirtySettings(); }, TrapFreezeTime.GetFloat(), "Pitfall Trap Player Freeze"); } private static void ReducePlayerVision(PlayerControl player) { if (!ReducedVisionPlayers.Contains(player.PlayerId)) { ReducedVisionPlayers.Add(player.PlayerId); player.MarkDirtySettings(); new LateTask(delegate { ReducedVisionPlayers.Remove(player.PlayerId); player.MarkDirtySettings(); }, TrapCauseVisionTime.GetFloat(), "Pitfall Trap Player Vision"); } } } public class PitfallTrap { public int PitfallPlayerId; public Vector2 Location; public float Timer; public List PlayersTrapped; public bool IsActive { get { if (Timer <= Pitfall.TrapDuration) { return (float)PlayersTrapped.Count < Pitfall.TrapMaxPlayerCount; } return false; } } } internal class Puppeteer : RoleBase { private const int Id = 4300; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem PuppeteerDoubleKills; private static readonly Dictionary PuppeteerList = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4300, TabGroup.ImpostorRoles, CustomRoles.Puppeteer); PuppeteerDoubleKills = BooleanOptionItem.Create(4312, "PuppeteerDoubleKills", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: true).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Puppeteer]); } public override void Init() { PlayerIds.Clear(); PuppeteerList.Clear(); } public override void Add(byte playerId) { Utils.GetPlayerById(playerId).AddDoubleTrigger(); PlayerIds.Add(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateOthers); } } private static void SendRPC(byte puppetId, byte targetId, byte typeId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)128, (SendOption)1, -1); val.Write(typeId); val.Write(puppetId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte b = reader.ReadByte(); byte value = reader.ReadByte(); byte key = reader.ReadByte(); switch (b) { case 0: PuppeteerList.Clear(); break; case 1: PuppeteerList[key] = value; break; case 2: PuppeteerList.Remove(key); break; } } public static bool PuppetIsActive(byte playerId) { return PuppeteerList.ContainsKey(playerId); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (target.Is(CustomRoles.LazyGuy) || target.Is(CustomRoles.Lazy) || (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) || Medic.ProtectList.Contains(target.PlayerId)) { return false; } return killer.CheckDoubleTrigger(target, delegate { PuppeteerList[target.PlayerId] = killer.PlayerId; killer.SetKillCooldown(); SendRPC(killer.PlayerId, target.PlayerId, 1); killer.RPCPlayCustomSound("Line"); Utils.NotifyRoles(killer, target); }); } private void OnFixedUpdateOthers(PlayerControl puppet) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (!PuppetIsActive(puppet.PlayerId)) { return; } if (!puppet.IsAlive() || Pelican.IsEaten(puppet.PlayerId)) { PuppeteerList.Remove(puppet.PlayerId); return; } Vector3 position = ((Component)puppet).transform.position; Dictionary dictionary = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (val.PlayerId != puppet.PlayerId && !val.Is(Custom_Team.Impostor) && !val.Is(CustomRoles.Pestilence)) { float value = Vector2.Distance(Vector2.op_Implicit(position), Vector2.op_Implicit(((Component)val).transform.position)); dictionary.Add(val.PlayerId, value); } } if (!dictionary.Any()) { return; } KeyValuePair keyValuePair = dictionary.OrderBy((KeyValuePair c) => c.Value).FirstOrDefault(); PlayerControl playerById = Utils.GetPlayerById(keyValuePair.Key); float num = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(Main.NormalOptions.KillDistance, 0, 2)]; if (keyValuePair.Value <= num && puppet.CanMove && playerById.CanMove && puppet.RpcCheckAndMurder(playerById, check: true)) { byte b = PuppeteerList[puppet.PlayerId]; RPC.PlaySoundRPC(b, Sounds.KillSound); puppet.RpcMurderPlayer(playerById); playerById.SetRealKiller(Utils.GetPlayerById(b)); Utils.MarkEveryoneDirtySettings(); PuppeteerList.Remove(puppet.PlayerId); SendRPC(byte.MaxValue, puppet.PlayerId, 2); Utils.NotifyRoles(Utils.GetPlayerById(b), puppet); if (!puppet.Is(CustomRoles.Pestilence) && PuppeteerDoubleKills.GetBool()) { puppet.SetDeathReason(PlayerState.DeathReason.Drained); puppet.RpcMurderPlayer(puppet); puppet.SetRealKiller(Utils.GetPlayerById(b)); } } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { PuppeteerList.Clear(); SendRPC(byte.MaxValue, byte.MaxValue, 0); } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || isForMeeting) { return string.Empty; } if (!PuppeteerList.ContainsValue(seer.PlayerId) || !PuppeteerList.ContainsKey(target.PlayerId)) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Puppeteer)), "◆"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("PuppeteerOperateButtonText")); } } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Puttpuer"); } } internal class QuickShooter : RoleBase { private const int Id = 2200; private static OptionItem KillCooldown; private static OptionItem MeetingReserved; private static OptionItem ShapeshiftCooldown; private bool Storaging; private readonly Dictionary NewSL = new Dictionary(); public static bool HasEnabled => CustomRoles.QuickShooter.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2200, TabGroup.ImpostorRoles, CustomRoles.QuickShooter); KillCooldown = FloatOptionItem.Create(2210, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 35f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.QuickShooter]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCooldown = FloatOptionItem.Create(2212, "QuickShooterShapeshiftCooldown", new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.QuickShooter]).SetValueFormat(OptionFormat.Seconds); MeetingReserved = IntegerOptionItem.Create(2214, "MeetingReserved", new IntegerValueRule(0, 15, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.QuickShooter]).SetValueFormat(OptionFormat.Pieces); } public override void Add(byte playerId) { base.AbilityLimit = 0f; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ((Storaging || base.AbilityLimit < 1f) ? KillCooldown.GetFloat() : 0.01f); Storaging = false; } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (shapeshifter.PlayerId == target.PlayerId) { return false; } float killTimer = shapeshifter.GetKillTimer(); Logger.Info($"Kill Timer: {killTimer}", "QuickShooter", escapeCRLF: true, 58, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\QuickShooter.cs"); if (killTimer <= 0f) { base.AbilityLimit++; SendSkillRPC(); resetCooldown = false; Storaging = true; shapeshifter.ResetKillCooldown(); shapeshifter.SetKillCooldown(); shapeshifter.Notify(Translator.GetString("QuickShooterStoraging")); Logger.Info($"{Utils.GetPlayerById(shapeshifter.PlayerId)?.GetNameWithRole()} : shot limit: {base.AbilityLimit}", "QuickShooter", escapeCRLF: true, 71, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\QuickShooter.cs"); } return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { NewSL[_state.PlayerId] = Math.Clamp((int)base.AbilityLimit, 0, MeetingReserved.GetInt()); base.AbilityLimit = NewSL[_state.PlayerId]; SendSkillRPC(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { base.AbilityLimit--; base.AbilityLimit = Math.Max(base.AbilityLimit, 0f); SendSkillRPC(); return true; } public override string GetProgressText(byte playerId, bool comms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.QuickShooter).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString("QuickShooterShapeshiftText")); } AbilityButton abilityButton2 = hud.AbilityButton; if (abilityButton2 != null) { ((ActionButton)abilityButton2).SetUsesRemaining((int)base.AbilityLimit); } } } internal class Refugee : RoleBase { private const int Id = 60009; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem RefugeeKillCD; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; public override void SetupCustomOption() { RefugeeKillCD = FloatOptionItem.Create(60009, "RefugeeKillCD", new FloatValueRule(0f, 180f, 2.5f), 22.5f, TabGroup.ImpostorRoles, isSingleValue: false).SetHeader(value: true).SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: true); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = RefugeeKillCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return true; } } internal class RiftMaker : RoleBase { private const int Id = 27200; private static readonly HashSet Playerids = new HashSet(); private static OptionItem SSCooldown; private static OptionItem KillCooldown; private static OptionItem TPCooldownOpt; private static OptionItem RiftRadius; private static OptionItem ShowShapeshiftAnimationsOpt; private static readonly Dictionary> MarkedLocation = new Dictionary>(); private static readonly Dictionary LastTP = new Dictionary(); private static float TPCooldown = 0f; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(27200, TabGroup.ImpostorRoles, CustomRoles.RiftMaker); KillCooldown = FloatOptionItem.Create(27210, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]).SetValueFormat(OptionFormat.Seconds); SSCooldown = FloatOptionItem.Create(27211, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]).SetValueFormat(OptionFormat.Seconds); TPCooldownOpt = FloatOptionItem.Create(27212, "TPCooldown", new FloatValueRule(5f, 25f, 2.5f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]).SetValueFormat(OptionFormat.Seconds); RiftRadius = FloatOptionItem.Create(27213, "RiftRadius", new FloatValueRule(0.5f, 2f, 0.5f), 1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]).SetValueFormat(OptionFormat.Multiplier); ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(27214, GeneralOption.ShowShapeshiftAnimations, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]); } public override void Init() { Playerids.Clear(); MarkedLocation.Clear(); LastTP.Clear(); TPCooldown = 0f; } public override void Add(byte playerId) { MarkedLocation[playerId] = new List(); long timeStamp = Utils.GetTimeStamp(); LastTP[playerId] = timeStamp; TPCooldown = TPCooldownOpt.GetFloat(); Playerids.Add(playerId); } private static void SendRPC(byte riftID, int operate) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)161, (SendOption)1, -1); val.Write(operate); if (operate == 3) { ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); return; } val.Write(riftID); switch (operate) { case 0: { int count = MarkedLocation[riftID].Count; val.Write(MarkedLocation[riftID][count - 1].x); val.Write(MarkedLocation[riftID][count - 1].y); val.Write(LastTP[riftID].ToString()); break; } case 2: val.Write(LastTP[riftID].ToString()); break; } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) int num = reader.ReadInt32(); if (num == 3) { long timeStamp = Utils.GetTimeStamp(); byte[] array = LastTP.Keys.ToArray(); foreach (byte key in array) { LastTP[key] = timeStamp; } return; } byte key2 = reader.ReadByte(); switch (num) { case 0: { float num2 = reader.ReadSingle(); float num3 = reader.ReadSingle(); if (!MarkedLocation.ContainsKey(key2)) { MarkedLocation[key2] = new List(); } if (MarkedLocation[key2].Count >= 2) { MarkedLocation[key2].RemoveAt(0); } MarkedLocation[key2].Add(new Vector2(num2, num3)); if (long.TryParse(reader.ReadString(), out var result2)) { LastTP[key2] = result2; } break; } case 1: if (MarkedLocation.ContainsKey(key2)) { MarkedLocation[key2].Clear(); } break; case 2: { if (long.TryParse(reader.ReadString(), out var result)) { LastTP[key2] = result; } break; } } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = SSCooldown.GetFloat(); AURoleOptions.ShapeshifterLeaveSkin = true; AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (shapeshifter.PlayerId == target.PlayerId) { if (shouldAnimate) { shouldAnimate = false; } return true; } if (ShowShapeshiftAnimationsOpt.GetBool()) { return true; } DoRifts(shapeshifter, target); return false; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { if (shapeshifting) { DoRifts(shapeshifter, target); } } private static void DoRifts(PlayerControl shapeshifter, PlayerControl target) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) byte playerId = shapeshifter.PlayerId; if (!MarkedLocation.ContainsKey(playerId)) { MarkedLocation[playerId] = new List(); } Vector2 customPosition = shapeshifter.GetCustomPosition(); int count = MarkedLocation[playerId].Count; if (count == 1 && Vector2.Distance(customPosition, MarkedLocation[playerId][0]) <= 5f) { shapeshifter.Notify(Translator.GetString("RiftsTooClose")); return; } if (count == 2 && Vector2.Distance(customPosition, MarkedLocation[playerId][1]) <= 5f) { shapeshifter.Notify(Translator.GetString("RiftsTooClose")); return; } if (count >= 2) { MarkedLocation[playerId].RemoveAt(0); } MarkedLocation[playerId].Add(shapeshifter.GetCustomPosition()); if (MarkedLocation[playerId].Count == 2) { LastTP[playerId] = Utils.GetTimeStamp(); } shapeshifter.Notify(Translator.GetString("RiftCreated")); SendRPC(playerId, 0); } public override void OnCoEnterVent(PlayerPhysics physics, int ventId) { PlayerControl player = physics.myPlayer; if ((Object)(object)player == (Object)null) { return; } new LateTask(delegate { PlayerPhysics obj = physics; if (obj != null) { obj.RpcBootFromVent(ventId); } MarkedLocation[player.PlayerId].Clear(); SendRPC(player.PlayerId, 1); player.Notify(Translator.GetString("RiftsDestroyed")); }, 0.5f, "RiftMakerOnVent"); } public override void OnFixedUpdateLowLoad(PlayerControl player) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || Pelican.IsEaten(player.PlayerId) || !player.IsAlive()) { return; } byte playerId = player.PlayerId; if (!MarkedLocation.ContainsKey(playerId)) { MarkedLocation[playerId] = new List(); } if (MarkedLocation[playerId].Count != 2) { return; } long timeStamp = Utils.GetTimeStamp(); if (!LastTP.ContainsKey(playerId)) { LastTP[playerId] = timeStamp; } if ((float)(timeStamp - LastTP[playerId]) <= TPCooldown) { return; } Vector2 customPosition = player.GetCustomPosition(); Vector2 position; if (Vector2.Distance(customPosition, MarkedLocation[playerId][0]) <= RiftRadius.GetFloat()) { position = MarkedLocation[playerId][1]; } else { if (!(Vector2.Distance(customPosition, MarkedLocation[playerId][1]) <= RiftRadius.GetFloat())) { return; } position = MarkedLocation[playerId][0]; } LastTP[playerId] = timeStamp; SendRPC(playerId, 2); player.RpcTeleport(position); } public override void AfterMeetingTasks() { long timeStamp = Utils.GetTimeStamp(); byte[] array = LastTP.Keys.ToArray(); foreach (byte key in array) { LastTP[key] = timeStamp; } SendRPC(byte.MaxValue, 3); } } internal class Saboteur : RoleBase { private const int Id = 2300; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem SaboteurCD; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2300, TabGroup.ImpostorRoles, CustomRoles.Saboteur); SaboteurCD = FloatOptionItem.Create(2302, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Saboteur]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = SaboteurCD.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return Utils.AnySabotageIsActive(); } } internal class Scavenger : RoleBase { private const int Id = 4400; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem ScavengerKillCooldown; public static readonly HashSet KilledPlayersId = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4400, TabGroup.ImpostorRoles, CustomRoles.Scavenger); ScavengerKillCooldown = FloatOptionItem.Create(4402, GeneralOption.KillCooldown, new FloatValueRule(5f, 180f, 2.5f), 40f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Scavenger]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); KilledPlayersId.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ScavengerKillCooldown.GetFloat(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) target.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); KilledPlayersId.Add(target.PlayerId); new LateTask(delegate { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) target.RpcMurderPlayer(target); target.SetRealKiller(killer); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Scavenger)), Translator.GetString("KilledByScavenger")), 8f); }, 0.5f, "Scavenger Kill"); killer.SetKillCooldown(); return false; } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { return !killer.Is(CustomRoles.Scavenger); } } internal class ShapeMaster : RoleBase { private const int Id = 4500; private static readonly HashSet Playerids = new HashSet(); private static OptionItem ShapeMasterShapeshiftDuration; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4500, TabGroup.ImpostorRoles, CustomRoles.ShapeMaster); ShapeMasterShapeshiftDuration = FloatOptionItem.Create(4502, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeMaster]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = 1f; AURoleOptions.ShapeshifterLeaveSkin = false; AURoleOptions.ShapeshifterDuration = ShapeMasterShapeshiftDuration.GetFloat(); } } internal class Sniper : RoleBase { private const int Id = 2400; private static readonly HashSet PlayerIdList = new HashSet(); private static OptionItem SniperBulletCount; private static OptionItem SniperPrecisionShooting; private static OptionItem SniperAimAssist; private static OptionItem SniperAimAssistOnshot; private static OptionItem CanKillWithBullets; private static readonly Dictionary snipeTarget = new Dictionary(); private static readonly Dictionary snipeBasePosition = new Dictionary(); private static readonly Dictionary LastPosition = new Dictionary(); private static readonly Dictionary bulletCount = new Dictionary(); private static readonly Dictionary> shotNotify = new Dictionary>(); private static readonly Dictionary IsAim = new Dictionary(); private static readonly Dictionary AimTime = new Dictionary(); private static bool meetingReset; private static int maxBulletCount; private static bool precisionShooting; private static bool AimAssist; private static bool AimAssistOneshot; private static bool SniperCanUseKillButton; public static bool HasEnabled => PlayerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(2400, TabGroup.ImpostorRoles, CustomRoles.Sniper); SniperBulletCount = IntegerOptionItem.Create(2410, "SniperBulletCount", new IntegerValueRule(1, 20, 1), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sniper]).SetValueFormat(OptionFormat.Pieces); SniperPrecisionShooting = BooleanOptionItem.Create(2411, "SniperPrecisionShooting", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sniper]); SniperAimAssist = BooleanOptionItem.Create(2412, "SniperAimAssist", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sniper]); SniperAimAssistOnshot = BooleanOptionItem.Create(2413, "SniperAimAssistOneshot", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(SniperAimAssist); CanKillWithBullets = BooleanOptionItem.Create(2414, "SniperCanKill", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sniper]); } public override void Init() { Logger.Disable("Sniper"); PlayerIdList.Clear(); snipeBasePosition.Clear(); LastPosition.Clear(); snipeTarget.Clear(); bulletCount.Clear(); shotNotify.Clear(); IsAim.Clear(); AimTime.Clear(); meetingReset = false; } public override void Add(byte playerId) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) PlayerIdList.Add(playerId); maxBulletCount = SniperBulletCount.GetInt(); precisionShooting = SniperPrecisionShooting.GetBool(); AimAssist = SniperAimAssist.GetBool(); AimAssistOneshot = SniperAimAssistOnshot.GetBool(); SniperCanUseKillButton = CanKillWithBullets.GetBool(); snipeBasePosition[playerId] = default(Vector3); LastPosition[playerId] = default(Vector3); snipeTarget[playerId] = 127; bulletCount[playerId] = maxBulletCount; shotNotify[playerId] = new List(); IsAim[playerId] = false; AimTime[playerId] = 0f; } private static bool IsThisRole(byte playerId) { return PlayerIdList.Contains(playerId); } public static bool SnipeIsActive(byte playerId) { return snipeTarget.ContainsValue(playerId); } private static void SendRPC(byte playerId) { Logger.Info($"Player{playerId}:SendRPC", "Sniper", escapeCRLF: true, 94, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)142, (SendOption)1, -1); val.Write(playerId); List list = shotNotify[playerId]; val.Write(list.Count); foreach (byte item in list) { val.Write(item); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader msg) { byte b = msg.ReadByte(); shotNotify[b].Clear(); for (int num = msg.ReadInt32(); num > 0; num--) { shotNotify[b].Add(msg.ReadByte()); } Logger.Info($"Player{b}:ReceiveRPC", "Sniper", escapeCRLF: true, 115, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = Options.DefaultShapeshiftCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { if (!pc.IsAlive()) { return false; } bool flag = false; if (!bulletCount.ContainsKey(pc.PlayerId)) { Logger.Info(" Sniper not Init yet.", "Sniper", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); return false; } if (bulletCount[pc.PlayerId] <= 0) { flag = true; } if (SniperCanUseKillButton) { flag = true; } Logger.Info($" CanUseKillButton:{flag}", "Sniper", escapeCRLF: true, 140, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); return flag; } private static Dictionary GetSnipeTargets(PlayerControl sniper) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); Vector3 val = snipeBasePosition[sniper.PlayerId]; Vector3 position = ((Component)sniper).transform.position; Vector3 val2 = position - val; Vector3 normalized = ((Vector3)(ref val2)).normalized; position -= normalized; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val3 in allAlivePlayerControls) { if (val3.PlayerId == sniper.PlayerId) { continue; } Vector3 val4 = ((Component)val3).transform.position - position; if (((Vector3)(ref val4)).magnitude < 1f) { continue; } Vector3 normalized2 = ((Vector3)(ref val4)).normalized; float num = Vector3.Dot(normalized, normalized2); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(10, 3); object value; if (val3 == null) { value = null; } else { NetworkedPlayerInfo data = val3.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(":pos="); defaultInterpolatedStringHandler.AppendFormatted(val4); defaultInterpolatedStringHandler.AppendLiteral(" dir="); defaultInterpolatedStringHandler.AppendFormatted(normalized2); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Sniper", escapeCRLF: true, 166, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); Logger.Info($" Dot={num}", "Sniper", escapeCRLF: true, 167, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); if ((double)num < 0.995) { continue; } if (precisionShooting) { val2 = Vector3.Cross(normalized, val4); float magnitude = ((Vector3)(ref val2)).magnitude; Logger.Info($" err={magnitude}", "Sniper", escapeCRLF: true, 177, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); if ((double)magnitude < 0.5) { dictionary.Add(val3, magnitude); } } else { float magnitude2 = ((Vector3)(ref val4)).magnitude; Logger.Info($" err={magnitude2}", "Sniper", escapeCRLF: true, 188, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Sniper.cs"); dictionary.Add(val3, magnitude2); } } return dictionary; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool animate, bool shapeshifting) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) byte sniperId = shapeshifter.PlayerId; if (bulletCount[sniperId] <= 0) { return; } if (shapeshifting) { meetingReset = false; snipeBasePosition[sniperId] = ((Component)shapeshifter).transform.position; LastPosition[sniperId] = ((Component)shapeshifter).transform.position; IsAim[sniperId] = true; AimTime[sniperId] = 0f; return; } IsAim[sniperId] = false; AimTime[sniperId] = 0f; if (meetingReset) { meetingReset = false; return; } bulletCount[sniperId]--; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } shapeshifter.RPCPlayCustomSound("AWP"); Dictionary targets = GetSnipeTargets(shapeshifter); if (targets.Count == 0) { return; } PlayerControl key = targets.OrderBy((KeyValuePair c) => c.Value).First().Key; snipeTarget[sniperId] = key.PlayerId; key.CheckMurder(key); if (!Options.DisableShieldAnimations.GetBool()) { shapeshifter.RpcGuardAndKill(); } else { shapeshifter.SetKillCooldown(); } snipeTarget[sniperId] = 127; targets.Remove(key); List snList = shotNotify[sniperId]; snList.Clear(); foreach (PlayerControl key2 in targets.Keys) { snList.Add(key2.PlayerId); Utils.NotifyRoles(key2); } SendRPC(sniperId); new LateTask(delegate { snList.Clear(); foreach (PlayerControl key3 in targets.Keys) { Utils.NotifyRoles(key3); } SendRPC(sniperId); }, 0.5f, "Sniper shot Notify"); } public static void OnFixedUpdateGlobal(PlayerControl pc) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (!HasEnabled || !IsThisRole(pc.PlayerId) || !pc.IsAlive() || !AimAssist) { return; } byte playerId = pc.PlayerId; if (!IsAim[playerId]) { return; } if (!GameStates.IsInTask) { IsAim[playerId] = false; AimTime[playerId] = 0f; return; } Vector3 position = ((Component)pc).transform.position; if (position != LastPosition[playerId]) { AimTime[playerId] = 0f; LastPosition[playerId] = position; } else { AimTime[playerId] += Time.fixedDeltaTime; Utils.NotifyRoles(pc); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { meetingReset = true; } public override string GetProgressText(byte playerId, bool comms) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Color.yellow), $"({bulletCount[playerId]})"); } public static bool TryGetSniper(byte targetId, ref PlayerControl sniper) { foreach (KeyValuePair item in snipeTarget) { if (item.Value == targetId) { sniper = Utils.GetPlayerById(item.Key); return true; } } return false; } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting) { return string.Empty; } if (seen == null) { seen = seer; } PlayerControl playerById = Utils.GetPlayerById(PlayerIdList.First()); if (!((Object)(object)playerById == (Object)(object)seer) || !((Object)(object)playerById == (Object)(object)seen)) { return string.Empty; } byte playerId = seer.PlayerId; if (AimAssist && 0.5f < AimTime[playerId] && (!AimAssistOneshot || AimTime[playerId] < 1f) && GetSnipeTargets(Utils.GetPlayerById(playerId)).Any()) { return "" + Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed), "◎") + ""; } return string.Empty; } public override string GetMarkOthers(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting) { return string.Empty; } foreach (byte playerId in PlayerIdList) { List list = shotNotify[playerId]; if (list.Any() && list.Contains(seer.PlayerId)) { return "" + Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed), "!") + ""; } } return string.Empty; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (IsThisRole(playerId)) { AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString((bulletCount[playerId] <= 0) ? "DefaultShapeshiftText" : "SniperSnipeButtonText")); } } } } internal class SoulCatcher : RoleBase { private const int Id = 4600; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem ShapeSoulCatcherShapeshiftDuration; private static OptionItem SoulCatcherShapeshiftCooldown; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4600, TabGroup.ImpostorRoles, CustomRoles.SoulCatcher); ShapeSoulCatcherShapeshiftDuration = FloatOptionItem.Create(4602, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(2.5f, 180f, 2.5f), 300f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SoulCatcher]).SetValueFormat(OptionFormat.Seconds); SoulCatcherShapeshiftCooldown = FloatOptionItem.Create(4603, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SoulCatcher]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterDuration = ShapeSoulCatcherShapeshiftDuration.GetFloat(); AURoleOptions.ShapeshifterCooldown = SoulCatcherShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterLeaveSkin = false; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("SoulCatcherButtonText")); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Teleport"); } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } if (shapeshifter.CanBeTeleported() && target.CanBeTeleported()) { Vector2 customPosition = target.GetCustomPosition(); target.RpcTeleport(shapeshifter.GetCustomPosition()); shapeshifter.RpcTeleport(customPosition); shapeshifter.RPCPlayCustomSound("Teleport"); target.RPCPlayCustomSound("Teleport"); } else { shapeshifter.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SoulCatcher)), Translator.GetString("ErrorTeleport"))); } return false; } } internal class Stealth : RoleBase { private const int Id = 27400; private static OptionItem optionExcludeImpostors; private static OptionItem optionDarkenDuration; private static bool excludeImpostors; private static float darkenDuration; private float darkenTimer; private PlayerControl[] darkenedPlayers; private SystemTypes? darkenedRoom; public static bool HasEnabled => CustomRoles.Stealth.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(27400, TabGroup.ImpostorRoles, CustomRoles.Stealth); optionExcludeImpostors = BooleanOptionItem.Create(27410, "StealthExcludeImpostors", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stealth]); optionDarkenDuration = FloatOptionItem.Create(27420, "StealthDarkenDuration", new FloatValueRule(0.5f, 10f, 0.5f), 3f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stealth]).SetValueFormat(OptionFormat.Seconds); } public override void Add(byte playerId) { excludeImpostors = optionExcludeImpostors.GetBool(); darkenDuration = (darkenTimer = optionDarkenDuration.GetFloat()); darkenedPlayers = null; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { PlayerControl[] array = FindPlayersInSameRoom(target); if (array == null) { Logger.Info("The room will not dim because the hit detection for the room cannot be obtained.", "Stealth", escapeCRLF: true, 47, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Stealth.cs"); return true; } if (excludeImpostors) { array = array.Where((PlayerControl player) => !player.Is(CustomRoles.Impostor)).ToArray(); } DarkenPlayers(array); return true; } private PlayerControl[] FindPlayersInSameRoom(PlayerControl killedPlayer) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) PlainShipRoom plainShipRoom = killedPlayer.GetPlainShipRoom(); if ((Object)(object)plainShipRoom == (Object)null) { return null; } Collider2D roomArea = plainShipRoom.roomArea; SystemTypes roomId = plainShipRoom.RoomId; RpcDarken(roomId); return Main.AllAlivePlayerControls.Where((PlayerControl player) => (Object)(object)player != (Object)(object)base._Player && player.Collider.IsTouching(roomArea)).ToArray(); } private void DarkenPlayers(PlayerControl[] playersToDarken) { int num = 0; PlayerControl[] array = (PlayerControl[])(object)new PlayerControl[playersToDarken.Length]; foreach (PlayerControl val in playersToDarken) { array[num] = val; num++; } darkenedPlayers = array; array = playersToDarken; foreach (PlayerControl val2 in array) { Main.PlayerStates[val2.PlayerId].IsBlackOut = true; val2.MarkDirtySettings(); } } public override void OnFixedUpdate(PlayerControl player) { if (darkenedPlayers != null) { darkenTimer -= Time.fixedDeltaTime; if (darkenTimer <= 0f) { ResetDarkenState(); } } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { ResetDarkenState(); } } private void RpcDarken(SystemTypes? roomType) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) object obj; if (!roomType.HasValue) { obj = null; } else { SystemTypes valueOrDefault = roomType.GetValueOrDefault(); obj = ((object)(SystemTypes)(ref valueOrDefault)).ToString(); } if (obj == null) { obj = "null"; } Logger.Info("Set the darkened room to " + (string?)obj, "Stealth", escapeCRLF: true, 103, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Stealth.cs"); darkenedRoom = roomType; SendRPC(roomType); } private void SendRPC(SystemTypes? roomType) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write((byte)(((int?)roomType) ?? 255)); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte b = reader.ReadByte(); darkenedRoom = ((b == byte.MaxValue) ? null : new SystemTypes?((SystemTypes)b)); } private void ResetDarkenState() { if (darkenedPlayers != null) { PlayerControl[] array = darkenedPlayers; foreach (PlayerControl val in array) { Main.PlayerStates[val.PlayerId].IsBlackOut = false; val.MarkDirtySettings(); } darkenedPlayers = null; } darkenTimer = darkenDuration; RpcDarken(null); Utils.NotifyRoles(base._Player, base._Player); } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } PlayerControl player = base._Player; if (!HasEnabled || isForMeeting || (Object)(object)seer != (Object)(object)player || (Object)(object)seen != (Object)(object)player || !darkenedRoom.HasValue) { return string.Empty; } return string.Format(Translator.GetString("StealthDarkened"), DestroyableSingleton.Instance.GetString(darkenedRoom.Value)); } } internal class Swooper : RoleBase { private const int Id = 4700; private static OptionItem SwooperCooldown; private static OptionItem SwooperDuration; private static OptionItem SwooperVentNormallyOnCooldown; private static readonly Dictionary ventedId = new Dictionary(); private static readonly Dictionary InvisCooldown = new Dictionary(); private static readonly Dictionary InvisDuration = new Dictionary(); public static bool HasEnabled => CustomRoles.Swooper.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4700, TabGroup.ImpostorRoles, CustomRoles.Swooper); SwooperCooldown = FloatOptionItem.Create(4702, "SwooperCooldown", new FloatValueRule(1f, 180f, 1f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swooper]).SetValueFormat(OptionFormat.Seconds); SwooperDuration = FloatOptionItem.Create(4704, "SwooperDuration", new FloatValueRule(1f, 60f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swooper]).SetValueFormat(OptionFormat.Seconds); SwooperVentNormallyOnCooldown = BooleanOptionItem.Create(4705, "SwooperVentNormallyOnCooldown", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swooper]); } public override void Init() { InvisCooldown.Clear(); InvisDuration.Clear(); ventedId.Clear(); } public override void Add(byte playerId) { InvisCooldown[playerId] = Utils.GetTimeStamp(); } private void SendRPC(PlayerControl pc) { if (!((InnerNetObject)pc).AmOwner) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, pc.GetClientId()); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write((InvisCooldown.TryGetValue(pc.PlayerId, out var value) ? value : (-1)).ToString()); val.Write((InvisDuration.TryGetValue(pc.PlayerId, out var value2) ? value2 : (-1)).ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { InvisCooldown.Clear(); InvisDuration.Clear(); long num = long.Parse(reader.ReadString()); long num2 = long.Parse(reader.ReadString()); if (num > 0) { InvisCooldown.Add(PlayerControl.LocalPlayer.PlayerId, num); } if (num2 > 0) { InvisCooldown.Add(PlayerControl.LocalPlayer.PlayerId, num2); } } private static bool CanGoInvis(byte id) { if (GameStates.IsInTask) { return !InvisCooldown.ContainsKey(id); } return false; } private static bool IsInvis(byte id) { return InvisDuration.ContainsKey(id); } public override void OnEnterVent(PlayerControl swooper, Vent vent) { byte playerId = swooper.PlayerId; if (!IsInvis(playerId)) { return; } InvisDuration.Remove(playerId); InvisCooldown.Remove(playerId); InvisCooldown.Add(playerId, Utils.GetTimeStamp()); SendRPC(swooper); if (swooper != null) { PlayerPhysics myPhysics = swooper.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(vent.Id); } } swooper.Notify(Translator.GetString("SwooperInvisStateOut")); } public override void OnCoEnterVent(PlayerPhysics physics, int ventId) { PlayerControl swooper = physics.myPlayer; byte swooperId = swooper.PlayerId; if (!((InnerNetClient)AmongUsClient.Instance).AmHost || IsInvis(swooperId)) { return; } new LateTask(delegate { if (CanGoInvis(swooperId)) { ventedId.Remove(swooperId); ventedId.Add(swooperId, ventId); physics.RpcBootFromVentDesync(ventId, swooper); InvisDuration.Remove(swooperId); InvisDuration.Add(swooperId, Utils.GetTimeStamp()); SendRPC(swooper); swooper.Notify(Translator.GetString("SwooperInvisState"), SwooperDuration.GetFloat()); } else if (!SwooperVentNormallyOnCooldown.GetBool()) { PlayerPhysics obj = physics; if (obj != null) { obj.RpcBootFromVent(ventId); } swooper.Notify(Translator.GetString("SwooperInvisInCooldown")); } }, 0.8f, "Swooper Vent"); } public override void OnFixedUpdateLowLoad(PlayerControl player) { long timeStamp = Utils.GetTimeStamp(); byte playerId = player.PlayerId; bool flag = false; if (InvisCooldown.TryGetValue(playerId, out var value) && value + (long)SwooperCooldown.GetFloat() - timeStamp < 0) { InvisCooldown.Remove(playerId); if (!player.IsModClient()) { player.Notify(Translator.GetString("SwooperCanVent")); } flag = true; } foreach (KeyValuePair item in InvisDuration) { byte key = item.Key; PlayerControl playerById = Utils.GetPlayerById(key); if ((Object)(object)playerById == (Object)null) { continue; } long num = item.Value + (long)SwooperDuration.GetFloat() - timeStamp; if (num < 0 || !playerById.IsAlive()) { if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(key, out var value2) ? value2 : Main.LastEnteredVent[key].Id); } } ventedId.Remove(key); InvisCooldown.Remove(key); InvisCooldown.Add(key, timeStamp); playerById.Notify(Translator.GetString("SwooperInvisStateOut")); flag = true; InvisDuration.Remove(key); } else if (num <= 10 && !playerById.IsModClient()) { playerById.Notify(string.Format(Translator.GetString("SwooperInvisStateCountdown"), num), 4f, sendInLog: false); } } if (flag) { SendRPC(player); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!IsInvis(killer.PlayerId)) { return true; } killer.RpcGuardAndKill(target); killer.SetKillCooldown(); target.RpcMurderPlayer(target); target.SetRealKiller(killer); return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { foreach (byte playerId in base._playerIdList) { if (!IsInvis(playerId)) { continue; } PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null) { continue; } if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(playerId, out var value) ? value : Main.LastEnteredVent[playerId].Id); } } InvisDuration.Remove(playerId); ventedId.Remove(playerId); SendRPC(playerById); } InvisCooldown.Clear(); InvisDuration.Clear(); ventedId.Clear(); } public override void AfterMeetingTasks() { InvisCooldown.Clear(); InvisDuration.Clear(); foreach (byte playerId in base._playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (playerById.IsAlive()) { InvisCooldown.Add(playerId, Utils.GetTimeStamp()); SendRPC(playerById); } } } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)seer == (Object)null || !isForHud || isForMeeting || !seer.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); byte playerId = seer.PlayerId; long value; if (IsInvis(playerId)) { long num = InvisDuration[playerId] + (long)SwooperDuration.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("SwooperInvisStateCountdown"), num + 1)); } else if (InvisCooldown.TryGetValue(playerId, out value)) { long num2 = value + (long)SwooperCooldown.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("SwooperInvisCooldownRemain"), num2 + 1)); } else { stringBuilder.Append(Translator.GetString("SwooperCanVent")); } return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { VentButton impostorVentButton = hud.ImpostorVentButton; if (impostorVentButton != null) { ((ActionButton)impostorVentButton).OverrideText(Translator.GetString(IsInvis(playerId) ? "SwooperRevertVentButtonText" : "SwooperVentButtonText")); } } public override Sprite ImpostorVentButtonSprite(PlayerControl player) { return CustomButton.Get("invisible"); } } internal class TimeThief : RoleBase { private const int Id = 3700; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem DecreaseMeetingTime; public static OptionItem LowerLimitVotingTime; private static OptionItem ReturnStolenTimeUponDeath; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3700, TabGroup.ImpostorRoles, CustomRoles.TimeThief); KillCooldown = FloatOptionItem.Create(3710, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeThief]).SetValueFormat(OptionFormat.Seconds); DecreaseMeetingTime = IntegerOptionItem.Create(3711, "TimeThiefDecreaseMeetingTime", new IntegerValueRule(0, 100, 1), 25, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeThief]).SetValueFormat(OptionFormat.Seconds); LowerLimitVotingTime = IntegerOptionItem.Create(3712, "TimeThiefLowerLimitVotingTime", new IntegerValueRule(1, 300, 1), 10, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeThief]).SetValueFormat(OptionFormat.Seconds); ReturnStolenTimeUponDeath = BooleanOptionItem.Create(3713, "TimeThiefReturnStolenTimeUponDeath", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeThief]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } private static int StolenTime(byte id) { if (!playerIdList.Contains(id) || (!Utils.GetPlayerById(id).IsAlive() && ReturnStolenTimeUponDeath.GetBool())) { return 0; } return DecreaseMeetingTime.GetInt() * Main.PlayerStates[id].GetKillCount(ExcludeSelfKill: true); } public static int TotalDecreasedMeetingTime() { int num = 0; foreach (byte playerId in playerIdList) { num -= StolenTime(playerId); } Logger.Info($"{num}second", "TimeThief.TotalDecreasedMeetingTime", escapeCRLF: true, 57, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\TimeThief.cs"); return num; } public override string GetProgressText(byte playerId, bool cooms) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (StolenTime(playerId) <= 0) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed.ShadeColor(0.5f)), $"{-StolenTime(playerId)}s"); } } internal class Trapster : RoleBase { private const int Id = 2600; private static readonly HashSet Playerids = new HashSet(); private static OptionItem TrapsterKillCooldown; private static OptionItem TrapConsecutiveBodies; private static OptionItem TrapTrapsterBody; private static OptionItem TrapConsecutiveTrapsterBodies; private static readonly HashSet BoobyTrapBody = new HashSet(); private static readonly Dictionary KillerOfBoobyTrapBody = new Dictionary(); public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2600, TabGroup.ImpostorRoles, CustomRoles.Trapster); TrapsterKillCooldown = FloatOptionItem.Create(2602, GeneralOption.KillCooldown, new FloatValueRule(2.5f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapster]).SetValueFormat(OptionFormat.Seconds); TrapConsecutiveBodies = BooleanOptionItem.Create(2603, "TrapConsecutiveBodies", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapster]); TrapTrapsterBody = BooleanOptionItem.Create(2604, "TrapTrapsterBody", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapster]); TrapConsecutiveTrapsterBodies = BooleanOptionItem.Create(2605, "TrapConsecutiveBodies", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(TrapTrapsterBody); } public override void Init() { BoobyTrapBody.Clear(); KillerOfBoobyTrapBody.Clear(); Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Clear(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = TrapsterKillCooldown.GetFloat(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { BoobyTrapBody.Add(target.PlayerId); return true; } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (deadBody.Object.Is(CustomRoles.Trapster) && TrapTrapsterBody.GetBool() && !reporter.Is(CustomRoles.Pestilence)) { byte playerId = deadBody.PlayerId; reporter.SetDeathReason(PlayerState.DeathReason.Trap); reporter.RpcMurderPlayer(reporter); reporter.SetRealKiller(deadBody.Object); RPC.PlaySoundRPC(playerId, Sounds.KillSound); if (TrapConsecutiveTrapsterBodies.GetBool()) { BoobyTrapBody.Add(reporter.PlayerId); } return false; } if (BoobyTrapBody.Contains(deadBody.PlayerId) && reporter.IsAlive() && !reporter.Is(CustomRoles.Pestilence) && base._Player.RpcCheckAndMurder(reporter, check: true)) { byte playerId2 = deadBody.PlayerId; reporter.SetDeathReason(PlayerState.DeathReason.Trap); reporter.RpcMurderPlayer(reporter); reporter.SetRealKiller(base._Player); RPC.PlaySoundRPC(playerId2, Sounds.KillSound); if (TrapConsecutiveBodies.GetBool()) { BoobyTrapBody.Add(reporter.PlayerId); } return false; } return true; } } internal class Trickster : RoleBase { private const int Id = 4800; private static readonly HashSet PlayerIds = new HashSet(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4800, TabGroup.ImpostorRoles, CustomRoles.Trickster); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } } internal class Twister : RoleBase { private const int Id = 5700; private static OptionItem ShapeshiftCooldown; private static OptionItem ShapeshiftDuration; private static OptionItem HideTwistedPlayerNames; private static HashSet changePositionPlayers = new HashSet(); public static bool HasEnabled => CustomRoles.Twister.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; public override void SetupCustomOption() { Options.SetupRoleOptions(5700, TabGroup.ImpostorRoles, CustomRoles.Twister); ShapeshiftCooldown = FloatOptionItem.Create(5710, "TwisterCooldown", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Twister]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDuration = FloatOptionItem.Create(5711, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 999f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Twister]).SetValueFormat(OptionFormat.Seconds); HideTwistedPlayerNames = BooleanOptionItem.Create(5712, "TwisterHideTwistedPlayerNames", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Twister]); } public override void Init() { changePositionPlayers.Clear(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDuration.GetFloat(); } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl targetSS, bool IsAnimate, bool shapeshifting) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == targetSS.PlayerId && !IsAnimate) { return; } changePositionPlayers = new HashSet { shapeshifter.PlayerId }; _ = IRandom.Instance; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl pc in allAlivePlayerControls) { if (!changePositionPlayers.Contains(pc.PlayerId) && pc.CanBeTeleported()) { List list = Main.AllAlivePlayerControls.Where((PlayerControl a) => pc.CanBeTeleported() && a.PlayerId != pc.PlayerId && !changePositionPlayers.Contains(a.PlayerId)).ToList(); if (list.Count == 0) { break; } PlayerControl val = list.RandomElement(); changePositionPlayers.Add(val.PlayerId); changePositionPlayers.Add(pc.PlayerId); pc.RPCPlayCustomSound("Teleport"); Vector2 customPosition = val.GetCustomPosition(); val.RpcTeleport(pc.GetCustomPosition()); pc.RpcTeleport(customPosition); if (!HideTwistedPlayerNames.GetBool()) { val.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Twister)), string.Format(Translator.GetString("TeleportedByTransporter"), pc.GetRealName()))); pc.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Twister)), string.Format(Translator.GetString("TeleportedByTransporter"), val.GetRealName()))); } } } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString("TwisterButtonText")); } } } internal class Underdog : RoleBase { private const int Id = 2700; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem UnderdogMaximumPlayersNeededToKill; private static OptionItem UnderdogKillCooldown; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2700, TabGroup.ImpostorRoles, CustomRoles.Underdog); UnderdogMaximumPlayersNeededToKill = IntegerOptionItem.Create(2702, "UnderdogMaximumPlayersNeededToKill", new IntegerValueRule(1, 15, 1), 5, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Underdog]).SetValueFormat(OptionFormat.Players); UnderdogKillCooldown = FloatOptionItem.Create(2703, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 12.5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Underdog]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerIds.Add(playerId); } public override bool CanUseKillButton(PlayerControl pc) { return Main.AllAlivePlayerControls.Length <= UnderdogMaximumPlayersNeededToKill.GetInt(); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = UnderdogKillCooldown.GetFloat(); } } internal class Undertaker : RoleBase { private const int Id = 4900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem SSCooldown; private static OptionItem KillCooldown; private static OptionItem FreezeTime; private static readonly Dictionary MarkedLocation = new Dictionary(); private static float DefaultSpeed = 0f; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(4900, TabGroup.ImpostorRoles, CustomRoles.Undertaker); KillCooldown = FloatOptionItem.Create(4910, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 20f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Undertaker]).SetValueFormat(OptionFormat.Seconds); SSCooldown = FloatOptionItem.Create(4911, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Undertaker]).SetValueFormat(OptionFormat.Seconds); FreezeTime = FloatOptionItem.Create(4913, "UndertakerFreezeDuration", new FloatValueRule(1f, 5f, 1f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Undertaker]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); MarkedLocation.Clear(); DefaultSpeed = 0f; } public override void Add(byte playerId) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) playerIdList.Add(playerId); MarkedLocation.TryAdd(playerId, ExtendedPlayerControl.GetBlackRoomPosition()); DefaultSpeed = Main.AllPlayerSpeed[playerId]; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = SSCooldown.GetFloat(); AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); } private static void SendRPC(byte playerId) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)160, (SendOption)1, -1); val.Write(playerId); float x = MarkedLocation[playerId].x; val.Write(x); float y = MarkedLocation[playerId].y; val.Write(y); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) byte key = reader.ReadByte(); float num = reader.ReadSingle(); float num2 = reader.ReadSingle(); if (MarkedLocation.ContainsKey(key)) { MarkedLocation[key] = new Vector2(num, num2); } else { MarkedLocation.Add(key, ExtendedPlayerControl.GetBlackRoomPosition()); } } public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (shapeshifter.PlayerId == target.PlayerId) { return false; } byte playerId = shapeshifter.PlayerId; MarkedLocation[playerId] = shapeshifter.GetCustomPosition(); SendRPC(playerId); shapeshifter.Notify(Translator.GetString("RejectShapeshift.AbilityWasUsed"), 2f); return false; } private static void FreezeUndertaker(PlayerControl player) { Main.AllPlayerSpeed[player.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[player.PlayerId] = false; player.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[player.PlayerId] = DefaultSpeed; ReportDeadBodyPatch.CanReport[player.PlayerId] = true; player.MarkDirtySettings(); }, FreezeTime.GetFloat(), "Freeze Undertaker"); } private static bool HasMarkedLoc(byte playerId) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (MarkedLocation.TryGetValue(playerId, out var value)) { return value != ExtendedPlayerControl.GetBlackRoomPosition(); } return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!HasMarkedLoc(killer.PlayerId)) { return true; } if (target.Is(CustomRoles.Bait)) { return true; } if (target.CanBeTeleported()) { Vector2 position = MarkedLocation[killer.PlayerId]; target.RpcTeleport(position); killer.SetKillCooldown(); target.RpcMurderPlayer(target); target.SetRealKiller(killer); MarkedLocation[killer.PlayerId] = ExtendedPlayerControl.GetBlackRoomPosition(); SendRPC(killer.PlayerId); FreezeUndertaker(killer); killer.SyncSettings(); } return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) foreach (byte key in MarkedLocation.Keys) { MarkedLocation[key] = ExtendedPlayerControl.GetBlackRoomPosition(); Main.AllPlayerSpeed[key] = DefaultSpeed; SendRPC(key); } } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("KillButtonText")); } AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString("UndertakerButtonText")); } } } internal class Vampire : RoleBase { private class BittenInfo { public byte VampireId; public float KillTimer; public BittenInfo(byte vampierId, float killTimer) { VampireId = vampierId; KillTimer = killTimer; base..ctor(); } } private enum ActionModeList { Vampire_OnlyBites, TriggerDouble } private const int Id = 5000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem OptionKillDelay; private static OptionItem CanVent; private static OptionItem ActionModeOpt; private static ActionModeList NowActionMode; private static float KillDelay = 0f; private static readonly Dictionary BittenPlayers = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(5000, TabGroup.ImpostorRoles, CustomRoles.Vampire); OptionKillDelay = FloatOptionItem.Create(5010, "VampireKillDelay", new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vampire]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(5011, GeneralOption.CanVent, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vampire]); ActionModeOpt = StringOptionItem.Create(5012, "VampireActionMode", EnumHelper.GetAllNames(), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vampire]); } public override void Init() { playerIdList.Clear(); BittenPlayers.Clear(); KillDelay = OptionKillDelay.GetFloat(); NowActionMode = (ActionModeList)ActionModeOpt.GetValue(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (NowActionMode == ActionModeList.TriggerDouble) { Utils.GetPlayerById(playerId)?.AddDoubleTrigger(); } } public static bool CheckCanUseVent() { return CanVent.GetBool(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CheckCanUseVent(); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (target.Is(CustomRoles.Bait)) { return true; } if (NowActionMode == ActionModeList.Vampire_OnlyBites) { killer.SetKillCooldown(); killer.RPCPlayCustomSound("Bite"); if (!BittenPlayers.ContainsKey(target.PlayerId)) { BittenPlayers.Add(target.PlayerId, new BittenInfo(killer.PlayerId, 0f)); } } else if (NowActionMode == ActionModeList.TriggerDouble) { return killer.CheckDoubleTrigger(target, delegate { killer.SetKillCooldown(); killer.RPCPlayCustomSound("Bite"); if (!BittenPlayers.ContainsKey(target.PlayerId)) { BittenPlayers.Add(target.PlayerId, new BittenInfo(killer.PlayerId, 0f)); } }); } return false; } public override void OnFixedUpdate(PlayerControl vampire) { byte vampireID = vampire.PlayerId; foreach (byte item in new List(from b in BittenPlayers where b.Value.VampireId == vampireID select b.Key)) { BittenInfo bittenInfo = BittenPlayers[item]; if (bittenInfo.KillTimer >= KillDelay) { Logger.Info("KillTimer >= KillDelay", "Vampire", escapeCRLF: true, 110, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Vampire.cs"); PlayerControl playerById = Utils.GetPlayerById(item); KillBitten(vampire, playerById); BittenPlayers.Remove(item); } else { bittenInfo.KillTimer += Time.fixedDeltaTime; BittenPlayers[item] = bittenInfo; } } } private static void KillBitten(PlayerControl vampire, PlayerControl target) { if (target.Data.Disconnected) { return; } if (target.IsAlive()) { target.SetDeathReason(PlayerState.DeathReason.Bite); target.RpcMurderPlayer(target); target.SetRealKiller(vampire); Logger.Info(((Object)target).name + " self-kill while being bitten by Vampire.", "Vampire", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Vampire.cs"); if (vampire.IsAlive()) { RPC.PlaySoundRPC(vampire.PlayerId, Sounds.KillSound); if (target.Is(CustomRoles.Trapper)) { vampire.TrapperKilled(target); } vampire.Notify(Translator.GetString("VampireTargetDead")); vampire.SetKillCooldown(); } } else { Logger.Info(((Object)target).name + " was dead after being bitten by Vampire", "Vampire", escapeCRLF: true, 147, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Vampire.cs"); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody) { foreach (byte key in BittenPlayers.Keys) { PlayerControl playerById = Utils.GetPlayerById(key); KillBitten(Utils.GetPlayerById(BittenPlayers[key].VampireId), playerById); } BittenPlayers.Clear(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("VampireBiteButtonText")); } } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Bite"); } } internal class Vindicator : RoleBase { private const int Id = 3800; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VindicatorAdditionalVote; private static OptionItem VindicatorHideVote; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3800, TabGroup.ImpostorRoles, CustomRoles.Vindicator); VindicatorAdditionalVote = IntegerOptionItem.Create(3802, "MayorAdditionalVote", new IntegerValueRule(1, 20, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vindicator]).SetValueFormat(OptionFormat.Votes); VindicatorHideVote = BooleanOptionItem.Create(3803, GeneralOption.HideAdditionalVotes, defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vindicator]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!VindicatorHideVote.GetBool()) { for (int i = 0; i < VindicatorAdditionalVote.GetInt(); i++) { statesList.Add(new VoterState { VoterId = votedPlayer.TargetPlayerId, VotedForId = votedPlayer.VotedFor }); } } } public override int AddRealVotesNum(PlayerVoteArea PVA) { return VindicatorAdditionalVote.GetInt(); } } internal class Visionary : RoleBase { private const int Id = 3900; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(3900, TabGroup.ImpostorRoles, CustomRoles.Visionary); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!seer.IsAlive() || !target.IsAlive() || target.Data.IsDead) { return string.Empty; } CustomRoles customRole = target.GetCustomRole(); using (List.Enumerator enumerator = target.GetCustomSubRoles().GetEnumerator()) { while (enumerator.MoveNext()) { bool flag; switch (enumerator.Current) { case CustomRoles.Refugee: case CustomRoles.Admired: case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Egoist: case CustomRoles.Infected: case CustomRoles.Recruit: case CustomRoles.Soulless: flag = true; break; default: flag = false; break; } if (flag) { return Main.roleColors[CustomRoles.Knight]; } } } if (customRole.IsImpostorTeamV2() || customRole.IsMadmate()) { return Main.roleColors[CustomRoles.Impostor]; } if (customRole.IsCrewmate()) { return Main.roleColors[CustomRoles.Bait]; } return Main.roleColors[CustomRoles.Knight]; } } internal class Warlock : RoleBase { private const int Id = 5100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem WarlockCanKillAllies; private static OptionItem WarlockCanKillSelf; private static OptionItem WarlockShiftDuration; private static readonly Dictionary WarlockTimer = new Dictionary(); private static readonly Dictionary CursedPlayers = new Dictionary(); private static readonly Dictionary IsCurseAndKill = new Dictionary(); private static bool IsCursed = false; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupRoleOptions(5100, TabGroup.ImpostorRoles, CustomRoles.Warlock); WarlockCanKillAllies = BooleanOptionItem.Create(5102, GeneralOption.CanKillImpostors, defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warlock]); WarlockCanKillSelf = BooleanOptionItem.Create(5103, "Warlock_CanKillSelf", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warlock]); WarlockShiftDuration = FloatOptionItem.Create(5104, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warlock]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); CursedPlayers.Clear(); IsCurseAndKill.Clear(); WarlockTimer.Clear(); IsCursed = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); CursedPlayers.Add(playerId, null); IsCurseAndKill.Add(playerId, value: false); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = (IsCursed ? 1f : Options.DefaultKillCooldown); AURoleOptions.ShapeshifterDuration = WarlockShiftDuration.GetFloat(); } public static bool CursedIsActive(PlayerControl player) { return CursedPlayers.ContainsValue(player); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (!Main.CheckShapeshift[killer.PlayerId] && !IsCurseAndKill[killer.PlayerId]) { if (target.Is(CustomRoles.LazyGuy) || target.Is(CustomRoles.Lazy) || (target.Is(CustomRoles.NiceMini) && Mini.Age < 18)) { return false; } IsCursed = true; killer.SetKillCooldown(); killer.RPCPlayCustomSound("Line"); CursedPlayers[killer.PlayerId] = target; WarlockTimer.Add(killer.PlayerId, 0f); IsCurseAndKill[killer.PlayerId] = true; return false; } if (Main.CheckShapeshift[killer.PlayerId]) { killer.RpcCheckAndMurder(target); return false; } if (IsCurseAndKill[killer.PlayerId]) { killer.RpcGuardAndKill(target); } return false; } public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)CursedPlayers[shapeshifter.PlayerId] != (Object)null) { if (shapeshifting && CursedPlayers[shapeshifter.PlayerId].IsAlive()) { PlayerControl val = CursedPlayers[shapeshifter.PlayerId]; Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position); Dictionary dictionary = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val3 in allAlivePlayerControls) { if (val3.PlayerId != val.PlayerId && (WarlockCanKillSelf.GetBool() || val3.PlayerId != shapeshifter.PlayerId) && (WarlockCanKillAllies.GetBool() || !val3.GetCustomRole().IsImpostor()) && !Pelican.IsEaten(val3.PlayerId) && !Medic.ProtectList.Contains(val3.PlayerId) && !val3.Is(CustomRoles.Glitch) && !val3.Is(CustomRoles.Pestilence)) { float value = Vector2.Distance(val2, Vector2.op_Implicit(((Component)val3).transform.position)); dictionary.Add(val3, value); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(11, 2); object value2; if (val3 == null) { value2 = null; } else { NetworkedPlayerInfo data = val3.Data; value2 = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value2); defaultInterpolatedStringHandler.AppendLiteral(" distance: "); defaultInterpolatedStringHandler.AppendFormatted(value); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Warlock", escapeCRLF: true, 113, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Warlock.cs"); } } if (dictionary.Count >= 1) { PlayerControl key = dictionary.OrderBy((KeyValuePair c) => c.Value).FirstOrDefault().Key; if (val.RpcCheckAndMurder(key, check: true)) { val.RpcMurderPlayer(key); key.SetRealKiller(shapeshifter); shapeshifter.RpcGuardAndKill(shapeshifter); Logger.Info(key.GetNameWithRole() + " was killed", "Warlock", escapeCRLF: true, 124, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Impostor\\Warlock.cs"); shapeshifter.Notify(Translator.GetString("WarlockControlKill")); } } else { shapeshifter.Notify(Translator.GetString("WarlockNoTarget")); } IsCurseAndKill[shapeshifter.PlayerId] = false; } else if (!shapeshifting) { shapeshifter.Notify(Translator.GetString("WarlockTargetDead")); } CursedPlayers[shapeshifter.PlayerId] = null; } else if (!GameStates.IsMeeting) { shapeshifter.Notify(Translator.GetString("WarlockNoTargetYet")); } } public override void OnFixedUpdate(PlayerControl player) { if (!WarlockTimer.TryGetValue(player.PlayerId, out var value)) { return; } byte playerId = player.PlayerId; if (player.IsAlive()) { if (value >= 1f) { player.SyncSettings(); player.RpcResetAbilityCooldown(); IsCursed = false; WarlockTimer.Remove(playerId); } else { value += Time.fixedDeltaTime; WarlockTimer[playerId] = value; } } else { WarlockTimer.Remove(playerId); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { foreach (byte playerId in playerIdList) { CursedPlayers[playerId] = null; IsCurseAndKill[playerId] = false; } IsCursed = false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { bool value; bool num = Main.CheckShapeshift.TryGetValue(playerId, out value) && value; bool value2; bool flag = IsCurseAndKill.TryGetValue(playerId, out value2) && value2; if (!num && !flag) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("WarlockCurseButtonText")); } AbilityButton abilityButton = hud.AbilityButton; if (abilityButton != null) { ((ActionButton)abilityButton).OverrideText(Translator.GetString("WarlockShapeshiftButtonText")); } } else { KillButton killButton2 = hud.KillButton; if (killButton2 != null) { ((ActionButton)killButton2).OverrideText(Translator.GetString("KillButtonText")); } } } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { if (shapeshifting) { return null; } return CustomButton.Get("Curse"); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { bool value = default(bool); if (!(!shapeshifting && IsCurseAndKill.TryGetValue(player.PlayerId, out value) && value)) { return null; } return CustomButton.Get("CurseKill"); } } internal class Wildling : RoleBase { private const int Id = 5200; private static OptionItem ProtectDuration; private static OptionItem ShapeshiftCD; private static OptionItem ShapeshiftDur; private long? TimeStamp; public static bool HasEnabled => CustomRoles.Wildling.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(5200, TabGroup.ImpostorRoles, CustomRoles.Wildling); ProtectDuration = FloatOptionItem.Create(5214, "BKProtectDuration", new FloatValueRule(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wildling]).SetValueFormat(OptionFormat.Seconds); ShapeshiftCD = FloatOptionItem.Create(5215, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new FloatValueRule(1f, 180f, 1f), 10f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wildling]).SetValueFormat(OptionFormat.Seconds); ShapeshiftDur = FloatOptionItem.Create(5216, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Wildling]).SetValueFormat(OptionFormat.Seconds); } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(TimeStamp.ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { reader.ReadByte(); string s = reader.ReadString(); TimeStamp = long.Parse(s); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCD.GetFloat(); AURoleOptions.ShapeshifterDuration = ShapeshiftDur.GetFloat(); } public override bool CanUseImpostorVentButton(PlayerControl pc) { return false; } private bool InProtect(byte playerId) { return TimeStamp > Utils.GetTimeStamp(DateTime.Now); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (InProtect(target.PlayerId)) { killer.RpcGuardAndKill(target); if (!Options.DisableShieldAnimations.GetBool()) { target.RpcGuardAndKill(); } target.Notify(Translator.GetString("BKOffsetKill")); return false; } return true; } public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { if (!(inMeeting || isSuicide)) { TimeStamp = Utils.GetTimeStamp(DateTime.Now) + (long)ProtectDuration.GetFloat(); SendRPC(killer.PlayerId); killer.Notify(Translator.GetString("BKInProtect")); } } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if (TimeStamp.HasValue && TimeStamp < Utils.GetTimeStamp(DateTime.Now)) { TimeStamp = 0L; pc.Notify(Translator.GetString("BKProtectOut")); } } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)seer == (Object)null || isForMeeting || !isForHud || !seer.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (InProtect(seer.PlayerId)) { long? num = TimeStamp - Utils.GetTimeStamp(DateTime.Now); stringBuilder.Append(string.Format(Translator.GetString("BKSkillTimeRemain"), num)); } else { stringBuilder.Append(Translator.GetString("BKSkillNotice")); } return stringBuilder.ToString(); } } internal class Witch : RoleBase { private enum SwitchTriggerList { TriggerKill, TriggerVent, TriggerDouble } private const int Id = 2500; private static readonly HashSet playerIdList = new HashSet(); public static OptionItem ModeSwitchActionOpt; private static readonly Dictionary SpellMode = new Dictionary(); private static readonly Dictionary> SpelledPlayer = new Dictionary>(); private static SwitchTriggerList NowSwitchTrigger; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(2500, TabGroup.ImpostorRoles, CustomRoles.Witch); ModeSwitchActionOpt = StringOptionItem.Create(2510, GeneralOption.ModeSwitchAction, EnumHelper.GetAllNames(), 2, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Witch]); } public override void Init() { playerIdList.Clear(); SpellMode.Clear(); SpelledPlayer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); SpellMode.Add(playerId, value: false); SpelledPlayer.Add(playerId, new HashSet()); NowSwitchTrigger = (SwitchTriggerList)ModeSwitchActionOpt.GetValue(); Utils.GetPlayerById(playerId).AddDoubleTrigger(); } private static void SendRPC(bool doSpell, byte witchId, byte target = byte.MaxValue) { if (doSpell) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)139, (SendOption)1, -1); val.Write(witchId); val.Write(target); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else { MessageWriter val2 = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)130, (SendOption)1, -1); val2.Write(witchId); val2.Write(SpellMode[witchId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val2); } } public static void ReceiveRPC(MessageReader reader, bool doSpell) { if (doSpell) { byte key = reader.ReadByte(); byte b = reader.ReadByte(); if (b != byte.MaxValue) { SpelledPlayer[key].Add(b); } else { SpelledPlayer[key].Clear(); } } else { byte key2 = reader.ReadByte(); SpellMode[key2] = reader.ReadBoolean(); } } private static void SwitchSpellMode(byte playerId, bool kill) { bool flag = false; switch (NowSwitchTrigger) { case SwitchTriggerList.TriggerKill: flag = kill; break; case SwitchTriggerList.TriggerVent: flag = !kill; break; } if (flag) { SpellMode[playerId] = !SpellMode[playerId]; SendRPC(doSpell: false, playerId); Utils.NotifyRoles(Utils.GetPlayerById(playerId)); } } private static bool IsSpellMode(byte playerId) { bool value; return SpellMode.TryGetValue(playerId, out value) && value; } private static bool IsSpelled(byte target) { return SpelledPlayer.Any((KeyValuePair> x) => x.Value.Contains(target)); } private static void SetSpelled(PlayerControl killer, PlayerControl target) { if (!IsSpelled(target.PlayerId)) { SpelledPlayer[killer.PlayerId].Add(target.PlayerId); SendRPC(doSpell: true, killer.PlayerId, target.PlayerId); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Curse"); Utils.NotifyRoles(killer, target); } } private static void RemoveSpelledPlayer() { foreach (byte playerId in playerIdList) { SpelledPlayer[playerId].Clear(); SendRPC(doSpell: true, playerId); } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (NowSwitchTrigger == SwitchTriggerList.TriggerDouble) { return killer.CheckDoubleTrigger(target, delegate { SetSpelled(killer, target); }); } if (!IsSpellMode(killer.PlayerId)) { SwitchSpellMode(killer.PlayerId, kill: true); return true; } SetSpelled(killer, target); SwitchSpellMode(killer.PlayerId, kill: true); return false; } public static void OnCheckForEndVoting(PlayerState.DeathReason deathReason, params byte[] exileIds) { if (!HasEnabled || deathReason != PlayerState.DeathReason.Vote) { return; } byte[] array = exileIds; foreach (byte key in array) { if (SpelledPlayer.ContainsKey(key)) { SpelledPlayer[key].Clear(); } } List list = new List(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl pc in allAlivePlayerControls) { IEnumerable>> source = SpelledPlayer.Where((KeyValuePair> x) => x.Value.Contains(pc.PlayerId)); if (!source.Any()) { continue; } PlayerControl playerById = Utils.GetPlayerById(source.FirstOrDefault().Key); if ((Object)(object)playerById != (Object)null && playerById.IsAlive()) { if (!Main.AfterMeetingDeathPlayers.ContainsKey(pc.PlayerId)) { pc.SetRealKiller(playerById); list.Add(pc.PlayerId); } } else { Main.AfterMeetingDeathPlayers.Remove(pc.PlayerId); } } int i = 0; array = new byte[list.Count]; foreach (byte item in list) { array[i] = item; i++; } CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Spell, array); RemoveSpelledPlayer(); } public override void OnPlayerExiled(PlayerControl player, NetworkedPlayerInfo exiled) { RemoveSpelledPlayer(); } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (NowSwitchTrigger == SwitchTriggerList.TriggerVent) { SwitchSpellMode(pc.PlayerId, kill: false); } } public override string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (isForMeeting && IsSpelled(seen.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Palette.ImpostorRed), "†"); } return string.Empty; } public override string GetLowerText(PlayerControl witch, PlayerControl seen, bool isForMeeting = false, bool isForHud = false) { if (!witch.IsAlive() || isForMeeting || (Object)(object)witch != (Object)(object)seen) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (isForHud) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(Translator.GetString("WitchCurrentMode")); handler.AppendLiteral(": "); stringBuilder3.Append(ref handler); } else { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendFormatted(Translator.GetString("Mode")); handler.AppendLiteral(": "); stringBuilder4.Append(ref handler); } if (NowSwitchTrigger == SwitchTriggerList.TriggerDouble) { stringBuilder.Append(Translator.GetString("WitchModeDouble")); } else { stringBuilder.Append(IsSpellMode(witch.PlayerId) ? Translator.GetString("WitchModeSpell") : Translator.GetString("WitchModeKill")); } return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { if (IsSpellMode(playerId) && NowSwitchTrigger != SwitchTriggerList.TriggerDouble) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("WitchSpellButtonText")); } else { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("KillButtonText")); } } } internal class Zombie : RoleBase { private const int Id = 23900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ZombieKillCooldown; private static OptionItem ZombieSpeedReduce; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(23900, TabGroup.ImpostorRoles, CustomRoles.Zombie); ZombieKillCooldown = FloatOptionItem.Create(23903, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Zombie]).SetValueFormat(OptionFormat.Seconds); ZombieSpeedReduce = FloatOptionItem.Create(23904, "ZombieSpeedReduce", new FloatValueRule(0f, 1f, 0.1f), 0.1f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Zombie]).SetValueFormat(OptionFormat.Multiplier); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetFloat((FloatOptionNames)3, 0.2f); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ZombieKillCooldown.GetFloat(); Main.AllPlayerSpeed[id] -= (float)Math.Clamp(ZombieSpeedReduce.GetFloat(), 0.0, (double)Main.AllPlayerSpeed[id] - 0.5); } public static void CheckRealVotes(PlayerControl target, ref int VoteNum) { if (target.Is(CustomRoles.Zombie)) { VoteNum = 0; } } } } namespace TOHE.Roles.Double { internal class Mini : RoleBase { private const int Id = 7000; private static OptionItem GrowUpDuration; private static OptionItem EveryoneCanKnowMini; private static OptionItem CountMeetingTime; private static OptionItem EvilMiniSpawnChances; private static OptionItem CanBeEvil; private static OptionItem UpDateAge; private static OptionItem MinorCD; private static OptionItem MajorCD; public static int Age; public static bool IsEvilMini; private static int GrowUpTime; private static long LastFixedUpdate; private static bool misguessed; public static bool HasEnabled { get { if (!CustomRoles.EvilMini.HasEnabled()) { return CustomRoles.NiceMini.HasEnabled(); } return true; } } public override CustomRoles ThisRoleBase { get { if (!IsEvilMini) { return CustomRoles.Crewmate; } return CustomRoles.Impostor; } } public override Custom_RoleType ThisRoleType { get { if (!IsEvilMini) { return Custom_RoleType.CrewmateBasic; } return Custom_RoleType.ImpostorKilling; } } public override void SetupCustomOption() { Options.SetupSingleRoleOptions(7000, TabGroup.CrewmateRoles, CustomRoles.Mini); GrowUpDuration = IntegerOptionItem.Create(7100, "GrowUpDuration", new IntegerValueRule(200, 800, 25), 400, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]).SetValueFormat(OptionFormat.Seconds); EveryoneCanKnowMini = BooleanOptionItem.Create(7102, "EveryoneCanKnowMini", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]); CanBeEvil = BooleanOptionItem.Create(7106, "CanBeEvil", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]); EvilMiniSpawnChances = IntegerOptionItem.Create(7108, "EvilMiniSpawnChances", new IntegerValueRule(0, 100, 5), 50, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(CanBeEvil).SetValueFormat(OptionFormat.Percent); MinorCD = FloatOptionItem.Create(7110, GeneralOption.KillCooldown, new FloatValueRule(0f, 180f, 2.5f), 45f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(CanBeEvil).SetValueFormat(OptionFormat.Seconds); MajorCD = FloatOptionItem.Create(7112, "MajorCooldown", new FloatValueRule(0f, 180f, 2.5f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(CanBeEvil).SetValueFormat(OptionFormat.Seconds); UpDateAge = BooleanOptionItem.Create(7114, "UpDateAge", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]); CountMeetingTime = BooleanOptionItem.Create(7116, "CountMeetingTime", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]); } public override void Init() { GrowUpTime = 0; Age = 0; misguessed = false; IsEvilMini = false; if (((InnerNetClient)AmongUsClient.Instance).AmHost && CustomRoles.Mini.IsEnable()) { IRandom instance = IRandom.Instance; IsEvilMini = CanBeEvil.GetBool() && instance.Next(0, 100) < EvilMiniSpawnChances.GetInt(); } } public override void Add(byte playerId) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { SendRPC(); } } public void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(Age); val.Write(IsEvilMini); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { Age = reader.ReadInt32(); IsEvilMini = reader.ReadBoolean(); } public static bool CheckSpawnEvilMini() { return IsEvilMini; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Mini)), Translator.GetString("Cantkillkid"))); return false; } return true; } public void OnFixedUpdates(PlayerControl player) { if (!GameStates.IsInGame || Age >= 18) { return; } if (!player.IsAlive() && player.Is(CustomRoles.NiceMini) && CustomWinnerHolder.WinnerTeam == CustomWinner.Default && !CustomWinnerHolder.CheckForConvertedWinner(player.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.NiceMini); CustomWinnerHolder.WinnerIds.Add(player.PlayerId); } if ((GameStates.IsMeeting && !CountMeetingTime.GetBool()) || LastFixedUpdate == Utils.GetTimeStamp()) { return; } LastFixedUpdate = Utils.GetTimeStamp(); GrowUpTime++; if (GrowUpTime >= GrowUpDuration.GetInt() / 18) { Age++; GrowUpTime = 0; Logger.Info("Mini grow up by 1", "Mini", escapeCRLF: true, 122, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Double\\Mini.cs"); if (player.Is(CustomRoles.EvilMini)) { player.ResetKillCooldown(); player.SyncSettings(); } if (player.Is(CustomRoles.NiceMini)) { player.RpcGuardAndKill(); } if (UpDateAge.GetBool()) { SendRPC(); player.Notify(Translator.GetString("MiniUp")); Utils.NotifyRoles(); } } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = GetKillCoolDown(); } private static float GetKillCoolDown() { if (MinorCD.GetFloat() <= MajorCD.GetFloat()) { return MinorCD.GetFloat(); } if (Age == 0) { return MinorCD.GetFloat(); } if (Age == 18) { return MajorCD.GetFloat(); } return MinorCD.GetFloat() + (MajorCD.GetFloat() - MinorCD.GetFloat()) / 18f * (float)Age; } public override string GetProgressText(byte playerId, bool comms) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Mini)), (Age != 18) ? $"({Age})" : ""); } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (guesser.Is(CustomRoles.NiceMini) && Age < 18 && misguessed) { guesser.ShowInfoMessage(isUI, Translator.GetString("MiniGuessMax")); return true; } return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (target.Is(CustomRoles.NiceMini) && Age < 18) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessMini")); return true; } return false; } public override bool CheckMisGuessed(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (Age < 18 && guesser.PlayerId == target.PlayerId) { misguessed = true; new LateTask(delegate { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(Translator.GetString("MiniMisGuessed"), target.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceMini)), Translator.GetString("GuessKillTitle")), logforChatManager: true); }, 0.6f, "Mini MisGuess Msg"); return true; } return false; } public override void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { PlayerControl playerById = Utils.GetPlayerById(exiled.PlayerId); if ((Object)(object)playerById != (Object)null && playerById.Is(CustomRoles.NiceMini) && Age < 18 && !CustomWinnerHolder.CheckForConvertedWinner(exiled.PlayerId)) { if (isMeetingHud) { name = string.Format(Translator.GetString("ExiledNiceMini"), Main.LastVotedPlayer, Utils.GetDisplayRoleAndSubName(exiled.PlayerId, exiled.PlayerId, notShowAddOns: true)); } else { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.NiceMini); CustomWinnerHolder.WinnerIds.Add(exiled.PlayerId); } DecidedWinner = true; } } public override string GetMarkOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!EveryoneCanKnowMini.GetBool() || (!target.Is(CustomRoles.NiceMini) && !target.Is(CustomRoles.EvilMini))) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Mini)), (Age != 18 && UpDateAge.GetBool()) ? $"({Age})" : string.Empty); } } } namespace TOHE.Roles.Crewmate { internal class Addict : RoleBase { private const int Id = 6300; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VentCooldown; private static OptionItem TimeLimit; private static OptionItem ImmortalTimeAfterVent; private static OptionItem FreezeTimeAfterImmortal; private static readonly Dictionary SuicideTimer = new Dictionary(); private static readonly Dictionary ImmortalTimer = new Dictionary(); private static float DefaultSpeed = 0f; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(6300, TabGroup.CrewmateRoles, CustomRoles.Addict); VentCooldown = FloatOptionItem.Create(6311, GeneralOption.EngineerBase_VentCooldown, new FloatValueRule(5f, 180f, 1f), 40f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Addict]).SetValueFormat(OptionFormat.Seconds); TimeLimit = FloatOptionItem.Create(6312, "AddictSuicideTimer", new FloatValueRule(5f, 180f, 1f), 45f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Addict]).SetValueFormat(OptionFormat.Seconds); ImmortalTimeAfterVent = FloatOptionItem.Create(6313, "AddictInvulnerbilityTimeAfterVent", new FloatValueRule(0f, 60f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Addict]).SetValueFormat(OptionFormat.Seconds); FreezeTimeAfterImmortal = FloatOptionItem.Create(6315, "AddictFreezeTimeAfterInvulnerbility", new FloatValueRule(0f, 60f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Addict]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); SuicideTimer.Clear(); ImmortalTimer.Clear(); DefaultSpeed = 0f; } public override void Add(byte playerId) { playerIdList.Add(playerId); SuicideTimer.TryAdd(playerId, -10f); ImmortalTimer.TryAdd(playerId, 420f); DefaultSpeed = Main.AllPlayerSpeed[playerId]; } public override void Remove(byte playerId) { playerIdList.Remove(playerId); SuicideTimer.Remove(playerId); ImmortalTimer.Remove(playerId); DefaultSpeed = Main.AllPlayerSpeed[playerId]; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } private static bool IsImmortal(PlayerControl player) { return ImmortalTimer[player.PlayerId] <= ImmortalTimeAfterVent.GetFloat(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { return !IsImmortal(target); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { byte[] array = playerIdList.ToArray(); foreach (byte key in array) { SuicideTimer[key] = -10f; ImmortalTimer[key] = 420f; Main.AllPlayerSpeed[key] = DefaultSpeed; } } public override void OnFixedUpdate(PlayerControl player) { if (!SuicideTimer.ContainsKey(player.PlayerId) || !player.IsAlive()) { return; } if (SuicideTimer[player.PlayerId] >= TimeLimit.GetFloat()) { player.SetDeathReason(PlayerState.DeathReason.Suicide); player.RpcMurderPlayer(player); SuicideTimer.Remove(player.PlayerId); return; } SuicideTimer[player.PlayerId] += Time.fixedDeltaTime; if (IsImmortal(player)) { ImmortalTimer[player.PlayerId] += Time.fixedDeltaTime; } else if (ImmortalTimer[player.PlayerId] != 420f && FreezeTimeAfterImmortal.GetFloat() > 0f) { AddictGetDown(player); ImmortalTimer[player.PlayerId] = 420f; } } public override void OnEnterVent(PlayerControl pc, Vent vent) { SuicideTimer[pc.PlayerId] = 0f; ImmortalTimer[pc.PlayerId] = 0f; pc.MarkDirtySettings(); } private static void AddictGetDown(PlayerControl addict) { Main.AllPlayerSpeed[addict.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[addict.PlayerId] = false; addict.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[addict.PlayerId] = DefaultSpeed; ReportDeadBodyPatch.CanReport[addict.PlayerId] = true; addict.MarkDirtySettings(); }, FreezeTimeAfterImmortal.GetFloat(), "AddictGetDown"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("AddictVentButtonText")); } } internal class Admirer : RoleBase { private const int Id = 24800; private static OptionItem AdmireCooldown; private static OptionItem KnowTargetRole; private static OptionItem SkillLimit; public static readonly Dictionary> AdmiredList = new Dictionary>(); public static bool HasEnabled => CustomRoles.Admired.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(24800, TabGroup.CrewmateRoles, CustomRoles.Admirer); AdmireCooldown = FloatOptionItem.Create(24810, "AdmireCooldown", new FloatValueRule(1f, 180f, 1f), 5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Admirer]).SetValueFormat(OptionFormat.Seconds); KnowTargetRole = BooleanOptionItem.Create(24811, "AdmirerKnowTargetRole", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Admirer]); SkillLimit = IntegerOptionItem.Create(24812, "AdmirerSkillLimit", new IntegerValueRule(0, 100, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Admirer]).SetValueFormat(OptionFormat.Times); } public override void Init() { AdmiredList.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = SkillLimit.GetInt(); AdmiredList.Add(playerId, new List()); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { AdmiredList.Remove(playerId); } private void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)192, (SendOption)1, -1); val.Write(playerId); val.Write(base.AbilityLimit); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void SendRPC(byte playerId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)191, (SendOption)1, -1); val.Write(playerId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader, bool isList) { byte key = reader.ReadByte(); if (!isList) { float abilityLimit = reader.ReadSingle(); Main.PlayerStates[key].RoleClass.AbilityLimit = abilityLimit; return; } byte item = reader.ReadByte(); if (!AdmiredList.ContainsKey(key)) { AdmiredList.Add(key, new List()); } else { AdmiredList[key].Add(item); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ((base.AbilityLimit >= 1f) ? AdmireCooldown.GetFloat() : 300f); } public override bool CanUseKillButton(PlayerControl player) { return base.AbilityLimit >= 1f; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0723: Unknown result type (might be due to invalid IL or missing references) //IL_0728: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_0570: Unknown result type (might be due to invalid IL or missing references) //IL_0599: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) if (base.AbilityLimit < 1f) { return false; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if (!AdmiredList.ContainsKey(killer.PlayerId)) { AdmiredList.Add(killer.PlayerId, new List()); } if (base.AbilityLimit < 1f) { return false; } if (CanBeAdmired(target, killer)) { if (KnowTargetRole.GetBool()) { AdmiredList[killer.PlayerId].Add(target.PlayerId); SendRPC(killer.PlayerId, target.PlayerId); } if (!killer.Is(CustomRoles.Madmate) && !killer.Is(CustomRoles.Recruit) && !killer.Is(CustomRoles.Charmed) && !killer.Is(CustomRoles.Infected) && !killer.Is(CustomRoles.Contagious)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Admired, "Admirer Assign", escapeCRLF: true, 114, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Admired); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Admirer)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Admirer)), Translator.GetString("AdmirerAdmired"))); } else if (killer.Is(CustomRoles.Madmate) && target.CanBeMadmate(forAdmirer: true)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Madmate, "Admirer Assign", escapeCRLF: true, 121, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Madmate); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("AdmirerAdmired"))); } else if (killer.Is(CustomRoles.Recruit) && Jackal.CanBeSidekick(target)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Recruit, "Admirer Assign", escapeCRLF: true, 128, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Recruit); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Recruit)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Recruit)), Translator.GetString("AdmirerAdmired"))); } else if (killer.Is(CustomRoles.Charmed) && Cultist.CanBeCharmed(target)) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Charmed, "Admirer Assign", escapeCRLF: true, 135, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Charmed); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Charmed)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Charmed)), Translator.GetString("AdmirerAdmired"))); } else if (killer.Is(CustomRoles.Infected) && target.CanBeInfected()) { Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Infected, "Admirer Assign", escapeCRLF: true, 142, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Infected); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infected)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Infected)), Translator.GetString("AdmirerAdmired"))); } else { if (!killer.Is(CustomRoles.Contagious) || !target.CanBeInfected()) { goto IL_0714; } Logger.Info("Set converted: " + target.GetNameWithRole().RemoveHtmlTags() + " to " + CustomRoles.Contagious, "Admirer Assign", escapeCRLF: true, 149, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); target.RpcSetCustomRole(CustomRoles.Contagious); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Contagious)), Translator.GetString("AdmiredPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Contagious)), Translator.GetString("AdmirerAdmired"))); } base.AbilityLimit--; SendRPC(killer.PlayerId); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); target.ResetKillCooldown(); target.SetKillCooldown(-1f, null, forceAnime: true); string[] obj = new string[6] { "设置职业:", null, null, null, null, null }; object obj2; if (target == null) { obj2 = null; } else { NetworkedPlayerInfo data = target.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = target.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Admirer.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Admirer, escapeCRLF: true, 168, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次仰慕机会", "Admirer", escapeCRLF: true, 169, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); return false; } goto IL_0714; IL_0714: SendRPC(killer.PlayerId); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Admirer)), Translator.GetString("AdmirerInvalidTarget"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次仰慕机会", "Admirer", escapeCRLF: true, 179, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Admirer.cs"); return false; } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return CheckKnowRoleTarget(seer, target); } public static bool CheckKnowRoleTarget(PlayerControl seer, PlayerControl target) { if (!KnowTargetRole.GetBool()) { return false; } if (AdmiredList.ContainsKey(seer.PlayerId)) { if (AdmiredList[seer.PlayerId].Contains(target.PlayerId)) { return true; } return false; } if (AdmiredList.ContainsKey(target.PlayerId)) { if (AdmiredList[target.PlayerId].Contains(seer.PlayerId)) { return true; } return false; } return false; } public override string GetProgressText(byte playerId, bool comms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Admirer).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public static bool CanBeAdmired(PlayerControl pc, PlayerControl admirer) { if (AdmiredList.ContainsKey(admirer.PlayerId)) { if (AdmiredList[admirer.PlayerId].Contains(pc.PlayerId)) { return false; } } else { AdmiredList.Add(admirer.PlayerId, new List()); } if ((Object)(object)pc != (Object)null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || pc.GetCustomRole().IsNeutral()) && !pc.Is(CustomRoles.Soulless) && !pc.Is(CustomRoles.Lovers) && !pc.Is(CustomRoles.Loyal) && ((!pc.Is(CustomRoles.NiceMini) && !pc.Is(CustomRoles.EvilMini)) || Mini.Age >= 18)) { if (pc.GetCustomSubRoles().Contains(CustomRoles.Hurried)) { return Hurried.CanBeConverted.GetBool(); } return true; } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("AdmireButtonText")); } } } internal class Alchemist : RoleBase { private const int Id = 6400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VentCooldown; private static OptionItem ShieldDuration; private static OptionItem Vision; private static OptionItem VisionOnLightsOut; private static OptionItem VisionDuration; private static OptionItem Speed; private static OptionItem InvisDuration; private static readonly Dictionary InvisTime = new Dictionary(); private static readonly Dictionary ventedId = new Dictionary(); public static readonly Dictionary BloodthirstList = new Dictionary(); private static byte PotionID = 10; private static string PlayerName = string.Empty; private static bool VisionPotionActive = false; private static bool FixNextSabo = false; private static bool IsProtected = false; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(6400, TabGroup.CrewmateRoles, CustomRoles.Alchemist); VentCooldown = FloatOptionItem.Create(6411, GeneralOption.EngineerBase_VentCooldown, new FloatValueRule(0f, 70f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Seconds); ShieldDuration = FloatOptionItem.Create(6412, "AlchemistShieldDur", new FloatValueRule(5f, 70f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Seconds); Vision = FloatOptionItem.Create(6416, "AlchemistVision", new FloatValueRule(0f, 1f, 0.05f), 0.85f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Multiplier); VisionOnLightsOut = FloatOptionItem.Create(6417, "AlchemistVisionOnLightsOut", new FloatValueRule(0f, 1f, 0.05f), 0.4f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Multiplier); VisionDuration = FloatOptionItem.Create(6418, "AlchemistVisionDur", new FloatValueRule(5f, 70f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Seconds); Speed = FloatOptionItem.Create(6419, "AlchemistSpeed", new FloatValueRule(0.1f, 5f, 0.1f), 1.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Multiplier); InvisDuration = FloatOptionItem.Create(6420, "AlchemistInvisDur", new FloatValueRule(5f, 70f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Alchemist]).SetValueFormat(OptionFormat.Seconds); Options.OverrideTasksData.Create(6421, TabGroup.CrewmateRoles, CustomRoles.Alchemist); } public override void Init() { playerIdList.Clear(); BloodthirstList.Clear(); PotionID = 10; PlayerName = string.Empty; ventedId.Clear(); InvisTime.Clear(); FixNextSabo = false; VisionPotionActive = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); PlayerName = Utils.GetPlayerById(playerId).GetRealName(); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { AddBloodlus(); } } public static void AddBloodlus() { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdatesBloodlus); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; if (VisionPotionActive) { opt.SetVisionV2(); if (Utils.IsActive((SystemTypes)7)) { opt.SetFloat((FloatOptionNames)4, VisionOnLightsOut.GetFloat() * 5f); } else { opt.SetFloat((FloatOptionNames)4, Vision.GetFloat()); } } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (!player.IsAlive()) { return true; } PotionID = (byte)IRandom.Instance.Next(1, 9); switch (PotionID) { case 1: player.Notify(Translator.GetString("AlchemistGotShieldPotion"), 15f); break; case 2: player.Notify(Translator.GetString("AlchemistGotSuicidePotion"), 15f); break; case 3: player.Notify(Translator.GetString("AlchemistGotTPPotion"), 15f); break; case 4: player.Notify(Translator.GetString("AlchemistGotSpeedPotion"), 15f); break; case 5: FixNextSabo = true; PotionID = 10; player.Notify(Translator.GetString("AlchemistGotQFPotion"), 15f); break; case 6: player.Notify(Translator.GetString("AlchemistGotBloodthirstPotion"), 15f); break; case 7: player.Notify(Translator.GetString("AlchemistGotSightPotion"), 15f); break; case 8: player.Notify(Translator.GetString("AlchemistGotInvisibility"), 15f); break; } SendRPC(player); return true; } private static void SendRPC(PlayerControl pc) { if (!((InnerNetObject)pc).AmOwner) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)159, (SendOption)1, pc.GetClientId()); val.Write(FixNextSabo); val.Write(PotionID); val.Write((InvisTime.TryGetValue(pc.PlayerId, out var value) ? value : (-1)).ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader) { FixNextSabo = reader.ReadBoolean(); PotionID = reader.ReadByte(); InvisTime.Clear(); long num = long.Parse(reader.ReadString()); if (num > 0) { InvisTime.Add(PlayerControl.LocalPlayer.PlayerId, num); } } private static bool IsInvis(byte playerId) { return InvisTime.ContainsKey(playerId); } private static bool IsBloodthirst(byte playerId) { return BloodthirstList.ContainsKey(playerId); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (!IsProtected) { return true; } killer.SetKillCooldown(5f); return false; } private static void OnFixedUpdatesBloodlus(PlayerControl player) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!IsBloodthirst(player.PlayerId)) { return; } if (!player.IsAlive() || Pelican.IsEaten(player.PlayerId)) { BloodthirstList.Remove(player.PlayerId); return; } Vector2 val = Vector2.op_Implicit(((Component)player).transform.position); Dictionary dictionary = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (val2.PlayerId != player.PlayerId && !val2.Is(CustomRoles.Pestilence)) { float value = Vector2.Distance(val, Vector2.op_Implicit(((Component)val2).transform.position)); dictionary.Add(val2.PlayerId, value); } } if (dictionary.Any()) { KeyValuePair keyValuePair = dictionary.OrderBy((KeyValuePair c) => c.Value).FirstOrDefault(); PlayerControl playerById = Utils.GetPlayerById(keyValuePair.Key); float num = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(Main.NormalOptions.KillDistance, 0, 2)]; if (keyValuePair.Value <= num && player.CanMove && playerById.CanMove && player.RpcCheckAndMurder(playerById, check: true)) { byte b = BloodthirstList[player.PlayerId]; RPC.PlaySoundRPC(b, Sounds.KillSound); player.RpcMurderPlayer(playerById); playerById.SetRealKiller(Utils.GetPlayerById(b)); player.MarkDirtySettings(); playerById.MarkDirtySettings(); BloodthirstList.Remove(player.PlayerId); Utils.NotifyRoles(Utils.GetPlayerById(b), player); } } } public override void OnFixedUpdateLowLoad(PlayerControl player) { if (!IsInvis(player.PlayerId)) { return; } long timeStamp = Utils.GetTimeStamp(); bool flag = false; foreach (KeyValuePair item in InvisTime) { byte key = item.Key; PlayerControl playerById = Utils.GetPlayerById(key); if ((Object)(object)playerById == (Object)null) { continue; } long num = item.Value + (long)InvisDuration.GetFloat() - timeStamp; if (num < 0 || !playerById.IsAlive()) { if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(key, out var value) ? value : Main.LastEnteredVent[key].Id); } } ventedId.Remove(key); playerById.Notify(Translator.GetString("SwooperInvisStateOut")); flag = true; InvisTime.Remove(key); } else if (num <= 10 && !playerById.IsModClient()) { playerById.Notify(string.Format(Translator.GetString("SwooperInvisStateCountdown"), num), 4f, sendInLog: false); } } if (flag) { SendRPC(player); } } public static void OnReportDeadBodyGlobal() { foreach (byte playerId in playerIdList) { if (!IsInvis(playerId)) { continue; } PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null) { continue; } if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(playerId, out var value) ? value : Main.LastEnteredVent[playerId].Id); } } InvisTime.Remove(playerId); ventedId.Remove(playerId); SendRPC(playerById); } BloodthirstList.Clear(); InvisTime.Clear(); ventedId.Clear(); } public override void OnEnterVent(PlayerControl player, Vent vent) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } NameNotifyManager.Notice.Remove(player.PlayerId); switch (PotionID) { case 1: IsProtected = true; player.Notify(Translator.GetString("AlchemistShielded"), ShieldDuration.GetInt()); new LateTask(delegate { IsProtected = false; player.Notify(Translator.GetString("AlchemistShieldOut")); }, ShieldDuration.GetInt(), "Alchemist Shield Is Out"); break; case 2: player.MyPhysics.RpcBootFromVent(vent.Id); new LateTask(delegate { player.SetDeathReason(PlayerState.DeathReason.Poison); player.SetRealKiller(player); player.RpcMurderPlayer(player); }, 1f, "Alchemist Is Poisoned"); break; case 3: new LateTask(delegate { //IL_0066: Unknown result type (might be due to invalid IL or missing references) PlayerControl[] array = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.CanBeTeleported() && x.PlayerId != player.PlayerId).ToArray(); List list = new List(array.Length); PlayerControl[] array2 = array; foreach (PlayerControl item in array2) { list.Add(item); } PlayerControl player2 = list.RandomElement(); player.RpcTeleport(player2.GetCustomPosition()); player.RPCPlayCustomSound("Teleport"); }, 2f, "Alchemist teleported to random player"); break; case 4: { int num = 10; player.Notify(Translator.GetString("AlchemistHasSpeed")); float tempSpeed = Main.AllPlayerSpeed[player.PlayerId]; Main.AllPlayerSpeed[player.PlayerId] = Speed.GetFloat(); player.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[player.PlayerId] = Main.AllPlayerSpeed[player.PlayerId] - Speed.GetFloat() + tempSpeed; player.Notify(Translator.GetString("AlchemistSpeedOut")); player.MarkDirtySettings(); }, num, "Alchemist: Set Speed to default"); break; } case 6: player.Notify(Translator.GetString("AlchemistPotionBloodthirst")); if (!IsBloodthirst(player.PlayerId)) { BloodthirstList.TryAdd(player.PlayerId, player.PlayerId); } break; case 7: VisionPotionActive = true; player.MarkDirtySettings(); player.Notify(Translator.GetString("AlchemistHasVision"), VisionDuration.GetFloat()); new LateTask(delegate { VisionPotionActive = false; player.MarkDirtySettings(); player.Notify(Translator.GetString("AlchemistVisionOut")); }, VisionDuration.GetFloat(), "Alchemist Vision Is Out"); break; default: player.Notify("NoPotion"); break; case 5: case 8: break; } PotionID = 10; SendRPC(player); } public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && PotionID == 8) { PotionID = 10; PlayerControl pc = __instance.myPlayer; NameNotifyManager.Notice.Remove(pc.PlayerId); new LateTask(delegate { ventedId.Remove(pc.PlayerId); ventedId.Add(pc.PlayerId, ventId); __instance.RpcBootFromVentDesync(ventId, pc); InvisTime.Add(pc.PlayerId, Utils.GetTimeStamp()); SendRPC(pc); pc.Notify(Translator.GetString("ChameleonInvisState"), InvisDuration.GetFloat()); }, 0.8f, "Alchemist Invis"); } } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)seer == (Object)null || !seer.IsAlive() || isForMeeting || !isForHud) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (IsInvis(seer.PlayerId)) { long num = InvisTime[seer.PlayerId] + (long)InvisDuration.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("ChameleonInvisStateCountdown"), num + 1)); } else { switch (PotionID) { case 1: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreShield")); break; case 2: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreSuicide")); break; case 3: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreTP")); break; case 4: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreSP")); break; case 5: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreQF")); break; case 6: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreBL")); break; case 7: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreNS")); break; case 8: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreINV")); break; case 10: stringBuilder.Append(Translator.GetString("PotionStore") + Translator.GetString("StoreNull")); break; } if (FixNextSabo) { stringBuilder.Append(Translator.GetString("WaitQFPotion")); } } return stringBuilder.ToString(); } public override string GetProgressText(byte playerId, bool comms) { if ((Object)(object)Utils.GetPlayerById(playerId) == (Object)null || !GameStates.IsInTask) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); switch (PotionID) { case 1: stringBuilder.Append("✚"); break; case 2: stringBuilder.Append("⁂"); break; case 3: stringBuilder.Append("§"); break; case 4: stringBuilder.Append("»"); break; case 5: stringBuilder.Append("★"); break; case 6: stringBuilder.Append("乂"); break; case 7: stringBuilder.Append("◉"); break; case 8: stringBuilder.Append("◌"); break; } if (FixNextSabo) { stringBuilder.Append("★"); } return stringBuilder.ToString(); } public override void UpdateSystem(ShipStatus __instance, SystemTypes systemType, byte amount, PlayerControl player) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if (!FixNextSabo) { return; } FixNextSabo = false; if ((int)systemType <= 8) { if ((int)systemType != 3) { if ((int)systemType == 8 && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)8, (byte)67); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)8, (byte)66); } } else if ((uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)3, (byte)16); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)3, (byte)17); } } else if ((int)systemType != 14) { if ((int)systemType == 21 && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)21, (byte)67); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)21, (byte)66); } } else if ((uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)14, (byte)16); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)14, (byte)17); } } public override void SwitchSystemUpdate(SwitchSystem __instance, byte amount, PlayerControl player) { __instance.ActualSwitches = 0; __instance.ExpectedSwitches = 0; Logger.Info(player.GetNameWithRole().RemoveHtmlTags() + " instant - fix-lights", "SwitchSystem", escapeCRLF: true, 515, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Alchemist.cs"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("AlchemistVentButtonText")); } } internal class Bastion : RoleBase { private const int Id = 10200; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem BombsClearAfterMeeting; private static OptionItem BastionBombCooldown; private static OptionItem BastionAbilityUseGainWithEachTaskCompleted; private static OptionItem BastionMaxBombs; private static readonly HashSet BombedVents = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(10200, TabGroup.CrewmateRoles, CustomRoles.Bastion); BombsClearAfterMeeting = BooleanOptionItem.Create(10210, "BombsClearAfterMeeting", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bastion]); BastionBombCooldown = FloatOptionItem.Create(10211, "BombCooldown", new FloatValueRule(0f, 180f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bastion]).SetValueFormat(OptionFormat.Seconds); BastionAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(10204, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bastion]).SetValueFormat(OptionFormat.Times); BastionMaxBombs = IntegerOptionItem.Create(10212, "BastionMaxBombs", new IntegerValueRule(1, 20, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bastion]); } public override void Init() { playerIdList.Clear(); BombedVents.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); base.AbilityLimit = BastionMaxBombs.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerInVentMaxTime = 1f; AURoleOptions.EngineerCooldown = BastionBombCooldown.GetFloat(); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += BastionAbilityUseGainWithEachTaskCompleted.GetFloat(); } return true; } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override bool OnCoEnterVentOthers(PlayerPhysics physics, int ventId) { if (!BombedVents.Contains(ventId)) { return false; } PlayerControl pc = physics.myPlayer; if (pc.Is(Custom_Team.Crewmate) && !pc.Is(CustomRoles.Bastion) && !pc.IsCrewVenter() && !CopyCat.playerIdList.Contains(pc.PlayerId) && !Main.TasklessCrewmate.Contains(pc.PlayerId)) { Logger.Info("Crewmate enter in bombed vent, bombed is cancel", "Bastion.OnCoEnterVentOther", escapeCRLF: true, 85, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Bastion.cs"); return false; } new LateTask(delegate { PlayerControl player = base._Player; player.Notify(Translator.GetString("BastionNotify")); pc.Notify(Translator.GetString("EnteredBombedVent")); pc.SetDeathReason(PlayerState.DeathReason.Bombed); pc.RpcMurderPlayer(pc); pc.SetRealKiller(player); BombedVents.Remove(ventId); }, 0.5f, "Player bombed by Bastion"); return true; } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (base.AbilityLimit >= 1f) { base.AbilityLimit--; SendSkillRPC(); if (!BombedVents.Contains(vent.Id)) { BombedVents.Add(vent.Id); } pc.Notify(Translator.GetString("VentBombSuccess")); } else { pc.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks")); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (BombsClearAfterMeeting.GetBool()) { BombedVents.Clear(); } } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("BastionVentButtonText"); } } internal class Benefactor : RoleBase { private const int Id = 26400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem TaskMarkPerRoundOpt; private static OptionItem ShieldDuration; private static OptionItem ShieldIsOneTimeUse; private static int maxTasksMarkedPerRound = 0; private static readonly Dictionary> taskIndex = new Dictionary>(); private static readonly Dictionary TaskMarkPerRound = new Dictionary(); private static readonly Dictionary shieldedPlayers = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(26400, TabGroup.CrewmateRoles, CustomRoles.Benefactor); TaskMarkPerRoundOpt = IntegerOptionItem.Create(26410, "TasksMarkPerRound", new IntegerValueRule(1, 14, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Benefactor]).SetValueFormat(OptionFormat.Votes); ShieldDuration = FloatOptionItem.Create(26411, "ShieldDuration", new FloatValueRule(1f, 30f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Benefactor]).SetValueFormat(OptionFormat.Votes); ShieldIsOneTimeUse = BooleanOptionItem.Create(26412, "ShieldIsOneTimeUse", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Benefactor]); Options.OverrideTasksData.Create(26413, TabGroup.CrewmateRoles, CustomRoles.Benefactor); } public override void Init() { playerIdList.Clear(); taskIndex.Clear(); shieldedPlayers.Clear(); TaskMarkPerRound.Clear(); maxTasksMarkedPerRound = TaskMarkPerRoundOpt.GetInt(); } public override void Add(byte playerId) { playerIdList.Add(playerId); TaskMarkPerRound[playerId] = 0; } public override void Remove(byte playerId) { playerIdList.Remove(playerId); TaskMarkPerRound.Remove(playerId); } private static void SendRPC(int type, byte benefactorId = byte.MaxValue, byte targetId = byte.MaxValue, int taskIndex = -1) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)166, (SendOption)1, -1); val.Write(type); if (type == 0) { val.Write(benefactorId); } if (type == 2) { val.Write(benefactorId); val.Write(TaskMarkPerRound[benefactorId]); val.Write(taskIndex); } if (type == 3) { val.Write(benefactorId); val.Write(taskIndex); val.Write(targetId); val.Write(shieldedPlayers[targetId].ToString()); } if (type == 4) { val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { int num = reader.ReadInt32(); if (num == 0) { byte key = reader.ReadByte(); TaskMarkPerRound[key] = 0; if (taskIndex.ContainsKey(key)) { taskIndex[key].Clear(); } } if (num == 1) { shieldedPlayers.Clear(); } if (num == 2) { byte key2 = reader.ReadByte(); int value = reader.ReadInt32(); TaskMarkPerRound[key2] = value; int item = reader.ReadInt32(); if (!taskIndex.ContainsKey(key2)) { taskIndex[key2] = new HashSet(); } taskIndex[key2].Add(item); } if (num == 3) { byte key3 = reader.ReadByte(); int item2 = reader.ReadInt32(); if (!taskIndex.ContainsKey(key3)) { taskIndex[key3] = new HashSet(); } taskIndex[key3].Remove(item2); byte key4 = reader.ReadByte(); if (long.TryParse(reader.ReadString(), out var result)) { shieldedPlayers[key4] = result; } } if (num == 4) { byte key5 = reader.ReadByte(); shieldedPlayers.Remove(key5); } } public override string GetProgressText(byte PlayerId, bool comms) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!TaskMarkPerRound.ContainsKey(PlayerId)) { TaskMarkPerRound[PlayerId] = 0; } int num = TaskMarkPerRound[PlayerId]; int value = Math.Max(maxTasksMarkedPerRound - num, 0); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Taskinator).ShadeColor(0.25f)), $"({value})"); } public override void AfterMeetingTasks() { byte[] array = TaskMarkPerRound.Keys.ToArray(); foreach (byte b in array) { TaskMarkPerRound[b] = 0; if (taskIndex.ContainsKey(b)) { taskIndex[b].Clear(); } SendRPC(0, b); } if (shieldedPlayers.Any()) { shieldedPlayers.Clear(); SendRPC(1); } } public override void OnOthersTaskComplete(PlayerControl player, PlayerTask task) { //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !HasEnabled || (Object)(object)player == (Object)null || (Object)(object)base._Player == (Object)null || !player.IsAlive()) { return; } byte playerId = player.PlayerId; if (player.Is(CustomRoles.Benefactor)) { if (!TaskMarkPerRound.ContainsKey(playerId)) { TaskMarkPerRound[playerId] = 0; } if (TaskMarkPerRound[playerId] >= maxTasksMarkedPerRound) { TaskMarkPerRound[playerId] = maxTasksMarkedPerRound; Logger.Info($"Max task per round ({TaskMarkPerRound[playerId]}) reached for {player.GetNameWithRole()}", "Benefactor", escapeCRLF: true, 162, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Benefactor.cs"); return; } TaskMarkPerRound[playerId]++; if (!taskIndex.ContainsKey(playerId)) { taskIndex[playerId] = new HashSet(); } taskIndex[playerId].Add(task.Index); SendRPC(2, playerId, byte.MaxValue, task.Index); player.Notify(Translator.GetString("BenefactorTaskMarked")); return; } byte[] array = taskIndex.Keys.ToArray(); foreach (byte b in array) { if (taskIndex[b].Contains(task.Index)) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Benefactor)), Translator.GetString("BenefactorTargetGotShield"))); player.RpcGuardAndKill(); long timeStamp = Utils.GetTimeStamp(); shieldedPlayers[playerId] = timeStamp; taskIndex[b].Remove(task.Index); SendRPC(3, b, playerId, task.Index); Logger.Info(player.GetAllRoleName() + " got a shield from " + playerById.GetNameWithRole(), "Benefactor", escapeCRLF: true, 187, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Benefactor.cs"); } } } } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if ((Object)(object)target == (Object)null || (Object)(object)killer == (Object)null) { return true; } if (!shieldedPlayers.ContainsKey(target.PlayerId)) { return false; } if (ShieldIsOneTimeUse.GetBool()) { shieldedPlayers.Remove(target.PlayerId); SendRPC(4, byte.MaxValue, target.PlayerId); Logger.Info(target.GetNameWithRole() + " shield broken", "BenefactorShieldBroken", escapeCRLF: true, 202, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Benefactor.cs"); } killer.RpcGuardAndKill(); killer.SetKillCooldown(); return true; } public override void OnFixedUpdateLowLoad(PlayerControl pc) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) long now = Utils.GetTimeStamp(); KeyValuePair[] array = shieldedPlayers.Where((KeyValuePair x) => x.Value + ShieldDuration.GetInt() < now).ToArray(); foreach (KeyValuePair keyValuePair in array) { byte key = keyValuePair.Key; shieldedPlayers.Remove(key); Utils.GetPlayerById(key)?.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Benefactor)), Translator.GetString("BKProtectOut"))); Utils.GetPlayerById(key)?.RpcGuardAndKill(); SendRPC(4, byte.MaxValue, key); } } } internal class Bodyguard : RoleBase { private const int Id = 10300; private static OptionItem ProtectRadiusOpt; public static bool HasEnabled => CustomRoles.Bodyguard.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(10300, TabGroup.CrewmateRoles, CustomRoles.Bodyguard); ProtectRadiusOpt = FloatOptionItem.Create(10302, "BodyguardProtectRadius", new FloatValueRule(0.5f, 5f, 0.5f), 1.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bodyguard]).SetValueFormat(OptionFormat.Multiplier); } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) PlayerControl player = base._Player; if (!player.IsAlive() || ((killer != null) ? new byte?(killer.PlayerId) : null) == target.PlayerId || player.PlayerId == target.PlayerId) { return false; } bool flag; switch (killer.GetCustomRole()) { case CustomRoles.Crusader: case CustomRoles.Deputy: case CustomRoles.Veteran: case CustomRoles.Taskinator: flag = true; break; default: flag = false; break; } if (flag) { return false; } if (Vector2.Distance(Vector2.op_Implicit(((Component)target).transform.position), Vector2.op_Implicit(((Component)player).transform.position)) > ProtectRadiusOpt.GetFloat()) { return false; } if (player.Is(CustomRoles.Madmate) && killer.GetCustomRole().IsImpostorTeam()) { Logger.Info(player.GetRealName() + " He was a impostor, so he chose to ignore the murder scene", "Bodyguard", escapeCRLF: true, 45, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Bodyguard.cs"); } else if (player.CheckForInvalidMurdering(killer)) { player.SetDeathReason(PlayerState.DeathReason.Sacrifice); player.RpcMurderPlayer(killer); player.SetRealKiller(killer); player.RpcMurderPlayer(player); Logger.Info(player.GetRealName() + " Stand up and die with the gangster " + killer.GetRealName(), "Bodyguard", escapeCRLF: true, 53, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Bodyguard.cs"); return true; } return false; } } internal class Captain : RoleBase { private const int Id = 26300; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem OptionCrewCanFindCaptain; private static OptionItem OptionMadmateCanFindCaptain; private static OptionItem OptionTaskRequiredToReveal; private static OptionItem OptionTaskRequiredToSlow; private static OptionItem OptionReducedSpeed; private static OptionItem OptionReducedSpeedTime; private static OptionItem CaptainCanTargetNB; private static OptionItem CaptainCanTargetNC; private static OptionItem CaptainCanTargetNE; private static OptionItem CaptainCanTargetNK; private static readonly Dictionary OriginalSpeed = new Dictionary(); private static readonly Dictionary> CaptainVoteTargets = new Dictionary>(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(26300, TabGroup.CrewmateRoles, CustomRoles.Captain); OptionCrewCanFindCaptain = BooleanOptionItem.Create(26311, "CrewCanFindCaptain", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); OptionMadmateCanFindCaptain = BooleanOptionItem.Create(26312, "MadmateCanFindCaptain", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(OptionCrewCanFindCaptain); OptionTaskRequiredToReveal = IntegerOptionItem.Create(26313, "CaptainRevealTaskRequired", new IntegerValueRule(0, 15, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(OptionCrewCanFindCaptain); OptionTaskRequiredToSlow = IntegerOptionItem.Create(26314, "CaptainSlowTaskRequired", new IntegerValueRule(0, 15, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); OptionReducedSpeed = FloatOptionItem.Create(26315, "ReducedSpeed", new FloatValueRule(0.1f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]).SetValueFormat(OptionFormat.Times); OptionReducedSpeedTime = FloatOptionItem.Create(26316, "ReducedSpeedTime", new FloatValueRule(1f, 60f, 1f), 5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]).SetValueFormat(OptionFormat.Seconds); CaptainCanTargetNB = BooleanOptionItem.Create(26317, "CaptainCanTargetNB", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); CaptainCanTargetNC = BooleanOptionItem.Create(26318, "CaptainCanTargetNC", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); CaptainCanTargetNE = BooleanOptionItem.Create(26319, "CaptainCanTargetNE", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); CaptainCanTargetNK = BooleanOptionItem.Create(26320, "CaptainCanTargetNK", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Captain]); Options.OverrideTasksData.Create(26321, TabGroup.CrewmateRoles, CustomRoles.Captain); } public override void Init() { playerIdList.Clear(); OriginalSpeed.Clear(); CaptainVoteTargets.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } private static void SendRPCSetSpeed(byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)133, (SendOption)1, -1); val.Write(targetId); val.Write(OriginalSpeed[targetId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCSetSpeed(MessageReader reader) { byte key = reader.ReadByte(); float value = reader.ReadSingle(); OriginalSpeed[key] = value; } private static void SendRPCRevertSpeed(byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)134, (SendOption)1, -1); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCRevertSpeed(MessageReader reader) { byte key = reader.ReadByte(); if (OriginalSpeed.ContainsKey(key)) { OriginalSpeed.Remove(key); } } private static void SendRPCRevertAllSpeed() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)135, (SendOption)1, -1); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCRevertAllSpeed() { OriginalSpeed.Clear(); } public static void SendRPCVoteAdd(byte playerId, byte targetId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)136, (SendOption)1, -1); val.Write(playerId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCVoteAdd(MessageReader reader) { byte key = reader.ReadByte(); byte item = reader.ReadByte(); if (!CaptainVoteTargets.ContainsKey(key)) { CaptainVoteTargets[key] = new List(); } CaptainVoteTargets[key].Add(item); } private static void SendRPCVoteRemove(byte captainTarget = byte.MaxValue, CustomRoles? SelectedAddon = null) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)137, (SendOption)1, -1); val.Write(captainTarget); if (captainTarget != byte.MaxValue) { val.Write((int)SelectedAddon.Value); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCVoteRemove(MessageReader reader) { byte b = reader.ReadByte(); if (b != byte.MaxValue) { int? num = reader.ReadInt32(); if (num.HasValue) { Main.PlayerStates[b].SubRoles.Remove((CustomRoles)num.Value); } } else { CaptainVoteTargets.Clear(); } } public static bool CrewCanFindCaptain() { return OptionCrewCanFindCaptain.GetBool(); } public override bool OnTaskComplete(PlayerControl pc, int completedTaskCount, int totalTaskCount) { if ((Object)(object)pc == (Object)null || !pc.IsAlive()) { return true; } if (pc.GetPlayerTaskState().CompletedTasksCount >= OptionTaskRequiredToReveal.GetInt()) { Utils.NotifyRoles(null, pc); } if (pc.GetPlayerTaskState().CompletedTasksCount < OptionTaskRequiredToSlow.GetInt()) { return true; } List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => (Object)(object)x != (Object)null && !OriginalSpeed.ContainsKey(x.PlayerId) && (x.GetCustomRole().IsImpostorTeamV3() || (CaptainCanTargetNB.GetBool() && x.GetCustomRole().IsNB()) || (CaptainCanTargetNE.GetBool() && x.GetCustomRole().IsNE()) || (CaptainCanTargetNC.GetBool() && x.GetCustomRole().IsNC()) || (CaptainCanTargetNK.GetBool() && x.GetCustomRole().IsNeutralKillerTeam()))).ToList(); Logger.Info($"Total Number of Potential Target {list.Count}", "Total Captain Target", escapeCRLF: true, 153, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Captain.cs"); if (list.Count == 0) { return true; } _ = IRandom.Instance; PlayerControl targetPC = list.RandomElement(); byte target = targetPC.PlayerId; OriginalSpeed[target] = Main.AllPlayerSpeed[target]; SendRPCSetSpeed(target); Logger.Info(targetPC.GetNameWithRole().RemoveHtmlTags() + " is chosen as the captain's target", "Captain Target", escapeCRLF: true, 160, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Captain.cs"); Main.AllPlayerSpeed[target] = OptionReducedSpeed.GetFloat(); targetPC.SyncSettings(); targetPC.Notify(Translator.GetString("CaptainSpeedReduced"), OptionReducedSpeedTime.GetFloat()); new LateTask(delegate { if (GameStates.IsInTask) { Main.AllPlayerSpeed[target] = OriginalSpeed[target]; targetPC.SyncSettings(); OriginalSpeed.Remove(target); SendRPCRevertSpeed(target); } }, OptionReducedSpeedTime.GetFloat(), "Captain Revert Speed"); return true; } private static CustomRoles? SelectRandomAddon(byte targetId) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return null; } List list = Main.PlayerStates[targetId].SubRoles.ToList(); for (int num = list.Count - 1; num >= 0; num--) { CustomRoles customRoles = list[num]; if (customRoles == CustomRoles.Cleansed || customRoles == CustomRoles.LastImpostor || customRoles == CustomRoles.Lovers || customRoles.IsBetrayalAddon()) { Logger.Info($"Removed {customRoles} from list of addons", "Captain", escapeCRLF: true, 187, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Captain.cs"); list.Remove(customRoles); } } if (list.Count == 0) { Logger.Info("No removable addons found on the target.", "Captain", escapeCRLF: true, 194, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Captain.cs"); return null; } return list.RandomElement(); } public override void OnPlayerExiled(PlayerControl captain, NetworkedPlayerInfo exiled) { if ((Object)(object)exiled == (Object)null || exiled.GetCustomRole() != CustomRoles.Captain) { return; } byte playerId = exiled.PlayerId; if (playerId == byte.MaxValue || !CaptainVoteTargets.ContainsKey(playerId)) { return; } for (int i = 0; i < CaptainVoteTargets[playerId].Count; i++) { byte b = CaptainVoteTargets[playerId][i]; if (b != byte.MaxValue && Utils.GetPlayerById(b).IsAlive()) { CustomRoles? customRoles = SelectRandomAddon(b); if (customRoles.HasValue) { Main.PlayerStates[b].RemoveSubRole(customRoles.Value); Logger.Info($"Successfully removed {customRoles} addon from {Utils.GetPlayerById(b).GetNameWithRole()}", "Captain", escapeCRLF: true, 214, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Captain.cs"); SendRPCVoteRemove(b, customRoles); } } } CaptainVoteTargets.Clear(); SendRPCVoteRemove(); } public override void OnReportDeadBody(PlayerControl y, NetworkedPlayerInfo x) { byte[] array = OriginalSpeed.Keys.ToArray(); foreach (byte b in array) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { Main.AllPlayerSpeed[b] = OriginalSpeed[b]; playerById.SyncSettings(); } } OriginalSpeed.Clear(); SendRPCRevertAllSpeed(); } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.Captain) && OptionCrewCanFindCaptain.GetBool() && target.GetPlayerTaskState().CompletedTasksCount >= OptionTaskRequiredToReveal.GetInt() && ((seer.Is(Custom_Team.Crewmate) && !seer.Is(CustomRoles.Madmate)) || (seer.Is(CustomRoles.Madmate) && OptionMadmateCanFindCaptain.GetBool()))) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Captain)), " ☆"); } return string.Empty; } public override void OnVoted(PlayerControl votedPlayer, PlayerControl votedTarget) { if (votedPlayer.Is(CustomRoles.Captain)) { if (!CaptainVoteTargets.ContainsKey(votedPlayer.PlayerId)) { CaptainVoteTargets[votedPlayer.PlayerId] = new List(); } if (!CaptainVoteTargets[votedPlayer.PlayerId].Contains(votedTarget.PlayerId)) { CaptainVoteTargets[votedPlayer.PlayerId].Add(votedTarget.PlayerId); SendRPCVoteAdd(votedPlayer.PlayerId, votedTarget.PlayerId); } } } } internal class Celebrity : RoleBase { private const int Id = 6500; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ImpKnowCelebrityDead; private static OptionItem NeutralKnowCelebrityDead; private static readonly HashSet CelebrityDead = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(6500, TabGroup.CrewmateRoles, CustomRoles.Celebrity); ImpKnowCelebrityDead = BooleanOptionItem.Create(6510, "ImpKnowCelebrityDead", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Celebrity]); NeutralKnowCelebrityDead = BooleanOptionItem.Create(6511, "NeutralKnowCelebrityDead", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Celebrity]); } public override void Init() { playerIdList.Clear(); CelebrityDead.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override bool GlobalKillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (target.PlayerId == base._Player.PlayerId && seer.PlayerId == base._Player.PlayerId) { return true; } if (!ImpKnowCelebrityDead.GetBool() && seer.GetCustomRole().IsImpostor()) { return false; } if (!NeutralKnowCelebrityDead.GetBool() && seer.GetCustomRole().IsNeutral()) { return false; } seer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Celebrity)), Translator.GetString("OnCelebrityDead"))); return true; } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (isSuicide && target.IsDisconnected()) { return; } if (inMeeting) { PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if ((ImpKnowCelebrityDead.GetBool() || !val.GetCustomRole().IsImpostor()) && (NeutralKnowCelebrityDead.GetBool() || !val.GetCustomRole().IsNeutral())) { Utils.SendMessage(string.Format(Translator.GetString("CelebrityDead"), target.GetRealName()), val.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Celebrity)), Translator.GetString("CelebrityNewsTitle"))); } } } else if (!CelebrityDead.Contains(target.PlayerId)) { CelebrityDead.Add(target.PlayerId); } } public override void OnOthersMeetingHudStart(PlayerControl targets) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) foreach (byte item in CelebrityDead) { if ((ImpKnowCelebrityDead.GetBool() || !targets.GetCustomRole().IsImpostor()) && (NeutralKnowCelebrityDead.GetBool() || !targets.GetCustomRole().IsNeutral())) { MeetingHudStartPatch.AddMsg(string.Format(Translator.GetString("CelebrityDead"), Main.AllPlayerNames[item]), targets.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Celebrity)), Translator.GetString("CelebrityNewsTitle"))); } } } public override void MeetingHudClear() { CelebrityDead.Clear(); } } internal class Chameleon : RoleBase { private const int Id = 7600; private static OptionItem ChameleonCooldown; private static OptionItem ChameleonDuration; private static OptionItem UseLimitOpt; private static OptionItem ChameleonAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary ventedId = new Dictionary(); private static readonly Dictionary InvisCooldown = new Dictionary(); private static readonly Dictionary InvisDuration = new Dictionary(); public static bool HasEnabled => CustomRoles.Chameleon.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(7600, TabGroup.CrewmateRoles, CustomRoles.Chameleon); ChameleonCooldown = FloatOptionItem.Create(7602, "ChameleonCooldown", new FloatValueRule(1f, 60f, 1f), 30f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chameleon]).SetValueFormat(OptionFormat.Seconds); ChameleonDuration = FloatOptionItem.Create(7604, "ChameleonDuration", new FloatValueRule(1f, 30f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chameleon]).SetValueFormat(OptionFormat.Seconds); UseLimitOpt = IntegerOptionItem.Create(7605, "AbilityUseLimit", new IntegerValueRule(0, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chameleon]).SetValueFormat(OptionFormat.Times); ChameleonAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(7606, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Chameleon]).SetValueFormat(OptionFormat.Times); } public override void Init() { InvisCooldown.Clear(); InvisDuration.Clear(); ventedId.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = UseLimitOpt.GetInt(); } public void SendRPC(PlayerControl pc, bool isLimit = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)190, (SendOption)1, isLimit ? (-1) : pc.GetClientId()); val.Write(pc.PlayerId); val.Write(isLimit); if (isLimit) { val.Write(base.AbilityLimit); } else { val.Write((InvisCooldown.TryGetValue(pc.PlayerId, out var value) ? value : (-1)).ToString()); val.Write((InvisDuration.TryGetValue(pc.PlayerId, out var value2) ? value2 : (-1)).ToString()); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC_Custom(MessageReader reader) { byte key = reader.ReadByte(); if (reader.ReadBoolean()) { float abilityLimit = reader.ReadSingle(); Main.PlayerStates[key].RoleClass.AbilityLimit = abilityLimit; return; } InvisCooldown.Clear(); InvisDuration.Clear(); long num = long.Parse(reader.ReadString()); long num2 = long.Parse(reader.ReadString()); if (num > 0) { InvisCooldown.Add(key, num); } if (num2 > 0) { InvisDuration.Add(key, num2); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = ChameleonCooldown.GetFloat() + 1f; AURoleOptions.EngineerInVentMaxTime = 1f; } private static bool CanGoInvis(byte id) { if (GameStates.IsInTask && !InvisDuration.ContainsKey(id)) { return !InvisCooldown.ContainsKey(id); } return false; } private static bool IsInvis(byte id) { return InvisDuration.ContainsKey(id); } public override void OnReportDeadBody(PlayerControl y, NetworkedPlayerInfo x) { byte[] array = base._playerIdList.ToArray(); foreach (byte b in array) { if (!IsInvis(b)) { continue; } PlayerControl playerById = Utils.GetPlayerById(b); if ((Object)(object)playerById == (Object)null) { return; } if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(b, out var value) ? value : Main.LastEnteredVent[b].Id); } } InvisDuration.Remove(b); ventedId.Remove(b); SendRPC(playerById); } InvisCooldown.Clear(); InvisDuration.Clear(); ventedId.Clear(); } public override void AfterMeetingTasks() { InvisCooldown.Clear(); InvisDuration.Clear(); foreach (byte playerId in base._playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (playerById.IsAlive()) { InvisCooldown.Add(playerById.PlayerId, Utils.GetTimeStamp()); SendRPC(playerById); } } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += ChameleonAbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPC(player, isLimit: true); } return true; } public override void OnFixedUpdateLowLoad(PlayerControl player) { long timeStamp = Utils.GetTimeStamp(); byte playerId = player.PlayerId; bool flag = false; if (InvisCooldown.TryGetValue(playerId, out var value) && value + (long)ChameleonCooldown.GetFloat() - timeStamp < 0) { InvisCooldown.Remove(playerId); if (!player.IsModClient()) { player.Notify(Translator.GetString("ChameleonCanVent")); } flag = true; } foreach (KeyValuePair item in InvisDuration) { byte key = item.Key; PlayerControl playerById = Utils.GetPlayerById(key); if ((Object)(object)playerById == (Object)null) { continue; } long num = item.Value + (long)ChameleonDuration.GetFloat() - timeStamp; if (num < 0 || !playerById.IsAlive()) { if (playerById != null) { PlayerPhysics myPhysics = playerById.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(key, out var value2) ? value2 : Main.LastEnteredVent[key].Id); } } ventedId.Remove(key); InvisCooldown.Remove(key); InvisCooldown.Add(key, timeStamp); playerById.Notify(Translator.GetString("ChameleonInvisStateOut")); flag = true; InvisDuration.Remove(key); } else if (num <= 10 && !playerById.IsModClient()) { playerById.Notify(string.Format(Translator.GetString("ChameleonInvisStateCountdown"), num), 4f, sendInLog: false); } } if (flag) { SendRPC(player); } } public override void OnCoEnterVent(PlayerPhysics physics, int ventId) { PlayerControl chameleon = physics.myPlayer; byte chameleonId = chameleon.Data.PlayerId; if (!((InnerNetClient)AmongUsClient.Instance).AmHost || IsInvis(chameleonId)) { return; } new LateTask(delegate { if (CanGoInvis(chameleonId)) { if (base.AbilityLimit >= 1f) { ventedId.Remove(chameleonId); ventedId.Add(chameleonId, ventId); physics.RpcBootFromVentDesync(ventId, chameleon); InvisDuration.Remove(chameleonId); InvisDuration.Add(chameleonId, Utils.GetTimeStamp()); SendRPC(chameleon); float abilityLimit = base.AbilityLimit; base.AbilityLimit = abilityLimit - 1f; SendRPC(chameleon, isLimit: true); chameleon.Notify(Translator.GetString("ChameleonInvisState"), ChameleonDuration.GetFloat()); } else { chameleon.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks")); } } else { chameleon.Notify(Translator.GetString("ChameleonInvisInCooldown")); } }, 0.8f, "Chameleon Vent"); } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (!IsInvis(pc.PlayerId)) { return; } InvisDuration.Remove(pc.PlayerId); InvisCooldown.Add(pc.PlayerId, Utils.GetTimeStamp()); SendRPC(pc); if (pc != null) { PlayerPhysics myPhysics = pc.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(vent.Id); } } pc.Notify(Translator.GetString("ChameleonInvisStateOut")); } public override string GetLowerText(PlayerControl pc, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if ((Object)(object)pc == (Object)null || !isForHud || isForMeeting || !pc.IsAlive()) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); long value; if (IsInvis(pc.PlayerId)) { long num = InvisDuration[pc.PlayerId] + (long)ChameleonDuration.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("ChameleonInvisStateCountdown"), num + 1)); } else if (InvisCooldown.TryGetValue(pc.PlayerId, out value)) { long num2 = value + (long)ChameleonCooldown.GetFloat() - Utils.GetTimeStamp(); stringBuilder.Append(string.Format(Translator.GetString("ChameleonInvisCooldownRemain"), num2 + 1)); } else { stringBuilder.Append(Translator.GetString("ChameleonCanVent")); } return stringBuilder.ToString(); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (!IsInvis(killer.PlayerId)) { return true; } if (target != null) { PlayerPhysics myPhysics = target.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(ventedId.TryGetValue(target.PlayerId, out var value) ? value : Main.LastEnteredVent[target.PlayerId].Id); } } return true; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString(IsInvis(PlayerControl.LocalPlayer.PlayerId) ? "ChameleonRevertDisguise" : "ChameleonDisguise")); ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("invisible"); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } } internal class Cleanser : RoleBase { private const int Id = 6600; private static OptionItem CleanserUsesOpt; private static OptionItem CleansedCanGetAddon; private static OptionItem HidesVote; private readonly HashSet CleansedPlayers = new HashSet(); private readonly Dictionary CleanserTarget = new Dictionary(); private bool DidVote; public static bool HasEnabled => CustomRoles.Cleanser.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(6600, TabGroup.CrewmateRoles, CustomRoles.Cleanser); CleanserUsesOpt = IntegerOptionItem.Create(6610, "MaxCleanserUses", new IntegerValueRule(1, 14, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleanser]).SetValueFormat(OptionFormat.Times); CleansedCanGetAddon = BooleanOptionItem.Create(6611, "CleansedCanGetAddon", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleanser]); HidesVote = BooleanOptionItem.Create(6612, "CleanserHideVote", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleanser]); } public override void Add(byte playerId) { CleanserTarget.Add(playerId, byte.MaxValue); base.AbilityLimit = CleanserUsesOpt.GetInt(); DidVote = false; } public static bool CantGetAddon() { return !CleansedCanGetAddon.GetBool(); } public override bool HideVote(PlayerVoteArea ps) { if (HidesVote.GetBool()) { return base.AbilityLimit > 0f; } return false; } public override string GetProgressText(byte playerId, bool comms) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Color val = ((!(base.AbilityLimit > 0f)) ? Color.gray : Utils.GetRoleColor(CustomRoles.Cleanser)); return Utils.ColorString(Color32.op_Implicit(val), $"({base.AbilityLimit})"); } public override void OnVote(PlayerControl voter, PlayerControl target) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) if (!voter.Is(CustomRoles.Cleanser) || DidVote) { return; } DidVote = true; if (!(base.AbilityLimit <= 0f)) { if (target.PlayerId == voter.PlayerId) { Utils.SendMessage(Translator.GetString("CleanserRemoveSelf"), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cleanser)), Translator.GetString("CleanserTitle"))); } else if (target.Is(CustomRoles.Stubborn)) { Utils.SendMessage(Translator.GetString("CleanserCantRemove"), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cleanser)), Translator.GetString("CleanserTitle"))); } else if (CleanserTarget[voter.PlayerId] == byte.MaxValue) { base.AbilityLimit--; CleanserTarget[voter.PlayerId] = target.PlayerId; Logger.Info(voter.GetNameWithRole() + " cleansed " + target.GetNameWithRole(), "Cleansed", escapeCRLF: true, 75, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Cleanser.cs"); CleansedPlayers.Add(target.PlayerId); Utils.SendMessage(string.Format(Translator.GetString("CleanserRemovedRole"), target.GetRealName()), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cleanser)), Translator.GetString("CleanserTitle"))); SendSkillRPC(); } } } public override void OnReportDeadBody(PlayerControl baba, NetworkedPlayerInfo lilelam) { DidVote = false; foreach (byte key in CleanserTarget.Keys) { CleanserTarget[key] = byte.MaxValue; } } public override void NotifyAfterMeeting() { byte[] array = CleanserTarget.Keys.ToArray(); foreach (byte key in array) { byte b = CleanserTarget[key]; if (b != byte.MaxValue) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { playerById.Notify(Translator.GetString("LostAddonByCleanser")); } } } } public override void AfterMeetingTasks() { byte[] array = CleanserTarget.Keys.ToArray(); foreach (byte b in array) { if (b == byte.MaxValue) { continue; } byte b2 = CleanserTarget[b]; if (b2 != byte.MaxValue) { PlayerControl playerById = Utils.GetPlayerById(b2); if (!((Object)(object)playerById == (Object)null)) { playerById.RpcSetCustomRole(CustomRoles.Cleansed); Logger.Info("Removed all the add ons of " + playerById.GetNameWithRole(), "Cleanser", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Cleanser.cs"); } } } Utils.MarkEveryoneDirtySettings(); } } internal class CopyCat : RoleBase { private const int Id = 11500; public static readonly HashSet playerIdList = new HashSet(); private static OptionItem KillCooldown; private static OptionItem CopyCrewVar; private static OptionItem CopyTeamChangingAddon; private static float CurrentKillCooldown = 0f; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(11500, TabGroup.CrewmateRoles, CustomRoles.CopyCat); KillCooldown = FloatOptionItem.Create(11510, "CopyCatCopyCooldown", new FloatValueRule(0f, 180f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CopyCat]).SetValueFormat(OptionFormat.Seconds); CopyCrewVar = BooleanOptionItem.Create(11513, "CopyCrewVar", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CopyCat]); CopyTeamChangingAddon = BooleanOptionItem.Create(11514, "CopyTeamChangingAddon", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.CopyCat]); } public override void Init() { playerIdList.Clear(); CurrentKillCooldown = 0f; } public override void Add(byte playerId) { playerIdList.Add(playerId); CurrentKillCooldown = KillCooldown.GetFloat(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public static bool CanCopyTeamChangingAddon() { return CopyTeamChangingAddon.GetBool(); } public static bool NoHaveTask(byte playerId) { return playerIdList.Contains(playerId); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return playerIdList.Contains(pc.PlayerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (Utils.GetPlayerById(id).IsAlive() ? CurrentKillCooldown : 300f); } public static void UnAfterMeetingTasks() { byte[] array = playerIdList.ToArray(); for (int i = 0; i < array.Length; i++) { PlayerControl playerById = Utils.GetPlayerById(array[i]); if (!playerById.IsAlive()) { continue; } CustomRoles customRole = playerById.GetCustomRole(); if (customRole != CustomRoles.Sidekick || customRole != CustomRoles.Retributionist) { if (customRole != CustomRoles.CopyCat) { playerById.GetRoleClass()?.OnRemove(playerById.PlayerId); } playerById.RpcSetCustomRole(CustomRoles.CopyCat); } playerById.ResetKillCooldown(); } } private static bool BlackList(CustomRoles role) { switch (role) { case CustomRoles.EvilGuesser: case CustomRoles.Addict: case CustomRoles.Alchemist: case CustomRoles.Bastion: case CustomRoles.Captain: case CustomRoles.Chameleon: case CustomRoles.CopyCat: case CustomRoles.Grenadier: case CustomRoles.Lighter: case CustomRoles.Medic: case CustomRoles.Mole: case CustomRoles.NiceGuesser: case CustomRoles.Pacifist: case CustomRoles.TimeMaster: case CustomRoles.Veteran: case CustomRoles.Doomsayer: return true; default: return false; } } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { CustomRoles customRoles = target.GetCustomRole(); if (BlackList(customRoles)) { killer.Notify(Translator.GetString("CopyCatCanNotCopy")); killer.ResetKillCooldown(); return false; } if (CopyCrewVar.GetBool()) { switch (customRoles) { case CustomRoles.Eraser: customRoles = CustomRoles.Cleanser; break; case CustomRoles.Nemesis: customRoles = CustomRoles.Retributionist; break; case CustomRoles.Visionary: customRoles = CustomRoles.Oracle; break; case CustomRoles.Workaholic: customRoles = CustomRoles.Snitch; break; case CustomRoles.Sunnyboy: customRoles = CustomRoles.Doctor; break; case CustomRoles.Vindicator: case CustomRoles.Pickpocket: customRoles = CustomRoles.Mayor; break; case CustomRoles.Councillor: customRoles = CustomRoles.Judge; break; case CustomRoles.Arrogance: case CustomRoles.Juggernaut: customRoles = CustomRoles.Reverie; break; case CustomRoles.Taskinator: customRoles = CustomRoles.Benefactor; break; case CustomRoles.AntiAdminer: customRoles = CustomRoles.Telecommunication; break; case CustomRoles.Pursuer: customRoles = CustomRoles.Deceiver; break; } } if (customRoles.IsCrewmate()) { if (customRoles != CustomRoles.CopyCat) { killer.RpcSetCustomRole(customRoles); killer.GetRoleClass()?.OnAdd(killer.PlayerId); } if (CopyTeamChangingAddon.GetBool()) { if (target.Is(CustomRoles.Madmate) || target.Is(CustomRoles.Rascal)) { killer.RpcSetCustomRole(CustomRoles.Madmate); } if (target.Is(CustomRoles.Charmed)) { killer.RpcSetCustomRole(CustomRoles.Charmed); } if (target.Is(CustomRoles.Infected)) { killer.RpcSetCustomRole(CustomRoles.Infected); } if (target.Is(CustomRoles.Recruit)) { killer.RpcSetCustomRole(CustomRoles.Recruit); } if (target.Is(CustomRoles.Contagious)) { killer.RpcSetCustomRole(CustomRoles.Contagious); } if (target.Is(CustomRoles.Soulless)) { killer.RpcSetCustomRole(CustomRoles.Soulless); } } killer.RpcGuardAndKill(killer); killer.Notify(string.Format(Translator.GetString("CopyCatRoleChange"), Utils.GetRoleName(customRoles))); return false; } killer.Notify(Translator.GetString("CopyCatCanNotCopy")); killer.ResetKillCooldown(); return false; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("CopyButtonText")); } } internal class Coroner : RoleBase { private const int Id = 7700; private static readonly HashSet UnreportablePlayers = new HashSet(); private static readonly Dictionary> CoronerTargets = new Dictionary>(); private static OptionItem ArrowsPointingToDeadBody; private static OptionItem UseLimitOpt; private static OptionItem LeaveDeadBodyUnreportable; private static OptionItem CoronerAbilityUseGainWithEachTaskCompleted; private static OptionItem InformKillerBeingTracked; public static bool HasEnabled => CustomRoles.Coroner.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(7700, TabGroup.CrewmateRoles, CustomRoles.Coroner); ArrowsPointingToDeadBody = BooleanOptionItem.Create(7710, "CoronerArrowsPointingToDeadBody", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Coroner]); LeaveDeadBodyUnreportable = BooleanOptionItem.Create(7711, "CoronerLeaveDeadBodyUnreportable", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Coroner]); UseLimitOpt = IntegerOptionItem.Create(7712, "AbilityUseLimit", new IntegerValueRule(0, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Coroner]).SetValueFormat(OptionFormat.Times); CoronerAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(7713, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Coroner]).SetValueFormat(OptionFormat.Times); InformKillerBeingTracked = BooleanOptionItem.Create(7714, "CoronerInformKillerBeingTracked", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Coroner]); } public override void Init() { UnreportablePlayers.Clear(); CoronerTargets.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = UseLimitOpt.GetInt(); CoronerTargets.Add(playerId, new HashSet()); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } public override void Remove(byte playerId) { CoronerTargets.Remove(playerId); } private static void SendRPC(byte playerId, bool add, Vector3 loc = default(Vector3)) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)183, (SendOption)1, -1); val.Write(playerId); val.Write(add); if (add) { val.Write(loc.x); val.Write(loc.y); val.Write(loc.z); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } private void SendRPCLimit(byte playerId, int operate, byte targetId = byte.MaxValue) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(operate); val.Write(base.AbilityLimit); if (operate != 2) { val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); int num = reader.ReadInt32(); float abilityLimit = reader.ReadSingle(); base.AbilityLimit = abilityLimit; if (num != 2) { byte item = reader.ReadByte(); if (!CoronerTargets.ContainsKey(key)) { CoronerTargets[key] = new HashSet(); } CoronerTargets[key].Add(item); if (num == 1) { UnreportablePlayers.Add(item); } } } private static void SendRPCKiller(byte playerId, byte killerId, bool add) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)184, (SendOption)1, -1); val.Write(playerId); val.Write(killerId); val.Write(add); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCKiller(MessageReader reader) { byte b = reader.ReadByte(); byte b2 = reader.ReadByte(); if (reader.ReadBoolean()) { CoronerTargets[b].Add(b2); TargetArrow.Add(b, b2); } else { CoronerTargets[b].Remove(b2); TargetArrow.Remove(b, b2); } } public static void ReceiveRPC(MessageReader reader) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte b = reader.ReadByte(); if (reader.ReadBoolean()) { LocateArrow.Add(b, new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); return; } LocateArrow.RemoveAllTarget(b); if (CoronerTargets.ContainsKey(b)) { CoronerTargets[b].Clear(); } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += CoronerAbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPCLimit(player.PlayerId, 2); } return true; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("CoronerReportButtonText")); } public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody, PlayerControl killer) { if (UnreportablePlayers.Contains(deadBody.PlayerId)) { return false; } if (reporter.Is(CustomRoles.Coroner)) { if ((Object)(object)killer != (Object)null) { FindKiller(reporter, deadBody, killer); } else { reporter.Notify(Translator.GetString("CoronerNoTrack")); } return false; } return true; } private bool FindKiller(PlayerControl pc, NetworkedPlayerInfo deadBody, PlayerControl killer) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (CoronerTargets.TryGetValue(pc.PlayerId, out var value) && value.Contains(killer.PlayerId)) { return true; } LocateArrow.Remove(pc.PlayerId, ((Component)deadBody.Object).transform.position); SendRPC(pc.PlayerId, add: false); if (base.AbilityLimit >= 1f) { CoronerTargets[pc.PlayerId].Add(killer.PlayerId); TargetArrow.Add(pc.PlayerId, killer.PlayerId); SendRPCKiller(pc.PlayerId, killer.PlayerId, add: true); pc.Notify(Translator.GetString("CoronerTrackRecorded")); base.AbilityLimit -= 1f; int operate = 0; if (LeaveDeadBodyUnreportable.GetBool()) { UnreportablePlayers.Add(deadBody.PlayerId); operate = 1; } SendRPCLimit(pc.PlayerId, operate, deadBody.PlayerId); if (InformKillerBeingTracked.GetBool()) { killer.Notify(Translator.GetString("CoronerIsTrackingYou")); } } else { pc.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks")); } return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte[] array = base._playerIdList.ToArray(); foreach (byte num in array) { LocateArrow.RemoveAllTarget(num); SendRPC(num, add: false); } foreach (KeyValuePair> coronerTarget in CoronerTargets) { array = coronerTarget.Value.ToArray(); foreach (byte b in array) { TargetArrow.Remove(coronerTarget.Key, b); SendRPCKiller(coronerTarget.Key, b, add: false); } CoronerTargets[coronerTarget.Key].Clear(); } } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!ArrowsPointingToDeadBody.GetBool() || inMeeting || target.IsDisconnected()) { return; } byte[] array = base._playerIdList.ToArray(); foreach (byte b in array) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { LocateArrow.Add(b, ((Component)target).transform.position); SendRPC(b, add: true, ((Component)target).transform.position); } } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (!seer.Is(CustomRoles.Coroner)) { return ""; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return ""; } if (GameStates.IsMeeting) { return ""; } if (CoronerTargets.ContainsKey(seer.PlayerId) && CoronerTargets[seer.PlayerId].Any()) { string text = ""; { foreach (byte item in CoronerTargets[seer.PlayerId]) { string arrows = TargetArrow.GetArrows(seer, item); text += Utils.ColorString(Color32.op_Implicit(seer.GetRoleColor()), arrows); } return text; } } return Utils.ColorString(Color32.op_Implicit(Color.white), LocateArrow.GetArrows(seer)); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } } internal class Crusader : RoleBase { private const int Id = 10400; private static OptionItem SkillLimitOpt; private static OptionItem SkillCooldown; private readonly HashSet ForCrusade = new HashSet(); private float CurrentKillCooldown; public static bool HasEnabled => CustomRoles.Crusader.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(10400, TabGroup.CrewmateRoles, CustomRoles.Crusader); SkillCooldown = FloatOptionItem.Create(10410, "CrusaderSkillCooldown", new FloatValueRule(2.5f, 180f, 2.5f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crusader]).SetValueFormat(OptionFormat.Seconds); SkillLimitOpt = IntegerOptionItem.Create(10411, "CrusaderSkillLimit", new IntegerValueRule(1, 15, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Crusader]).SetValueFormat(OptionFormat.Times); } public override void Add(byte playerId) { base.AbilityLimit = SkillLimitOpt.GetInt(); CurrentKillCooldown = SkillCooldown.GetFloat(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CanUseKillButton(Utils.GetPlayerById(id)) ? CurrentKillCooldown : 300f); } public override bool CanUseKillButton(PlayerControl pc) { return base.AbilityLimit > 0f; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override string GetProgressText(byte playerId, bool comms) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CanUseKillButton(Utils.GetPlayerById(playerId)) ? Utils.GetRoleColor(CustomRoles.Crusader).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (ForCrusade.Contains(target.PlayerId) || base.AbilityLimit <= 0f) { return false; } ForCrusade.Remove(target.PlayerId); ForCrusade.Add(target.PlayerId); base.AbilityLimit--; SendSkillRPC(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } target.RpcGuardAndKill(killer); return false; } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (!ForCrusade.Contains(target.PlayerId)) { return false; } PlayerControl player = base._Player; if (!player.IsAlive() || player.PlayerId == target.PlayerId) { return false; } bool flag; switch (killer.GetCustomRole()) { case CustomRoles.Bodyguard: case CustomRoles.Deputy: case CustomRoles.Veteran: case CustomRoles.Taskinator: flag = true; break; default: flag = false; break; } if (flag) { return false; } if (player.CheckForInvalidMurdering(killer) && player.RpcCheckAndMurder(killer, check: true)) { killer.RpcGuardAndKill(target); player.RpcMurderPlayer(killer); ForCrusade.Remove(target.PlayerId); return true; } if (killer.Is(CustomRoles.Pestilence)) { player.SetDeathReason(PlayerState.DeathReason.PissedOff); killer.RpcMurderPlayer(player); ForCrusade.Remove(target.PlayerId); target.RpcGuardAndKill(killer); return true; } return false; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("CrusaderKillButtonText")); } } internal class Deceiver : RoleBase { private const int Id = 10500; private static OptionItem DeceiverSkillCooldown; private static OptionItem DeceiverSkillLimitTimes; private static OptionItem DeceiverAbilityLost; private readonly HashSet notActiveList = new HashSet(); private readonly HashSet clientList = new HashSet(); public static bool HasEnabled => CustomRoles.Deceiver.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; private bool CanSeel => base.AbilityLimit > 0f; public override void SetupCustomOption() { Options.SetupRoleOptions(10500, TabGroup.CrewmateRoles, CustomRoles.Deceiver); DeceiverSkillCooldown = FloatOptionItem.Create(10510, "DeceiverSkillCooldown", new FloatValueRule(2.5f, 180f, 2.5f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deceiver]).SetValueFormat(OptionFormat.Seconds); DeceiverSkillLimitTimes = IntegerOptionItem.Create(10511, "DeceiverSkillLimitTimes", new IntegerValueRule(1, 15, 1), 2, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deceiver]).SetValueFormat(OptionFormat.Times); DeceiverAbilityLost = BooleanOptionItem.Create(10512, "DeceiverAbilityLost", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deceiver]); } public override void Add(byte playerId) { base.AbilityLimit = DeceiverSkillLimitTimes.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override bool CanUseKillButton(PlayerControl pc) { if (pc.IsAlive()) { return base.AbilityLimit > 0f; } return false; } public override string GetProgressText(byte playerId, bool comms) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((!Main.PlayerStates[playerId].IsDead && base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Deceiver).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CanUseKillButton(Utils.GetPlayerById(id)) ? DeceiverSkillCooldown.GetFloat() : 300f); } private bool IsClient(byte playerId) { return clientList.Contains(playerId); } private bool CanBeClient(PlayerControl pc) { if ((Object)(object)pc != (Object)null && pc.IsAlive() && !GameStates.IsMeeting) { return !IsClient(pc.PlayerId); } return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return true; } if (target.Is(CustomRoles.Pestilence) || target.Is(CustomRoles.SerialKiller)) { return true; } if (!CanBeClient(target) || !CanSeel) { return false; } base.AbilityLimit--; SendSkillRPC(); if (target.Is(CustomRoles.KillingMachine)) { Logger.Info("target is Killing Machine, ability used count reduced, but target will not die", "Deceiver", escapeCRLF: true, 64, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Deceiver.cs"); return false; } clientList.Add(target.PlayerId); notActiveList.Add(killer.PlayerId); killer.RpcGuardAndKill(killer); killer.SetKillCooldown(); killer.RPCPlayCustomSound("Bet"); Utils.NotifyRoles(killer, target); Logger.Info("Counterfeiters " + killer.GetRealName() + " sell counterfeits to " + target.GetRealName(), "Deceiver", escapeCRLF: true, 78, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Deceiver.cs"); return false; } public override bool CheckMurderOnOthersTarget(PlayerControl pc, PlayerControl _) { if (!IsClient(pc.PlayerId) || notActiveList.Contains(pc.PlayerId)) { return false; } PlayerControl player = base._Player; if ((Object)(object)player == (Object)null) { return true; } pc.SetDeathReason(PlayerState.DeathReason.Misfire); pc.RpcMurderPlayer(pc); pc.SetRealKiller(player); Logger.Info($"The customer {pc.GetRealName()} of {pc.GetRealName()}, a counterfeiter, commits suicide by using counterfeits", "Deceiver", escapeCRLF: true, 93, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Deceiver.cs"); return true; } public override void OnReportDeadBody(PlayerControl rafaeu, NetworkedPlayerInfo dinosaurs) { notActiveList.Clear(); foreach (byte client in clientList) { PlayerControl playerById = Utils.GetPlayerById(client); if ((Object)(object)playerById == (Object)null || !playerById.IsAlive()) { continue; } CustomRoles customRole = playerById.GetCustomRole(); if ((!customRole.IsCrewmate() || customRole.IsCrewKiller()) && (!customRole.IsNeutral() || customRole.IsNK())) { continue; } PlayerControl player = base._Player; if (!((Object)(object)player == (Object)null)) { CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Misfire, playerById.PlayerId); playerById.SetRealKiller(Utils.GetPlayerById(client)); playerById.SetRealKiller(player); if (DeceiverAbilityLost.GetBool()) { base.AbilityLimit = 0f; SendSkillRPC(); } Logger.Info($"Deceiver: {player.GetRealName()} deceived {playerById.GetRealName()} player without kill button", "Deceiver", escapeCRLF: true, 119, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Deceiver.cs"); } } } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("DeceiverButtonText")); } } internal class Deputy : RoleBase { private const int Id = 7800; private static OptionItem HandcuffCooldown; private static OptionItem HandcuffMax; private static OptionItem DeputyHandcuffCDForTarget; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(7800, TabGroup.CrewmateRoles, CustomRoles.Deputy); HandcuffCooldown = FloatOptionItem.Create(7810, "DeputyHandcuffCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deputy]).SetValueFormat(OptionFormat.Seconds); DeputyHandcuffCDForTarget = FloatOptionItem.Create(7814, "DeputyHandcuffCDForTarget", new FloatValueRule(0f, 180f, 2.5f), 45f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deputy]).SetValueFormat(OptionFormat.Seconds); HandcuffMax = IntegerOptionItem.Create(7812, "DeputyHandcuffMax", new IntegerValueRule(1, 30, 1), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Deputy]).SetValueFormat(OptionFormat.Times); } public override void Add(byte playerId) { base.AbilityLimit = HandcuffMax.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = HandcuffCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl player) { if (!player.Data.IsDead) { return base.AbilityLimit >= 1f; } return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.SerialKiller)) { return false; } if (base.AbilityLimit < 1f) { return false; } Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} : Limit {base.AbilityLimit}", "Deputy", escapeCRLF: true, 45, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Deputy.cs"); if ((Object)(object)target != (Object)(object)base._Player) { base.AbilityLimit--; SendSkillRPC(); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Deputy)), Translator.GetString("DeputyHandcuffedPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Deputy)), Translator.GetString("HandcuffedByDeputy"))); target.SetKillCooldownV3(DeputyHandcuffCDForTarget.GetFloat()); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } if (!Options.DisableShieldAnimations.GetBool()) { target.RpcGuardAndKill(target); } return false; } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Deputy)), Translator.GetString("DeputyInvalidTarget"))); return false; } public override string GetProgressText(byte PlayerId, bool comms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit >= 1f) ? Utils.GetRoleColor(CustomRoles.Deputy) : Color.gray), $"({base.AbilityLimit})"); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("DeputyHandcuffText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Deputy"); } } internal class Detective : RoleBase { private const int Id = 7900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem DetectiveCanknowKiller; private static readonly Dictionary DetectiveNotify = new Dictionary(); private static readonly Dictionary InfoAboutDeadPlayerAndKiller = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(7900, TabGroup.CrewmateRoles, CustomRoles.Detective); DetectiveCanknowKiller = BooleanOptionItem.Create(7902, "DetectiveCanknowKiller", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Detective]); } public override void Init() { playerIdList.Clear(); DetectiveNotify.Clear(); InfoAboutDeadPlayerAndKiller.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); CustomRoleManager.CheckDeadBodyOthers.Add(GetInfoFromDeadBody); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); CustomRoleManager.CheckDeadBodyOthers.Remove(GetInfoFromDeadBody); } private void GetInfoFromDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (!((target.IsDisconnected() && killer.PlayerId == target.PlayerId) || inMeeting)) { InfoAboutDeadPlayerAndKiller[killer.PlayerId] = Utils.GetRoleName(killer.GetCustomRole()); InfoAboutDeadPlayerAndKiller[target.PlayerId] = Utils.GetRoleName(target.GetCustomRole()); } } public override void OnReportDeadBody(PlayerControl player, NetworkedPlayerInfo deadBody) { if ((Object)(object)deadBody == (Object)null) { return; } if ((Object)(object)player != (Object)null && player.Is(CustomRoles.Detective) && player.PlayerId != deadBody.PlayerId) { StringBuilder stringBuilder = new StringBuilder(); InfoAboutDeadPlayerAndKiller.TryGetValue(deadBody.PlayerId, out var value); stringBuilder.Append(string.Format(Translator.GetString("DetectiveNoticeVictim"), deadBody.PlayerName, value)); if (DetectiveCanknowKiller.GetBool()) { PlayerControl realKillerById = deadBody.PlayerId.GetRealKillerById(); if ((Object)(object)realKillerById == (Object)null) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendLiteral(";\n"); handler.AppendFormatted(Translator.GetString("DetectiveNoticeKillerNotFound")); stringBuilder3.Append(ref handler); } else { InfoAboutDeadPlayerAndKiller.TryGetValue(realKillerById.Data.PlayerId, out var value2); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 1, stringBuilder2); handler.AppendLiteral(";\n"); handler.AppendFormatted(string.Format(Translator.GetString("DetectiveNoticeKiller"), value2)); stringBuilder4.Append(ref handler); } } DetectiveNotify.Remove(player.PlayerId); DetectiveNotify.Add(player.PlayerId, stringBuilder.ToString()); } InfoAboutDeadPlayerAndKiller.Clear(); } public override void OnMeetingHudStart(PlayerControl pc) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (DetectiveNotify.ContainsKey(pc.PlayerId)) { MeetingHudStartPatch.AddMsg(DetectiveNotify[pc.PlayerId], pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Detective)), Translator.GetString("DetectiveNoticeTitle"))); } } public override void MeetingHudClear() { DetectiveNotify.Clear(); InfoAboutDeadPlayerAndKiller.Clear(); } } internal class Dictator : RoleBase { private const int Id = 11600; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(11600, TabGroup.CrewmateRoles, CustomRoles.Dictator); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public static bool CheckVotingForTarget(PlayerControl pc, PlayerVoteArea pva) { if (pc.Is(CustomRoles.Dictator) && pva.DidVote && pc.PlayerId != pva.VotedFor && pva.VotedFor < 253) { return !pc.Data.IsDead; } return false; } } internal class Doctor : RoleBase { private const int Id = 6700; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem TaskCompletedBatteryChargeOpt; private static OptionItem VisibleToEveryoneOpt; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(6700, TabGroup.CrewmateRoles, CustomRoles.Doctor); TaskCompletedBatteryChargeOpt = FloatOptionItem.Create(6710, "DoctorTaskCompletedBatteryCharge", new FloatValueRule(0f, 250f, 1f), 50f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doctor]).SetValueFormat(OptionFormat.Seconds); VisibleToEveryoneOpt = BooleanOptionItem.Create(6711, "DoctorVisibleToEveryone", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Doctor]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ScientistCooldown = 0f; AURoleOptions.ScientistBatteryCharge = TaskCompletedBatteryChargeOpt.GetFloat(); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { return true; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (VisibleToEveryoneOpt.GetBool() && !target.GetCustomSubRoles().Any((CustomRoles sub) => sub.IsBetrayalAddon())) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessDoctor")); return true; } return false; } public static bool VisibleToEveryone(PlayerControl target) { if (target.Is(CustomRoles.Doctor)) { return VisibleToEveryoneOpt.GetBool(); } return false; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return VisibleToEveryone(target); } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return VisibleToEveryone(target); } } internal class Enigma : RoleBase { private abstract class EnigmaClue { public int ClueStage { get; set; } public EnigmaClueType EnigmaClueType { get; set; } public abstract string Title { get; } public abstract string GetMessage(PlayerControl killer, bool showStageClue); } private class EnigmaHatClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueHatTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { PlayerOutfit normalOutfit = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit; if (normalOutfit.HatId == "hat_EmptyHat") { return Translator.GetString("EnigmaClueHat2"); } switch (base.ClueStage) { case 1: case 2: return Translator.GetString("EnigmaClueHat1"); case 3: if (showStageClue) { return string.Format(Translator.GetString("EnigmaClueHat3"), normalOutfit.HatId); } return Translator.GetString("EnigmaClueHat1"); default: return null; } } } private class EnigmaVisorClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueVisorTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { PlayerOutfit normalOutfit = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit; if (normalOutfit.VisorId == "visor_EmptyVisor") { return Translator.GetString("EnigmaClueVisor2"); } switch (base.ClueStage) { case 1: case 2: return Translator.GetString("EnigmaClueVisor1"); case 3: if (showStageClue) { return string.Format(Translator.GetString("EnigmaClueVisor3"), normalOutfit.VisorId); } return Translator.GetString("EnigmaClueVisor1"); default: return null; } } } private class EnigmaSkinClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueSkinTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { PlayerOutfit normalOutfit = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit; if (normalOutfit.SkinId == "skin_EmptySkin") { return Translator.GetString("EnigmaClueSkin2"); } switch (base.ClueStage) { case 1: case 2: return Translator.GetString("EnigmaClueSkin1"); case 3: if (showStageClue) { return string.Format(Translator.GetString("EnigmaClueSkin3"), normalOutfit.SkinId); } return Translator.GetString("EnigmaClueSkin1"); default: return null; } } } private class EnigmaPetClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaCluePetTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { PlayerOutfit normalOutfit = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit; if (normalOutfit.PetId == "pet_EmptyPet") { return Translator.GetString("EnigmaCluePet2"); } switch (base.ClueStage) { case 1: case 2: return Translator.GetString("EnigmaCluePet1"); case 3: if (showStageClue) { return string.Format(Translator.GetString("EnigmaCluePet3"), normalOutfit.PetId); } return Translator.GetString("EnigmaCluePet1"); default: return null; } } } private class EnigmaNameClue : EnigmaClue { private readonly IRandom rd = IRandom.Instance; public override string Title => Translator.GetString("EnigmaClueNameTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { string playerName = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit.PlayerName; string letter = playerName[rd.Next(0, playerName.Length)].ToString().ToLower(); switch (base.ClueStage) { case 1: return GetStage1Clue(killer, letter); case 2: if (showStageClue) { GetStage2Clue(letter); } return GetStage1Clue(killer, letter); case 3: if (showStageClue) { GetStage3Clue(playerName, letter); } if (rd.Next(0, 100) < EnigmaClueStage2Probability.GetInt()) { GetStage2Clue(letter); } return GetStage1Clue(killer, letter); default: return null; } } private string GetStage1Clue(PlayerControl killer, string letter) { string randomLetter = GetRandomLetter(killer, letter); if (rd.Next(1, 2) == 1) { return string.Format(Translator.GetString("EnigmaClueName1"), letter, randomLetter); } return string.Format(Translator.GetString("EnigmaClueName1"), randomLetter, letter); } private static string GetStage2Clue(string letter) { return string.Format(Translator.GetString("EnigmaClueName2"), letter); } private string GetStage3Clue(string killerName, string letter) { string arg = string.Empty; string text = killerName.Replace(letter, string.Empty); if (!string.IsNullOrEmpty(text)) { arg = text[rd.Next(0, text.Length)].ToString().ToLower(); } return string.Format(Translator.GetString("EnigmaClueName3"), letter, arg); } private string GetRandomLetter(PlayerControl killer, string letter) { string text = Main.AllAlivePlayerControls.Where((PlayerControl a) => a.PlayerId != killer.PlayerId).ToList().RandomElement() .GetRealName() .Replace(letter, ""); return text[rd.Next(0, text.Length)].ToString().ToLower(); } } private class EnigmaNameLengthClue : EnigmaClue { private readonly IRandom rd = IRandom.Instance; public override string Title => Translator.GetString("EnigmaClueNameLengthTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { int length = Main.PlayerStates[killer.Data.PlayerId].NormalOutfit.PlayerName.Length; switch (base.ClueStage) { case 1: return GetStage1Clue(length); case 2: if (showStageClue) { return GetStage2Clue(length); } return GetStage1Clue(length); case 3: if (showStageClue) { return GetStage3Clue(length); } if (rd.Next(0, 100) < EnigmaClueStage2Probability.GetInt()) { return GetStage2Clue(length); } return GetStage1Clue(length); default: return null; } } private string GetStage1Clue(int length) { int num = length - rd.Next(2, 4); int num2 = length + rd.Next(2, 4); num = ((num >= 0) ? num : 0); num = ((num >= 10) ? 8 : num); num2 = ((num2 > 10) ? 10 : num2); return string.Format(Translator.GetString("EnigmaClueNameLength1"), num, num2); } private string GetStage2Clue(int length) { int num = length - rd.Next(1, 3); int num2 = length + rd.Next(1, 3); num = ((num >= 0) ? num : 0); num = ((num >= 10) ? 9 : num); num2 = ((num2 > 10) ? 10 : num2); return string.Format(Translator.GetString("EnigmaClueNameLength1"), num, num2); } private static string GetStage3Clue(int length) { return string.Format(Translator.GetString("EnigmaClueNameLength2"), length); } } private class EnigmaColorClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueColorTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { PlayerOutfit val = Camouflage.PlayerSkins[killer.PlayerId]; switch (base.ClueStage) { case 1: case 2: return GetStage1Clue(val.ColorId); case 3: if (showStageClue) { return string.Format(Translator.GetString("EnigmaClueColor3"), killer.Data.ColorName); } return GetStage1Clue(val.ColorId); default: return GetStage1Clue(val.ColorId); } } private static string GetStage1Clue(int colorId) { switch (colorId) { case 0: case 3: case 4: case 5: case 7: case 10: case 11: case 13: case 14: case 17: return Translator.GetString("EnigmaClueColor1"); case 1: case 2: case 6: case 8: case 9: case 12: case 15: case 16: return Translator.GetString("EnigmaClueColor2"); default: return null; } } } private class EnigmaLocationClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueLocationTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) string empty = string.Empty; PlainShipRoom lastRoom = Main.PlayerStates[killer.PlayerId].LastRoom; if ((Object)(object)lastRoom == (Object)null) { empty += Translator.GetString("FailToTrack"); } else { string text = empty; SystemTypes roomId = lastRoom.RoomId; empty = text + Translator.GetString(((object)(SystemTypes)(ref roomId)).ToString()); } return string.Format(Translator.GetString("EnigmaClueLocation"), empty); } } private class EnigmaKillerStatusClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueStatusTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { if (killer.inVent) { return Translator.GetString("EnigmaClueStatus1"); } if (killer.onLadder) { return Translator.GetString("EnigmaClueStatus2"); } if (killer.Data.IsDead) { return Translator.GetString("EnigmaClueStatus3"); } return Translator.GetString("EnigmaClueStatus4"); } } private class EnigmaKillerRoleClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueRoleTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { CustomRoles customRole = killer.GetCustomRole(); switch (base.ClueStage) { case 1: if (customRole.IsImpostor()) { return Translator.GetString("EnigmaClueRole1"); } if (customRole.IsNeutral()) { return Translator.GetString("EnigmaClueRole2"); } return Translator.GetString("EnigmaClueRole3"); case 2: if (showStageClue) { return string.Format(Translator.GetString("EnigmaClueRole4"), killer.GetDisplayRoleAndSubName(killer)); } if (customRole.IsImpostor()) { return Translator.GetString("EnigmaClueRole1"); } if (customRole.IsNeutral()) { return Translator.GetString("EnigmaClueRole2"); } return Translator.GetString("EnigmaClueRole3"); default: return null; } } } private class EnigmaKillerLevelClue : EnigmaClue { private readonly IRandom rd = IRandom.Instance; public override string Title => Translator.GetString("EnigmaClueLevelTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { int playerLevel = (int)killer.Data.PlayerLevel; switch (base.ClueStage) { case 1: return GetStage1Clue(playerLevel); case 2: if (showStageClue) { return GetStage2Clue(playerLevel); } return GetStage1Clue(playerLevel); case 3: if (showStageClue) { return GetStage3Clue(playerLevel); } if (rd.Next(0, 100) < EnigmaClueStage2Probability.GetInt()) { return GetStage2Clue(playerLevel); } return GetStage1Clue(playerLevel); default: return null; } } private static string GetStage1Clue(int level) { if (level > 50) { return Translator.GetString("EnigmaClueLevel1"); } return Translator.GetString("EnigmaClueLevel2"); } private static string GetStage2Clue(int level) { int num = level - 15; int num2 = level + 15; return string.Format(Translator.GetString("EnigmaClueLevel3"), num, (num2 >= 100) ? 100 : num2); } private static string GetStage3Clue(int level) { return string.Format(Translator.GetString("EnigmaClueLevel4"), level); } } private class EnigmaFriendCodeClue : EnigmaClue { public override string Title => Translator.GetString("EnigmaClueFriendCodeTitle"); public override string GetMessage(PlayerControl killer, bool showStageClue) { string friendCode = killer.Data.FriendCode; return string.Format(Translator.GetString("EnigmaClueFriendCode"), friendCode); } } private enum EnigmaClueType { HatClue, VisorClue, SkinClue, PetClue, NameClue, NameLengthClue, ColorClue, LocationClue, KillerStatusClue, KillerRoleClue, KillerLevelClue, FriendCodeClue } private const int Id = 8100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem EnigmaClueStage1Tasks; private static OptionItem EnigmaClueStage2Tasks; private static OptionItem EnigmaClueStage3Tasks; private static OptionItem EnigmaClueStage2Probability; private static OptionItem EnigmaClueStage3Probability; private static OptionItem EnigmaGetCluesWithoutReporting; private static readonly Dictionary MsgToSend = new Dictionary(); private static readonly Dictionary MsgToSendTitle = new Dictionary(); private static readonly Dictionary> ShownClues = new Dictionary>(); private static readonly List EnigmaClues = new List(24) { new EnigmaHatClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.HatClue }, new EnigmaHatClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.HatClue }, new EnigmaVisorClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.VisorClue }, new EnigmaVisorClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.VisorClue }, new EnigmaSkinClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.SkinClue }, new EnigmaSkinClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.SkinClue }, new EnigmaPetClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.PetClue }, new EnigmaPetClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.PetClue }, new EnigmaNameClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.NameClue }, new EnigmaNameClue { ClueStage = 2, EnigmaClueType = EnigmaClueType.NameClue }, new EnigmaNameClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.NameClue }, new EnigmaNameLengthClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.NameLengthClue }, new EnigmaNameLengthClue { ClueStage = 2, EnigmaClueType = EnigmaClueType.NameLengthClue }, new EnigmaNameLengthClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.NameLengthClue }, new EnigmaColorClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.ColorClue }, new EnigmaColorClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.ColorClue }, new EnigmaLocationClue { ClueStage = 2, EnigmaClueType = EnigmaClueType.LocationClue }, new EnigmaKillerStatusClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.KillerStatusClue }, new EnigmaKillerRoleClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.KillerRoleClue }, new EnigmaKillerRoleClue { ClueStage = 2, EnigmaClueType = EnigmaClueType.KillerRoleClue }, new EnigmaKillerLevelClue { ClueStage = 1, EnigmaClueType = EnigmaClueType.KillerLevelClue }, new EnigmaKillerLevelClue { ClueStage = 2, EnigmaClueType = EnigmaClueType.KillerLevelClue }, new EnigmaKillerLevelClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.KillerLevelClue }, new EnigmaFriendCodeClue { ClueStage = 3, EnigmaClueType = EnigmaClueType.FriendCodeClue } }; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8100, TabGroup.CrewmateRoles, CustomRoles.Enigma); EnigmaClueStage1Tasks = FloatOptionItem.Create(8111, "EnigmaClueStage1Tasks", new FloatValueRule(0f, 10f, 1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]).SetValueFormat(OptionFormat.Times); EnigmaClueStage2Tasks = FloatOptionItem.Create(8112, "EnigmaClueStage2Tasks", new FloatValueRule(0f, 10f, 1f), 3f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]).SetValueFormat(OptionFormat.Times); EnigmaClueStage3Tasks = FloatOptionItem.Create(8113, "EnigmaClueStage3Tasks", new FloatValueRule(0f, 10f, 1f), 7f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]).SetValueFormat(OptionFormat.Times); EnigmaClueStage2Probability = IntegerOptionItem.Create(8114, "EnigmaClueStage2Probability", new IntegerValueRule(0, 100, 5), 75, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]).SetValueFormat(OptionFormat.Percent); EnigmaClueStage3Probability = IntegerOptionItem.Create(8115, "EnigmaClueStage3Probability", new IntegerValueRule(0, 100, 5), 60, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]).SetValueFormat(OptionFormat.Percent); EnigmaGetCluesWithoutReporting = BooleanOptionItem.Create(8116, "EnigmaClueGetCluesWithoutReporting", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Enigma]); Options.OverrideTasksData.Create(8120, TabGroup.CrewmateRoles, CustomRoles.Enigma); } public override void Init() { playerIdList.Clear(); ShownClues.Clear(); MsgToSend.Clear(); MsgToSendTitle.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); ShownClues.Add(playerId, new HashSet()); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); ShownClues.Remove(playerId); } public override void OnReportDeadBody(PlayerControl player, NetworkedPlayerInfo target) { if ((Object)(object)target == (Object)null) { return; } PlayerControl realKillerById = target.PlayerId.GetRealKillerById(); if ((Object)(object)realKillerById == (Object)null) { return; } IRandom instance = IRandom.Instance; byte[] array = playerIdList.ToArray(); foreach (byte playerId in array) { if (!EnigmaGetCluesWithoutReporting.GetBool() && playerId != player.PlayerId) { continue; } PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null) { continue; } int completedTasksCount = playerById.GetPlayerTaskState().CompletedTasksCount; int stage = 0; bool flag = false; if (completedTasksCount >= EnigmaClueStage3Tasks.GetInt()) { stage = 3; flag = instance.Next(0, 100) < EnigmaClueStage3Probability.GetInt(); } else if (completedTasksCount >= EnigmaClueStage2Tasks.GetInt()) { stage = 2; flag = instance.Next(0, 100) < EnigmaClueStage2Probability.GetInt(); } else if (completedTasksCount >= EnigmaClueStage1Tasks.GetInt()) { stage = 1; } List list = EnigmaClues.Where((EnigmaClue a) => a.ClueStage <= stage && !ShownClues[playerId].Any((EnigmaClue b) => b.EnigmaClueType == a.EnigmaClueType && b.ClueStage == a.ClueStage)).ToList(); if (list.Count == 0) { continue; } if (flag && list.Any((EnigmaClue a) => a.ClueStage == stage)) { list = list.Where((EnigmaClue a) => a.ClueStage == stage).ToList(); } EnigmaClue enigmaClue = list.RandomElement(); string title = enigmaClue.Title; string message = enigmaClue.GetMessage(realKillerById, flag); ShownClues[playerId].Add(enigmaClue); if (MsgToSend.ContainsKey(playerId)) { MsgToSend[playerId] = message; } else { MsgToSend.Add(playerId, message); } if (MsgToSendTitle.ContainsKey(playerId)) { MsgToSendTitle[playerId] = title; } else { MsgToSendTitle.Add(playerId, title); } } } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { MsgToSend.Remove(target.PlayerId); MsgToSendTitle.Remove(target.PlayerId); } public override void OnMeetingHudStart(PlayerControl pc) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (MsgToSend.ContainsKey(pc.PlayerId)) { MeetingHudStartPatch.AddMsg(MsgToSend[pc.PlayerId], pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Enigma)), MsgToSendTitle[pc.PlayerId])); } } public override void MeetingHudClear() { MsgToSend.Clear(); } } internal class FortuneTeller : RoleBase { private const int Id = 8000; private static OptionItem CheckLimitOpt; private static OptionItem AccurateCheckMode; private static OptionItem HidesVote; private static OptionItem ShowSpecificRole; private static OptionItem AbilityUseGainWithEachTaskCompleted; private static OptionItem RandomActiveRoles; private readonly HashSet didVote = new HashSet(); private float TempCheckLimit; private readonly HashSet targetList = new HashSet(); public static bool HasEnabled => CustomRoles.FortuneTeller.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8000, TabGroup.CrewmateRoles, CustomRoles.FortuneTeller); CheckLimitOpt = IntegerOptionItem.Create(8010, "FortuneTellerSkillLimit", new IntegerValueRule(0, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]).SetValueFormat(OptionFormat.Times); RandomActiveRoles = BooleanOptionItem.Create(8011, "RandomActiveRoles", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]); AccurateCheckMode = BooleanOptionItem.Create(8012, "AccurateCheckMode", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]); ShowSpecificRole = BooleanOptionItem.Create(8013, "ShowSpecificRole", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]); HidesVote = BooleanOptionItem.Create(8014, "FortuneTellerHideVote", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]); AbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8015, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.FortuneTeller]).SetValueFormat(OptionFormat.Times); Options.OverrideTasksData.Create(8020, TabGroup.CrewmateRoles, CustomRoles.FortuneTeller); } public override void Add(byte playerId) { base.AbilityLimit = CheckLimitOpt.GetInt(); } public void SendRPC(byte playerId, bool isTemp = false, bool voted = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(isTemp); if (!isTemp) { val.Write(playerId); val.Write(base.AbilityLimit); val.Write(voted); } else { val.Write(playerId); val.Write(TempCheckLimit); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { bool num = reader.ReadBoolean(); byte item = reader.ReadByte(); float num2 = reader.ReadSingle(); if (!num) { base.AbilityLimit = num2; if (reader.ReadBoolean() && !didVote.Contains(item)) { didVote.Add(item); } } else { TempCheckLimit = num2; didVote.Remove(item); } } public override bool HideVote(PlayerVoteArea pva) { if (HidesVote.GetBool()) { return TempCheckLimit > 0f; } return false; } private static string GetTargetRoleList(CustomRoles[] roles) { if (roles == null) { return ""; } return string.Join("\n", roles.Select((CustomRoles role) => " ★ " + Utils.GetRoleName(role))); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.Is(CustomRoles.FortuneTeller) && player.IsAlive()) { base.AbilityLimit += AbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPC(player.PlayerId); } return true; } public override void OnVote(PlayerControl player, PlayerControl target) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)target == (Object)null || didVote.Contains(player.PlayerId)) { return; } didVote.Add(player.PlayerId); if (base.AbilityLimit < 1f) { Utils.SendMessage(Translator.GetString("FortuneTellerCheckReachLimit"), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.FortuneTeller)), Translator.GetString("FortuneTellerCheckMsgTitle"))); return; } if (RandomActiveRoles.GetBool() && targetList.Contains(target.PlayerId)) { Utils.SendMessage(Translator.GetString("FortuneTellerAlreadyCheckedMsg") + "\n\n" + string.Format(Translator.GetString("FortuneTellerCheckLimit"), base.AbilityLimit), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.FortuneTeller)), Translator.GetString("FortuneTellerCheckMsgTitle"))); return; } base.AbilityLimit -= 1f; SendRPC(player.PlayerId, isTemp: false, voted: true); if (player.PlayerId == target.PlayerId) { Utils.SendMessage(Translator.GetString("FortuneTellerCheckSelfMsg") + "\n\n" + string.Format(Translator.GetString("FortuneTellerCheckLimit"), base.AbilityLimit), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.FortuneTeller)), Translator.GetString("FortuneTellerCheckMsgTitle"))); return; } string text; if ((player.AllTasksCompleted() || AccurateCheckMode.GetBool()) && ShowSpecificRole.GetBool()) { text = string.Format(Translator.GetString("FortuneTellerCheck.TaskDone"), target.GetRealName(), Translator.GetString(target.GetCustomRole().ToString())); } else if (RandomActiveRoles.GetBool()) { targetList.Add(target.PlayerId); CustomRoles targetRole2 = target.GetCustomRole(); List list = CustomRolesHelper.AllRoles.Where((CustomRoles role) => (role.IsEnable() || role.RoleExist(countDead: true)) && role != targetRole2 && !role.IsAdditionRole()).ToList(); int num = Math.Min(4, list.Count); List list2 = new List(1) { targetRole2 }; IRandom instance = IRandom.Instance; for (int i = 0; i < num; i++) { int index = instance.Next(list.Count); list2.Add(list[index]); list.RemoveAt(index); } int index3; for (int num2 = list2.Count - 1; num2 > 0; num2--) { int num3 = instance.Next(0, num2 + 1); List list3 = list2; int index2 = num3; List list4 = list2; index3 = num2; CustomRoles value = list2[num2]; CustomRoles value2 = list2[num3]; list3[index2] = value; list4[index3] = value2; } index3 = 0; CustomRoles[] array = new CustomRoles[list2.Count]; foreach (CustomRoles item in list2) { array[index3] = item; index3++; } string targetRoleList = GetTargetRoleList(array); text = string.Format(Translator.GetString("FortuneTellerCheck.Result"), target.GetRealName(), targetRoleList); } else { List source = EnumHelper.Achunk(6, shuffle: true, (CustomRoles x) => !x.IsGhostRole() && !x.IsAdditionRole() && x != CustomRoles.NotAssigned); CustomRoles targetRole = target.GetCustomRole(); string empty = string.Empty; empty = GetTargetRoleList(source.FirstOrDefault((CustomRoles[] x) => x.Contains(targetRole))); text = ((!(empty == string.Empty)) ? string.Format(Translator.GetString("FortuneTellerCheck.Result"), target.GetRealName(), empty) : string.Format(Translator.GetString("FortuneTellerCheck.Null"), target.GetRealName())); } Utils.SendMessage(Translator.GetString("FortuneTellerCheck") + "\n" + text + "\n\n" + string.Format(Translator.GetString("FortuneTellerCheckLimit"), base.AbilityLimit), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.FortuneTeller)), Translator.GetString("FortuneTellerCheckMsgTitle"))); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit)}")); return stringBuilder.ToString(); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { didVote.Clear(); TempCheckLimit = base.AbilityLimit; SendRPC(_state.PlayerId, isTemp: true); } } internal class Grenadier : RoleBase { private const int Id = 8200; private static readonly Dictionary GrenadierBlinding = new Dictionary(); private static readonly Dictionary MadGrenadierBlinding = new Dictionary(); private static OptionItem GrenadierSkillCooldown; private static OptionItem GrenadierSkillDuration; private static OptionItem GrenadierCauseVision; private static OptionItem GrenadierCanAffectNeutral; private static OptionItem GrenadierSkillMaxOfUseage; private static OptionItem GrenadierAbilityUseGainWithEachTaskCompleted; public static bool stopGrenadierSkill = false; public static bool stopMadGrenadierSkill = false; public static bool HasEnabled => CustomRoles.Grenadier.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8200, TabGroup.CrewmateRoles, CustomRoles.Grenadier); GrenadierSkillCooldown = FloatOptionItem.Create(8210, "GrenadierSkillCooldown", new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]).SetValueFormat(OptionFormat.Seconds); GrenadierSkillDuration = FloatOptionItem.Create(8211, "GrenadierSkillDuration", new FloatValueRule(1f, 60f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]).SetValueFormat(OptionFormat.Seconds); GrenadierCauseVision = FloatOptionItem.Create(8212, "GrenadierCauseVision", new FloatValueRule(0f, 5f, 0.05f), 0.3f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]).SetValueFormat(OptionFormat.Multiplier); GrenadierCanAffectNeutral = BooleanOptionItem.Create(8213, "GrenadierCanAffectNeutral", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]); GrenadierSkillMaxOfUseage = FloatOptionItem.Create(8214, "GrenadierSkillMaxOfUseage", new FloatValueRule(0f, 20f, 1f), 2f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]).SetValueFormat(OptionFormat.Times); GrenadierAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8215, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Grenadier]).SetValueFormat(OptionFormat.Times); } public override void Init() { GrenadierBlinding.Clear(); MadGrenadierBlinding.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = GrenadierSkillMaxOfUseage.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = GrenadierSkillCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public static void ApplyGameOptionsForOthers(IGameOptions opt, PlayerControl player) { if ((GrenadierBlinding.Any() && (player.GetCustomRole().IsImpostor() || (player.GetCustomRole().IsNeutral() && GrenadierCanAffectNeutral.GetBool()))) || (MadGrenadierBlinding.Any() && !player.GetCustomRole().IsImpostorTeam() && !player.Is(CustomRoles.Madmate))) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, GrenadierCauseVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, GrenadierCauseVision.GetFloat()); } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += GrenadierAbilityUseGainWithEachTaskCompleted.GetFloat(); SendSkillRPC(); } return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { GrenadierBlinding.Clear(); MadGrenadierBlinding.Clear(); } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (!(base.AbilityLimit >= 1f)) { return; } if (pc.Is(CustomRoles.Madmate)) { MadGrenadierBlinding.Remove(pc.PlayerId); MadGrenadierBlinding.Add(pc.PlayerId, Utils.GetTimeStamp()); CollectionExtensions.Do(from x in Main.AllPlayerControls where x.IsModClient() where !x.GetCustomRole().IsImpostorTeam() && !x.Is(CustomRoles.Madmate) select x, (Action)delegate(PlayerControl x) { x.RPCPlayCustomSound("FlashBang"); }); } else { GrenadierBlinding.Remove(pc.PlayerId); GrenadierBlinding.Add(pc.PlayerId, Utils.GetTimeStamp()); CollectionExtensions.Do(from x in Main.AllPlayerControls where x.IsModClient() where x.GetCustomRole().IsImpostor() || (x.GetCustomRole().IsNeutral() && GrenadierCanAffectNeutral.GetBool()) select x, (Action)delegate(PlayerControl x) { x.RPCPlayCustomSound("FlashBang"); }); } if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(pc); } pc.RPCPlayCustomSound("FlashBang"); pc.Notify(Translator.GetString("GrenadierSkillInUse"), GrenadierSkillDuration.GetFloat()); base.AbilityLimit -= 1f; SendSkillRPC(); Utils.MarkEveryoneDirtySettings(); } public override void OnFixedUpdateLowLoad(PlayerControl player) { if (!GrenadierBlinding.ContainsKey(player.PlayerId) && !MadGrenadierBlinding.ContainsKey(player.PlayerId)) { return; } long timeStamp = Utils.GetTimeStamp(); if (GrenadierBlinding.TryGetValue(player.PlayerId, out var value) && value + GrenadierSkillDuration.GetInt() < timeStamp) { GrenadierBlinding.Remove(player.PlayerId); stopGrenadierSkill = true; } if (MadGrenadierBlinding.TryGetValue(player.PlayerId, out var value2) && value2 + GrenadierSkillDuration.GetInt() < timeStamp) { MadGrenadierBlinding.Remove(player.PlayerId); stopMadGrenadierSkill = true; } if (stopGrenadierSkill || stopMadGrenadierSkill) { if (!Options.DisableShieldAnimations.GetBool()) { player.RpcGuardAndKill(); } else { player.RpcResetAbilityCooldown(); } player.Notify(Translator.GetString("GrenadierSkillStop")); Utils.MarkEveryoneDirtySettings(); stopGrenadierSkill = false; stopMadGrenadierSkill = false; } } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("GrenadierVentButtonText"); } } internal class Guardian : RoleBase { private const int Id = 11700; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(11700, TabGroup.CrewmateRoles, CustomRoles.Guardian); Options.OverrideTasksData.Create(11710, TabGroup.CrewmateRoles, CustomRoles.Guardian); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public static bool CannotBeKilled(PlayerControl Guardian) { if (Guardian.Is(CustomRoles.Guardian)) { return Guardian.GetPlayerTaskState().IsTaskFinished; } return false; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (CannotBeKilled(target)) { return false; } return true; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.Guardian && target.GetPlayerTaskState().IsTaskFinished) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessGuardianTask")); return true; } return false; } } internal class GuessMaster : RoleBase { private const int Id = 26800; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(26800, TabGroup.CrewmateRoles, CustomRoles.GuessMaster); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public static void OnGuess(CustomRoles role, bool isMisguess = false, PlayerControl dp = null) { if (!HasEnabled) { return; } foreach (byte gmID in playerIdList) { PlayerControl playerById = Utils.GetPlayerById(gmID); if ((Object)(object)playerById == (Object)null || !playerById.IsAlive()) { continue; } if (isMisguess && (Object)(object)dp != (Object)null) { new LateTask(delegate { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("GuessMasterMisguess"), dp.GetRealName()), gmID, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.GuessMaster)), Translator.GetString("GuessMasterTitle"))); }, 1f, "GuessMaster On Miss Guess"); } else { new LateTask(delegate { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("GuessMasterTargetRole"), Utils.GetRoleName(role)), gmID, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.GuessMaster)), Translator.GetString("GuessMasterTitle"))); }, 1f, "GuessMaster Target Role"); } } } } internal class Inspector : RoleBase { private const int Id = 8300; private static OptionItem TryHideMsg; private static OptionItem InspectCheckLimitMax; private static OptionItem InspectCheckLimitPerMeeting; private static OptionItem InspectCheckTargetKnow; private static OptionItem InspectCheckOtherTargetKnow; private static OptionItem InspectCheckBaitCountTypeOpt; private static OptionItem InspectCheckRevealTargetTeam; private static OptionItem InspectAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary MaxCheckLimit = new Dictionary(); private static readonly Dictionary RoundCheckLimit = new Dictionary(); public static bool HasEnabled => CustomRoles.Inspector.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public static bool CheckBaitCountType => InspectCheckBaitCountTypeOpt.GetBool(); public override void SetupCustomOption() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(8300, TabGroup.CrewmateRoles, CustomRoles.Inspector); TryHideMsg = BooleanOptionItem.Create(8310, "InspectorTryHideMsg", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]).SetColor(Color.green); InspectCheckLimitMax = IntegerOptionItem.Create(8311, "MaxInspectCheckLimit", new IntegerValueRule(0, 20, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]).SetValueFormat(OptionFormat.Times); InspectCheckLimitPerMeeting = IntegerOptionItem.Create(8312, "InspectCheckLimitPerMeeting", new IntegerValueRule(1, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]).SetValueFormat(OptionFormat.Times); InspectCheckBaitCountTypeOpt = BooleanOptionItem.Create(8314, "InspectCheckBaitCountMode", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]); InspectCheckTargetKnow = BooleanOptionItem.Create(8315, "InspectCheckTargetKnow", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]); InspectCheckOtherTargetKnow = BooleanOptionItem.Create(8316, "InspectCheckOtherTargetKnow", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(InspectCheckTargetKnow); InspectCheckRevealTargetTeam = BooleanOptionItem.Create(8317, "InspectCheckRevealTarget", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(InspectCheckOtherTargetKnow); InspectAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8318, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inspector]).SetValueFormat(OptionFormat.Times); Options.OverrideTasksData.Create(8320, TabGroup.CrewmateRoles, CustomRoles.Inspector); } public override void Init() { MaxCheckLimit.Clear(); RoundCheckLimit.Clear(); } public override void Add(byte playerId) { MaxCheckLimit.Add(playerId, InspectCheckLimitMax.GetInt()); RoundCheckLimit.Add(playerId, InspectCheckLimitPerMeeting.GetInt()); } public override void Remove(byte playerId) { MaxCheckLimit.Remove(playerId); RoundCheckLimit.Remove(playerId); } public static void SendRPC(byte playerId, int operate) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)157, (SendOption)1, -1); val.Write(playerId); val.Write(operate); if (operate == 0) { val.Write(RoundCheckLimit[playerId]); } if (operate == 1) { val.Write(RoundCheckLimit[playerId]); val.Write(MaxCheckLimit[playerId]); } if (operate == 3) { val.Write(MaxCheckLimit[playerId]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte key = reader.ReadByte(); int num = reader.ReadInt32(); if (num == 0) { int value = reader.ReadInt32(); RoundCheckLimit[key] = value; } if (num == 1) { int value2 = reader.ReadInt32(); float value3 = reader.ReadSingle(); RoundCheckLimit[key] = value2; MaxCheckLimit[key] = value3; } if (num == 2) { float value4 = reader.ReadSingle(); MaxCheckLimit[key] = value4; } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { MaxCheckLimit[player.PlayerId] += InspectAbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPC(player.PlayerId, 2); } return true; } public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInfo target) { foreach (byte key in RoundCheckLimit.Keys) { RoundCheckLimit[key] = InspectCheckLimitPerMeeting.GetInt(); SendRPC(key, 0); } } public static bool InspectCheckMsg(PlayerControl pc, string msg, bool isUI = false) { string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null || GameStates.IsExilling) { return false; } if (!pc.Is(CustomRoles.Inspector)) { return false; } int num = 0; msg = msg.ToLower().TrimStart().TrimEnd(); if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id|編號|玩家編號")) { num = 1; } else { if (!CheckCommond(ref msg, "compare|cmp|比较|比較", exact: false)) { return false; } num = 2; } if (!pc.IsAlive()) { Utils.SendMessage(Translator.GetString("InspectorDead"), pc.PlayerId); return true; } switch (num) { case 1: Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId); return true; case 2: { if (TryHideMsg.GetBool()) { TryHideMsgForCompare(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var id, out var id2, out var error)) { Utils.SendMessage(error, pc.PlayerId); return true; } PlayerControl target1 = Utils.GetPlayerById(id); PlayerControl target2 = Utils.GetPlayerById(id2); if (!((Object)(object)target1 != (Object)null) || !((Object)(object)target2 != (Object)null)) { break; } Logger.Info($"{pc.GetNameWithRole()} checked {target1.GetNameWithRole()} and {target2.GetNameWithRole()}", "Inspector", escapeCRLF: true, 174, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); if (MaxCheckLimit[pc.PlayerId] < 1f || RoundCheckLimit[pc.PlayerId] < 1) { if (MaxCheckLimit[pc.PlayerId] < 1f) { new LateTask(delegate { pc.ShowInfoMessage(isUI, Translator.GetString("InspectCheckMax")); Logger.Msg("Check attempted at max checks per game", "Inspector", escapeCRLF: true, 183, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 1"); } else { new LateTask(delegate { pc.ShowInfoMessage(isUI, Translator.GetString("InspectCheckRound")); Logger.Msg("Check attempted at max checks per meeting", "Inspector", escapeCRLF: true, 191, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 2"); } return true; } if (pc.PlayerId == target1.PlayerId || pc.PlayerId == target2.PlayerId) { new LateTask(delegate { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) pc.ShowInfoMessage(isUI, Translator.GetString("InspectCheckSelf"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("Check attempted on self", "Inspector", escapeCRLF: true, 201, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 3"); return true; } if (target1.GetCustomRole().IsRevealingRole(target1) || target1.IsAnySubRole((CustomRoles role) => role.IsRevealingRole(target1)) || target2.GetCustomRole().IsRevealingRole(target2) || target2.IsAnySubRole((CustomRoles role) => role.IsRevealingRole(target2))) { new LateTask(delegate { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) pc.ShowInfoMessage(isUI, Translator.GetString("InspectCheckReveal"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("Check attempted on revealed role", "Inspector", escapeCRLF: true, 210, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 4"); return true; } if (((target1.GetCustomRole().IsImpostorTeamV2() || target1.IsAnySubRole((CustomRoles role) => role.IsImpostorTeamV2())) && !target1.Is(CustomRoles.Admired) && (target2.GetCustomRole().IsImpostorTeamV2() || (target2.IsAnySubRole((CustomRoles role) => role.IsImpostorTeamV2()) && !target2.Is(CustomRoles.Admired)))) || ((target1.GetCustomRole().IsNeutralTeamV2() || target1.IsAnySubRole((CustomRoles role) => role.IsNeutralTeamV2())) && !target1.Is(CustomRoles.Admired) && (target2.GetCustomRole().IsNeutralTeamV2() || target2.IsAnySubRole((CustomRoles role) => role.IsNeutralTeamV2())) && !target2.Is(CustomRoles.Admired)) || (((target1.GetCustomRole().IsCrewmateTeamV2() && (target1.GetCustomSubRoles().All((CustomRoles role) => role.IsCrewmateTeamV2()) || target1.GetCustomSubRoles().Count == 0)) || target1.Is(CustomRoles.Admired)) && ((target2.GetCustomRole().IsCrewmateTeamV2() && (target2.GetCustomSubRoles().All((CustomRoles role) => role.IsCrewmateTeamV2()) || target2.GetCustomSubRoles().Count == 0)) || target2.Is(CustomRoles.Admired)))) { new LateTask(delegate { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) pc.ShowInfoMessage(isUI, string.Format(Translator.GetString("InspectCheckTrue"), target1.GetRealName(), target2.GetRealName()), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("Check attempt, result TRUE", "Inspector", escapeCRLF: true, 240, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 5"); } else { new LateTask(delegate { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) pc.ShowInfoMessage(isUI, string.Format(Translator.GetString("InspectCheckFalse"), target1.GetRealName(), target2.GetRealName()), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("Check attempt, result FALSE", "Inspector", escapeCRLF: true, 248, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 6"); } if (InspectCheckTargetKnow.GetBool()) { string textToSend = target1.GetRealName() ?? ""; if (InspectCheckOtherTargetKnow.GetBool()) { textToSend = textToSend + " and " + target2.GetRealName(); } textToSend += Translator.GetString("InspectCheckTargetMsg"); string textToSend2 = target2.GetRealName() ?? ""; if (InspectCheckOtherTargetKnow.GetBool()) { textToSend2 = textToSend2 + " and " + target1.GetRealName(); } textToSend2 += Translator.GetString("InspectCheckTargetMsg"); new LateTask(delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(textToSend, target1.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Utils.SendMessage(textToSend2, target2.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("Check attempt, target1 notified", "Inspector", escapeCRLF: true, 267, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); Logger.Msg("Check attempt, target2 notified", "Inspector", escapeCRLF: true, 268, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.2f, "Inspector Msg 7"); if (InspectCheckRevealTargetTeam.GetBool() && pc.AllTasksCompleted()) { string roleT1 = ""; string roleT2 = ""; if (target1.Is(CustomRoles.Admired)) { roleT1 = "Crewmate"; } else if (target1.GetCustomRole().IsImpostorTeamV2() || target1.IsAnySubRole((CustomRoles role) => role.IsImpostorTeamV2())) { roleT1 = "Impostor"; } else if (target1.GetCustomRole().IsNeutralTeamV2() || target1.IsAnySubRole((CustomRoles role) => role.IsNeutralTeamV2())) { roleT1 = "Neutral"; } else if (target1.GetCustomRole().IsCrewmateTeamV2() && (target1.GetCustomSubRoles().Any((CustomRoles role) => role.IsCrewmateTeamV2()) || target1.GetCustomSubRoles().Count == 0)) { roleT1 = "Crewmate"; } if (target2.Is(CustomRoles.Admired)) { roleT2 = "Crewmate"; } else if (target2.GetCustomRole().IsImpostorTeamV2() || target2.IsAnySubRole((CustomRoles role) => role.IsImpostorTeamV2())) { roleT2 = "Impostor"; } else if (target2.GetCustomRole().IsNeutralTeamV2() || target2.IsAnySubRole((CustomRoles role) => role.IsNeutralTeamV2())) { roleT2 = "Neutral"; } else if (target2.GetCustomRole().IsCrewmateTeamV2() && (target2.GetCustomSubRoles().Any((CustomRoles role) => role.IsCrewmateTeamV2()) || target2.GetCustomSubRoles().Count == 0)) { roleT2 = "Crewmate"; } new LateTask(delegate { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("InspectorTargetReveal"), target2.GetRealName(), roleT2), target1.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Utils.SendMessage(string.Format(Translator.GetString("InspectorTargetReveal"), target1.GetRealName(), roleT1), target2.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), Translator.GetString("InspectCheckTitle"))); Logger.Msg("check attempt, target1 notified target2 as " + roleT2 + " and target2 notified target1 as " + roleT1, "Inspector", escapeCRLF: true, 288, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); }, 0.3f, "Inspector Msg 8"); } } else { if (target1.Is(CustomRoles.Aware)) { if (!Aware.AwareInteracted.ContainsKey(target1.PlayerId)) { Aware.AwareInteracted[target1.PlayerId] = new List(); } if (!Aware.AwareInteracted[target1.PlayerId].Contains(Utils.GetRoleName(CustomRoles.Inspector))) { Aware.AwareInteracted[target1.PlayerId].Add(Utils.GetRoleName(CustomRoles.Inspector)); } } if (target2.Is(CustomRoles.Aware)) { if (!Aware.AwareInteracted.ContainsKey(target2.PlayerId)) { Aware.AwareInteracted[target2.PlayerId] = new List(); } if (!Aware.AwareInteracted[target2.PlayerId].Contains(Utils.GetRoleName(CustomRoles.Inspector))) { Aware.AwareInteracted[target2.PlayerId].Add(Utils.GetRoleName(CustomRoles.Inspector)); } } } MaxCheckLimit[pc.PlayerId] -= 1f; RoundCheckLimit[pc.PlayerId]--; SendRPC(pc.PlayerId, 1); break; } } return true; } private static bool MsgToPlayerAndRole(string msg, out byte id1, out byte id2, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } msg = msg.TrimStart().TrimEnd(); Logger.Msg(msg, "Inspector", escapeCRLF: true, 318, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); string[] array = msg.Split(" "); if (array.Length != 2) { Logger.Msg($"nums length is {array.Length}", "Inspector", escapeCRLF: true, 323, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); id1 = byte.MaxValue; id2 = byte.MaxValue; error = Translator.GetString("InspectCheckHelp"); return false; } if (!int.TryParse(array[0], out var result) || !int.TryParse(array[1], out var result2)) { Logger.Msg($"{array.Length}, nums0 {array[0]}, nums1 {array[1]}", "Inspector", escapeCRLF: true, 331, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Inspector.cs"); id1 = byte.MaxValue; id2 = byte.MaxValue; error = Translator.GetString("InspectCheckHelp"); return false; } id1 = Convert.ToByte(result); id2 = Convert.ToByte(result2); PlayerControl playerById = Utils.GetPlayerById(id1); PlayerControl playerById2 = Utils.GetPlayerById(id2); if ((Object)(object)playerById == (Object)null || playerById.Data.IsDead || (Object)(object)playerById2 == (Object)null || playerById2.Data.IsDead) { error = Translator.GetString("InspectCheckNull"); return false; } error = string.Empty; return true; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg == "/" + text) { return true; } } else if (msg.StartsWith("/" + text)) { msg = msg.Replace("/" + text, string.Empty); return true; } } return false; } private static void TryHideMsgForCompare() { ChatUpdatePatch.DoBlockChat = true; CustomRolesHelper.AllRoles.Where((CustomRoles x) => x != CustomRoles.NotAssigned).ToList(); IRandom instance = IRandom.Instance; string[] array = new string[3] { "cmp", "compare", "比较" }; for (int i = 0; i < 20; i++) { string text = "/"; if (instance.Next(1, 100) < 20) { text += "id"; } else { text += array[instance.Next(0, array.Length - 1)]; text += " "; text += instance.Next(0, 15); text += " "; text += instance.Next(0, 15); } PlayerControl val = Main.AllAlivePlayerControls.RandomElement(); DestroyableSingleton.Instance.Chat.AddChat(val, text, true); CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(text).EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } ChatUpdatePatch.DoBlockChat = false; } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(MaxCheckLimit[playerId] < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(MaxCheckLimit[playerId], 1)}")); return stringBuilder.ToString(); } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!IsForMeeting) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Inspector)), target.PlayerId.ToString()) + " " + TargetPlayerName; } } internal class Investigator : RoleBase { private const int Id = 24900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem InvestigateCooldown; private static OptionItem InvestigateMax; private static OptionItem InvestigateRoundMax; private static readonly Dictionary MaxInvestigateLimit = new Dictionary(); private static readonly Dictionary RoundInvestigateLimit = new Dictionary(); private static readonly Dictionary> InvestigatedList = new Dictionary>(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(24900, TabGroup.CrewmateRoles, CustomRoles.Investigator); InvestigateCooldown = FloatOptionItem.Create(24910, "InvestigateCooldown", new FloatValueRule(0f, 180f, 2.5f), 27.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Investigator]).SetValueFormat(OptionFormat.Seconds); InvestigateMax = IntegerOptionItem.Create(24911, "InvestigateMax", new IntegerValueRule(1, 15, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Investigator]).SetValueFormat(OptionFormat.Times); InvestigateRoundMax = IntegerOptionItem.Create(24912, "InvestigateRoundMax", new IntegerValueRule(1, 15, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Investigator]).SetValueFormat(OptionFormat.Times); } public override void Init() { playerIdList.Clear(); InvestigatedList.Clear(); MaxInvestigateLimit.Clear(); RoundInvestigateLimit.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); MaxInvestigateLimit[playerId] = InvestigateMax.GetInt(); RoundInvestigateLimit[playerId] = InvestigateRoundMax.GetInt(); InvestigatedList[playerId] = new HashSet(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); MaxInvestigateLimit.Remove(playerId); RoundInvestigateLimit.Remove(playerId); InvestigatedList.Remove(playerId); } private static void SendRPC(int operate, byte playerId = byte.MaxValue, byte targetId = byte.MaxValue) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)179, (SendOption)1, -1); val.Write(operate); if (operate == 0) { val.Write(playerId); val.Write(targetId); val.Write(MaxInvestigateLimit[playerId]); val.Write(RoundInvestigateLimit[playerId]); } else { ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader) { int num = reader.ReadInt32(); if (num == 0) { byte key = reader.ReadByte(); byte item = reader.ReadByte(); if (!InvestigatedList.ContainsKey(key)) { InvestigatedList[key] = new HashSet(); } InvestigatedList[key].Add(item); int value = reader.ReadInt32(); MaxInvestigateLimit[key] = value; int value2 = reader.ReadInt32(); MaxInvestigateLimit[key] = value2; } if (num != 1) { return; } foreach (byte key2 in RoundInvestigateLimit.Keys) { RoundInvestigateLimit[key2] = InvestigateRoundMax.GetInt(); InvestigatedList[key2] = new HashSet(); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = InvestigateCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl player) { if ((Object)(object)player == (Object)null) { return false; } byte playerId = player.PlayerId; if (!MaxInvestigateLimit.ContainsKey(playerId)) { MaxInvestigateLimit[playerId] = InvestigateMax.GetInt(); } if (!RoundInvestigateLimit.ContainsKey(playerId)) { RoundInvestigateLimit[playerId] = InvestigateRoundMax.GetInt(); } if (!player.Data.IsDead && MaxInvestigateLimit[player.PlayerId] >= 1) { return RoundInvestigateLimit[player.PlayerId] >= 1; } return false; } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (!MaxInvestigateLimit.ContainsKey(killer.PlayerId)) { MaxInvestigateLimit[killer.PlayerId] = InvestigateMax.GetInt(); } if (!RoundInvestigateLimit.ContainsKey(killer.PlayerId)) { RoundInvestigateLimit[killer.PlayerId] = InvestigateRoundMax.GetInt(); } if (MaxInvestigateLimit[killer.PlayerId] < 1 || RoundInvestigateLimit[killer.PlayerId] < 1) { return false; } MaxInvestigateLimit[killer.PlayerId]--; RoundInvestigateLimit[killer.PlayerId]--; if (!InvestigatedList.ContainsKey(killer.PlayerId)) { InvestigatedList[killer.PlayerId] = new HashSet(); } InvestigatedList[killer.PlayerId].Add(target.PlayerId); SendRPC(0, killer.PlayerId, target.PlayerId); Utils.NotifyRoles(killer); killer.ResetKillCooldown(); killer.SetKillCooldown(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } return false; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if ((Object)(object)seer == (Object)null || (Object)(object)target == (Object)null) { return string.Empty; } if (!InvestigatedList.TryGetValue(seer.PlayerId, out var value)) { return string.Empty; } if (!value.Contains(target.PlayerId)) { return string.Empty; } if (target.HasKillButton() || CopyCat.playerIdList.Contains(target.PlayerId)) { return "#FF1919"; } return "#8CFFFF"; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { foreach (byte key in RoundInvestigateLimit.Keys) { RoundInvestigateLimit[key] = InvestigateRoundMax.GetInt(); InvestigatedList[key] = new HashSet(); } SendRPC(1); } public override string GetProgressText(byte playerId, bool comms) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((MaxInvestigateLimit[playerId] >= 1) ? Utils.GetRoleColor(CustomRoles.Investigator).ShadeColor(0.25f) : Color.gray), $"({MaxInvestigateLimit[playerId]})"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("InvestigatorButtonText")); } } internal class Jailer : RoleBase { private const int Id = 10600; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem JailCooldown; private static OptionItem MaxExecution; private static OptionItem NBCanBeExe; private static OptionItem NCCanBeExe; private static OptionItem NECanBeExe; private static OptionItem NKCanBeExe; private static OptionItem CKCanBeExe; private static OptionItem NotifyJailedOnMeetingOpt; private static readonly Dictionary JailerTarget = new Dictionary(); private static readonly Dictionary JailerExeLimit = new Dictionary(); private static readonly Dictionary JailerHasExe = new Dictionary(); private static readonly Dictionary JailerDidVote = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(10600, TabGroup.CrewmateRoles, CustomRoles.Jailer); JailCooldown = FloatOptionItem.Create(10610, "JailerJailCooldown", new FloatValueRule(0f, 999f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]).SetValueFormat(OptionFormat.Seconds); MaxExecution = IntegerOptionItem.Create(10611, "JailerMaxExecution", new IntegerValueRule(1, 14, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]).SetValueFormat(OptionFormat.Times); NBCanBeExe = BooleanOptionItem.Create(10612, "JailerNBCanBeExe", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); NCCanBeExe = BooleanOptionItem.Create(10613, "JailerNCCanBeExe", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); NECanBeExe = BooleanOptionItem.Create(10614, "JailerNECanBeExe", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); NKCanBeExe = BooleanOptionItem.Create(10615, "JailerNKCanBeExe", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); CKCanBeExe = BooleanOptionItem.Create(10616, "JailerCKCanBeExe", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); NotifyJailedOnMeetingOpt = BooleanOptionItem.Create(10618, "notifyJailedOnMeeting", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Jailer]); } public override void Init() { playerIdList.Clear(); JailerExeLimit.Clear(); JailerTarget.Clear(); JailerHasExe.Clear(); JailerDidVote.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); JailerExeLimit.Add(playerId, MaxExecution.GetInt()); JailerTarget.Add(playerId, byte.MaxValue); JailerHasExe.Add(playerId, value: false); JailerDidVote.Add(playerId, value: false); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); JailerExeLimit.Remove(playerId); JailerHasExe.Remove(playerId); JailerDidVote.Remove(playerId); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public static bool IsTarget(byte playerId) { return JailerTarget.ContainsValue(playerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (Utils.GetPlayerById(id).IsAlive() ? JailCooldown.GetFloat() : 300f); } public override string GetProgressText(byte playerId, bool cooms) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer).ShadeColor(0.25f)), JailerExeLimit.TryGetValue(playerId, out value) ? $"({value})" : "Invalid"); } public static void SendRPC(byte jailerId, byte targetId = byte.MaxValue, bool setTarget = true) { if (!setTarget) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)156, (SendOption)1, -1); val.Write(jailerId); val.Write(JailerExeLimit[jailerId]); val.Write(JailerHasExe[jailerId]); val.Write(JailerDidVote[jailerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)155, (SendOption)1, -1); val.Write(jailerId); val.Write(targetId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader, bool setTarget = true) { byte key = reader.ReadByte(); if (!setTarget) { int value = reader.ReadInt32(); if (JailerExeLimit.ContainsKey(key)) { JailerExeLimit[key] = value; } else { JailerExeLimit.Add(key, MaxExecution.GetInt()); } bool value2 = reader.ReadBoolean(); if (JailerHasExe.ContainsKey(key)) { JailerHasExe[key] = value2; } else { JailerHasExe.Add(key, value: false); } bool value3 = reader.ReadBoolean(); if (JailerDidVote.ContainsKey(key)) { JailerDidVote[key] = value3; } else { JailerDidVote.Add(key, value: false); } } else { byte value4 = reader.ReadByte(); JailerTarget[key] = value4; } } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (JailerTarget[killer.PlayerId] != byte.MaxValue) { killer.Notify(Translator.GetString("JailerTargetAlreadySelected")); return false; } JailerTarget[killer.PlayerId] = target.PlayerId; killer.Notify(Translator.GetString("SuccessfullyJailed")); killer.ResetKillCooldown(); killer.SetKillCooldown(); SendRPC(killer.PlayerId, target.PlayerId); return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override void OnReportDeadBody(PlayerControl sob, NetworkedPlayerInfo bakugan) { foreach (byte targetId in JailerTarget.Values) { if (targetId == byte.MaxValue) { continue; } PlayerControl playerById = Utils.GetPlayerById(targetId); if ((Object)(object)playerById == (Object)null || !NotifyJailedOnMeetingOpt.GetBool() || !playerById.IsAlive()) { continue; } new LateTask(delegate { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsInGame) { Utils.SendMessage(Translator.GetString("JailedNotifyMsg"), targetId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), Translator.GetString("JailerTitle"))); } }, 5f, $"Jailer Notify Jailed - id:{targetId}"); } } public override void OnVote(PlayerControl voter, PlayerControl target) { if ((Object)(object)voter == (Object)null || (Object)(object)target == (Object)null || !voter.Is(CustomRoles.Jailer) || (JailerDidVote.TryGetValue(voter.PlayerId, out var value) && value) || (JailerTarget.TryGetValue(voter.PlayerId, out var value2) && value2 == byte.MaxValue)) { return; } JailerDidVote[voter.PlayerId] = true; if (target.PlayerId == JailerTarget[voter.PlayerId]) { if (JailerExeLimit[voter.PlayerId] > 0) { JailerExeLimit[voter.PlayerId] = JailerExeLimit[voter.PlayerId] - 1; JailerHasExe[voter.PlayerId] = true; } else { JailerHasExe[voter.PlayerId] = false; } } SendRPC(voter.PlayerId, byte.MaxValue, setTarget: false); } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!(JailerTarget.TryGetValue(seer.PlayerId, out var value) && isForMeeting) || !((Object)(object)seer != (Object)(object)seen) || seen.PlayerId != value) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), "⊠"); } private static bool CanBeExecuted(CustomRoles role) { if ((!role.IsNB() || !NBCanBeExe.GetBool()) && (!role.IsNC() || !NCCanBeExe.GetBool()) && (!role.IsNE() || !NECanBeExe.GetBool()) && (!role.IsNK() || !NKCanBeExe.GetBool()) && (!role.IsCrewKiller() || !CKCanBeExe.GetBool())) { return role.IsImpostorTeamV3(); } return true; } public override void AfterMeetingTasks() { foreach (byte key in JailerHasExe.Keys) { byte b = JailerTarget[key]; if (b != byte.MaxValue && JailerHasExe[key]) { PlayerControl playerById = Utils.GetPlayerById(b); if (playerById.IsAlive()) { CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Execution, b); playerById.SetRealKiller(Utils.GetPlayerById(key)); } if (!CanBeExecuted(playerById.GetCustomRole())) { JailerExeLimit[key] = 0; SendRPC(key, byte.MaxValue, setTarget: false); } } JailerHasExe[key] = false; JailerTarget[key] = byte.MaxValue; JailerDidVote[key] = false; SendRPC(key); } } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("JailorKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("penitentiary"); } } internal class Judge : RoleBase { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { if (PlayerControl.LocalPlayer.Is(CustomRoles.Judge) && PlayerControl.LocalPlayer.IsAlive()) { CreateJudgeButton(__instance); } } } private const int Id = 10700; private static readonly HashSet playerIdList = new HashSet(); public static OptionItem TrialLimitPerMeeting; private static OptionItem TryHideMsg; private static OptionItem CanTrialMadmate; private static OptionItem CanTrialCharmed; private static OptionItem CanTrialSidekick; private static OptionItem CanTrialInfected; private static OptionItem CanTrialContagious; private static OptionItem CanTrialCrewKilling; private static OptionItem CanTrialNeutralB; private static OptionItem CanTrialNeutralK; private static OptionItem CanTrialNeutralE; private static OptionItem CanTrialNeutralC; private static readonly Dictionary TrialLimit = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { //IL_0205: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(10700, TabGroup.CrewmateRoles, CustomRoles.Judge); TrialLimitPerMeeting = IntegerOptionItem.Create(10710, "JudgeTrialLimitPerMeeting", new IntegerValueRule(1, 30, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]).SetValueFormat(OptionFormat.Times); CanTrialMadmate = BooleanOptionItem.Create(10712, "JudgeCanTrialMadmate", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialCharmed = BooleanOptionItem.Create(10716, "JudgeCanTrialCharmed", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialSidekick = BooleanOptionItem.Create(10719, "JudgeCanTrialSidekick", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialInfected = BooleanOptionItem.Create(10720, "JudgeCanTrialInfected", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialContagious = BooleanOptionItem.Create(10721, "JudgeCanTrialContagious", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialCrewKilling = BooleanOptionItem.Create(10713, "JudgeCanTrialnCrewKilling", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialNeutralB = BooleanOptionItem.Create(10714, "JudgeCanTrialNeutralB", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialNeutralE = BooleanOptionItem.Create(10717, "JudgeCanTrialNeutralE", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialNeutralC = BooleanOptionItem.Create(10718, "JudgeCanTrialNeutralC", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); CanTrialNeutralK = BooleanOptionItem.Create(10715, "JudgeCanTrialNeutralK", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]); TryHideMsg = BooleanOptionItem.Create(10711, "JudgeTryHideMsg", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Judge]).SetColor(Color.green); } public override void Init() { playerIdList.Clear(); TrialLimit.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); TrialLimit.Add(playerId, TrialLimitPerMeeting.GetInt()); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); TrialLimit.Remove(playerId); } public override void OnReportDeadBody(PlayerControl party, NetworkedPlayerInfo dinosaur) { foreach (byte key in TrialLimit.Keys) { TrialLimit[key] = TrialLimitPerMeeting.GetInt(); } } public static bool TrialMsg(PlayerControl pc, string msg, bool isUI = false) { //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null || GameStates.IsExilling) { return false; } if (!pc.Is(CustomRoles.Judge)) { return false; } int num = 0; msg = msg.ToLower().TrimStart().TrimEnd(); if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id||編號|玩家編號")) { num = 1; } else { if (!CheckCommond(ref msg, "sp|jj|tl|trial|审判|判|审|審判|審", exact: false)) { return false; } num = 2; } if (!pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("JudgeDead")); return true; } switch (num) { case 1: Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId); return true; case 2: { if (TryHideMsg.GetBool()) { GuessManager.TryHideMsg(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var id, out var error)) { Utils.SendMessage(error, pc.PlayerId); return true; } PlayerControl playerById = Utils.GetPlayerById(id); if (!((Object)(object)playerById != (Object)null)) { break; } Logger.Info(pc.GetNameWithRole() + " try trial " + playerById.GetNameWithRole(), "Judge", escapeCRLF: true, 123, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Judge.cs"); bool flag = true; if (TrialLimit[pc.PlayerId] < 1) { pc.ShowInfoMessage(isUI, Translator.GetString("JudgeTrialMax")); return true; } if (Jailer.IsTarget(playerById.PlayerId)) { pc.ShowInfoMessage(isUI, Translator.GetString("CanNotTrialJailed"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Jailer)), Translator.GetString("JailerTitle"))); return true; } if (pc.PlayerId == playerById.PlayerId) { pc.ShowInfoMessage(isUI, Translator.GetString("Judge_LaughToWhoTrialSelf"), Utils.ColorString(Color32.op_Implicit(Color.cyan), Translator.GetString("MessageFromKPD"))); } else { if (playerById.Is(CustomRoles.NiceMini) && Mini.Age < 18) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessMini")); return true; } if (playerById.Is(CustomRoles.PunchingBag)) { pc.ShowInfoMessage(isUI, Translator.GetString("EradicatePunchingBag")); return true; } if (playerById.Is(CustomRoles.Rebound)) { Logger.Info(pc.GetNameWithRole() + " judged " + playerById.GetNameWithRole() + ", judge sucide = true because target rebound", "JudgeTrialMsg", escapeCRLF: true, 153, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Judge.cs"); flag = true; } else { if (playerById.Is(CustomRoles.Solsticer)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSolsticer")); return true; } if (playerById.Is(CustomRoles.Pestilence)) { flag = true; } else if (playerById.Is(CustomRoles.Trickster)) { flag = true; } else { if (Medic.ProtectList.Contains(playerById.PlayerId) && !Medic.GuesserIgnoreShield.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessShielded")); return true; } if (Guardian.CannotBeKilled(playerById)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessGuardianTask")); return true; } if (pc.IsAnySubRole((CustomRoles x) => x.IsConverted())) { flag = false; } else if (playerById.Is(CustomRoles.Rascal)) { flag = false; } else if ((playerById.Is(CustomRoles.Sidekick) || playerById.Is(CustomRoles.Recruit)) && CanTrialSidekick.GetBool()) { flag = false; } else if ((playerById.GetCustomRole().IsMadmate() || playerById.Is(CustomRoles.Madmate)) && CanTrialMadmate.GetBool()) { flag = false; } else if (playerById.Is(CustomRoles.Infected) && CanTrialInfected.GetBool()) { flag = false; } else if (playerById.Is(CustomRoles.Contagious) && CanTrialContagious.GetBool()) { flag = false; } else if (playerById.Is(CustomRoles.Charmed) && CanTrialCharmed.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsCrewKiller() && CanTrialCrewKilling.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsNK() && CanTrialNeutralK.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsNB() && CanTrialNeutralB.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsNE() && CanTrialNeutralE.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsNC() && CanTrialNeutralC.GetBool()) { flag = false; } else if (playerById.GetCustomRole().IsImpostor()) { flag = false; } else { Logger.Warn("Impossibe to reach here!", "JudgeTrial", escapeCRLF: true, 188, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Judge.cs"); flag = true; } } } } PlayerControl dp = (flag ? pc : playerById); playerById = dp; string Name = dp.GetRealName(); TrialLimit[pc.PlayerId]--; if (GameStates.IsProceeding) { break; } new LateTask(delegate { dp.SetDeathReason(PlayerState.DeathReason.Trialed); dp.SetRealKiller(pc); dp.RpcGuesserMurderPlayer(); Main.PlayersDiedInMeeting.Add(dp.PlayerId); MurderPlayerPatch.AfterPlayerDeathTasks(pc, dp, inMeeting: true); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); new LateTask(delegate { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("Judge_TrialKill"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Judge)), Translator.GetString("Judge_TrialKillTitle")), logforChatManager: true); }, 0.6f, "Guess Msg"); }, 0.2f, "Trial Kill"); break; } } return true; } private static bool MsgToPlayerAndRole(string msg, out byte id, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } MatchCollection matchCollection = new Regex("\\d+").Matches(msg); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { text += matchCollection[i]; } if (int.TryParse(text, out var result)) { id = Convert.ToByte(result); PlayerControl playerById = Utils.GetPlayerById(id); if ((Object)(object)playerById == (Object)null || playerById.Data.IsDead) { error = Translator.GetString("Judge_TrialNull"); return false; } error = string.Empty; return true; } id = byte.MaxValue; error = Translator.GetString("Judge_TrialHelp"); return false; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg == "/" + text) { return true; } } else if (msg.StartsWith("/" + text)) { msg = msg.Replace("/" + text, string.Empty); return true; } } return false; } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)118, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC_Custom(MessageReader reader, PlayerControl pc) { int value = reader.ReadByte(); TrialMsg(pc, $"/tl {value}", isUI: true); } private static void JudgeOnClick(byte playerId) { Logger.Msg($"Click: ID {playerId}", "Judge UI", escapeCRLF: true, 292, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Judge.cs"); PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && GameStates.IsVoting) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { TrialMsg(PlayerControl.LocalPlayer, $"/tl {playerId}", isUI: true); } else { SendRPC(playerId); } } } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!IsForMeeting || !seer.IsAlive() || !target.IsAlive()) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Judge)), target.PlayerId.ToString()) + " " + TargetPlayerName; } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Judge)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public static void CreateJudgeButton(MeetingHud __instance) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) foreach (PlayerVoteArea pva in (Il2CppArrayBase)(object)__instance.playerStates) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); obj.GetComponent().sprite = CustomButton.Get("JudgeIcon"); PassiveButton component = obj.GetComponent(); ((UnityEventBase)component.OnClick).RemoveAllListeners(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { JudgeOnClick(pva.TargetPlayerId); })); } } } } internal class Keeper : RoleBase { private const int Id = 26500; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem KeeperUsesOpt; private static OptionItem HidesVote; private static readonly HashSet keeperTarget = new HashSet(); private static readonly Dictionary keeperUses = new Dictionary(); private static readonly Dictionary DidVote = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(26500, TabGroup.CrewmateRoles, CustomRoles.Keeper); KeeperUsesOpt = IntegerOptionItem.Create(26510, "MaxProtections", new IntegerValueRule(1, 14, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Keeper]).SetValueFormat(OptionFormat.Times); HidesVote = BooleanOptionItem.Create(26511, "KeeperHideVote", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Keeper]); } public override void Init() { playerIdList.Clear(); keeperTarget.Clear(); keeperUses.Clear(); DidVote.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); DidVote.Add(playerId, value: false); keeperUses[playerId] = 0; } public override void Remove(byte playerId) { playerIdList.Remove(playerId); DidVote.Remove(playerId); keeperUses.Remove(playerId); } public override bool HideVote(PlayerVoteArea pva) { if (HidesVote.GetBool()) { return keeperUses[pva.TargetPlayerId] > 0; } return false; } public override string GetProgressText(byte playerId, bool comms) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) if (playerId == byte.MaxValue) { return string.Empty; } if (!keeperUses.ContainsKey(playerId)) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); int num = Math.Max(KeeperUsesOpt.GetInt() - keeperUses[playerId], 0); Color val3 = ((num >= 1) ? Utils.GetRoleColor(CustomRoles.Keeper) : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {num}")); return stringBuilder.ToString(); } private static void SendRPC(int type, byte keeperId = byte.MaxValue, byte targetId = byte.MaxValue) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)158, (SendOption)1, -1); val.Write(type); if (type == 0) { val.Write(keeperId); val.Write(keeperUses[keeperId]); val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { switch (reader.ReadInt32()) { case 0: { byte key = reader.ReadByte(); DidVote[key] = true; int value = reader.ReadInt32(); keeperUses[key] = value; byte item = reader.ReadByte(); if (!keeperTarget.Contains(item)) { keeperTarget.Add(item); } break; } case 1: foreach (byte key2 in DidVote.Keys) { DidVote[key2] = false; } keeperTarget.Clear(); break; } } public static bool OnVotes(PlayerControl voter, PlayerControl target) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if (!CustomRoles.Keeper.HasEnabled()) { return true; } if ((Object)(object)voter == (Object)null || (Object)(object)target == (Object)null) { return true; } if (!voter.Is(CustomRoles.Keeper)) { return true; } if (DidVote[voter.PlayerId]) { return true; } DidVote[voter.PlayerId] = true; if (keeperTarget.Contains(target.PlayerId)) { return true; } if (keeperUses[voter.PlayerId] >= KeeperUsesOpt.GetInt()) { return true; } keeperUses[voter.PlayerId]++; keeperTarget.Add(target.PlayerId); Logger.Info(voter.GetNameWithRole() + " chosen as keeper target by " + target.GetNameWithRole(), "Keeper", escapeCRLF: true, 131, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Keeper.cs"); SendRPC(0, voter.PlayerId, target.PlayerId); Utils.SendMessage(string.Format(Translator.GetString("KeeperProtect"), target.GetRealName()), voter.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Keeper)), Translator.GetString("KeeperTitle"))); return false; } public override void AfterMeetingTasks() { foreach (byte key in DidVote.Keys) { DidVote[key] = false; } keeperTarget.Clear(); SendRPC(1); } public static bool IsTargetExiled(byte exileId) { return keeperTarget.Contains(exileId); } } internal class Knight : RoleBase { private const int Id = 10800; private static OptionItem CanVent; private static OptionItem KillCooldown; public static bool HasEnabled => CustomRoles.Knight.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(10800, TabGroup.CrewmateRoles, CustomRoles.Knight); KillCooldown = FloatOptionItem.Create(10810, GeneralOption.KillCooldown, new FloatValueRule(0f, 60f, 2.5f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Knight]).SetValueFormat(OptionFormat.Seconds); CanVent = BooleanOptionItem.Create(10811, GeneralOption.CanVent, defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Knight]); } public override void Add(byte playerId) { base.AbilityLimit = 1f; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public static bool CheckCanUseVent(PlayerControl player) { if (player.Is(CustomRoles.Knight)) { return CanVent.GetBool(); } return false; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return CheckCanUseVent(pc); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (IsKilled(id) ? 300f : KillCooldown.GetFloat()); } public override bool CanUseKillButton(PlayerControl pc) { return !IsKilled(pc.PlayerId); } public override string GetProgressText(byte id, bool comms) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((!IsKilled(id)) ? Utils.GetRoleColor(CustomRoles.Knight).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } private bool IsKilled(byte playerId) { return base.AbilityLimit <= 0f; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl banana) { base.AbilityLimit--; SendSkillRPC(); Logger.Info(killer.GetNameWithRole() + " : Kill chance used", "Knight", escapeCRLF: true, 50, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Knight.cs"); killer.ResetKillCooldown(); killer.SetKillCooldown(); return true; } } internal class LazyGuy : RoleBase { private const int Id = 6800; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(6800, TabGroup.CrewmateRoles, CustomRoles.LazyGuy); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } } internal class Lighter : RoleBase { private const int Id = 8400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem LighterVisionNormal; private static OptionItem LighterVisionOnLightsOut; private static OptionItem LighterSkillCooldown; private static OptionItem LighterSkillDuration; private static OptionItem LighterSkillMaxOfUseage; private static OptionItem LighterAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary Timer = new Dictionary(); private static readonly Dictionary LighterNumOfUsed = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(8400, TabGroup.CrewmateRoles, CustomRoles.Lighter); LighterSkillCooldown = FloatOptionItem.Create(8410, "LighterSkillCooldown", new FloatValueRule(1f, 180f, 1f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Seconds); LighterSkillDuration = FloatOptionItem.Create(8411, "LighterSkillDuration", new FloatValueRule(1f, 180f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Seconds); LighterVisionNormal = FloatOptionItem.Create(8412, "LighterVisionNormal", new FloatValueRule(0f, 5f, 0.05f), 1.35f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Multiplier); LighterVisionOnLightsOut = FloatOptionItem.Create(8413, "LighterVisionOnLightsOut", new FloatValueRule(0f, 5f, 0.05f), 0.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Multiplier); LighterSkillMaxOfUseage = IntegerOptionItem.Create(8414, "AbilityUseLimit", new IntegerValueRule(0, 180, 1), 4, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Times); LighterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8415, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]).SetValueFormat(OptionFormat.Times); } public override void Init() { playerIdList.Clear(); Timer.Clear(); LighterNumOfUsed.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); LighterNumOfUsed.Add(playerId, LighterSkillMaxOfUseage.GetInt()); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); LighterNumOfUsed.Remove(playerId); } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if (Timer.TryGetValue(pc.PlayerId, out var value) && value + LighterSkillDuration.GetInt() < Utils.GetTimeStamp()) { Timer.Remove(pc.PlayerId); if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(); } else { pc.RpcResetAbilityCooldown(); } pc.Notify(Translator.GetString("LighterSkillStop")); pc.MarkDirtySettings(); } } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (LighterNumOfUsed[pc.PlayerId] >= 1f) { Timer.Remove(pc.PlayerId); Timer.Add(pc.PlayerId, Utils.GetTimeStamp()); if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(pc); } pc.Notify(Translator.GetString("LighterSkillInUse"), LighterSkillDuration.GetFloat()); LighterNumOfUsed[pc.PlayerId] -= 1f; pc.MarkDirtySettings(); } else { pc.Notify(Translator.GetString("OutOfAbilityUsesDoMoreTasks")); } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { Timer.Clear(); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(LighterNumOfUsed[playerId] < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(LighterNumOfUsed[playerId], 1)}")); return stringBuilder.ToString(); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { LighterNumOfUsed[player.PlayerId] += LighterAbilityUseGainWithEachTaskCompleted.GetFloat(); } return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerInVentMaxTime = 1f; AURoleOptions.EngineerCooldown = LighterSkillCooldown.GetFloat(); if (Timer.Any()) { opt.SetVision(HasImpVision: false); if (Utils.IsActive((SystemTypes)7)) { opt.SetFloat((FloatOptionNames)4, LighterVisionOnLightsOut.GetFloat() * 5f); } else { opt.SetFloat((FloatOptionNames)4, LighterVisionNormal.GetFloat()); } } } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("LighterVentButtonText"); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Lighter"); } } internal class Lookout : RoleBase { private const int Id = 11800; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(11800, TabGroup.CrewmateRoles, CustomRoles.Lookout); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !seen.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Lookout)), $" {seen.Data.PlayerId}"); } } internal class Marshall : RoleBase { private const int Id = 11900; private static readonly HashSet playerIdList = new HashSet(); private static readonly Color RoleColor = Utils.GetRoleColor(CustomRoles.Marshall); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(11900, TabGroup.CrewmateRoles, CustomRoles.Marshall); Options.OverrideTasksData.Create(11910, TabGroup.CrewmateRoles, CustomRoles.Marshall); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } private static bool GetExpose(PlayerControl pc) { if (!pc.IsAlive() || pc.Is(CustomRoles.Madmate)) { return false; } if (pc.Is(CustomRoles.Marshall)) { return pc.GetPlayerTaskState().IsTaskFinished; } return false; } private static bool IsMarshallTarget(PlayerControl seer) { if (CustomRoles.Marshall.HasEnabled()) { return seer.Is(Custom_Team.Crewmate); } return false; } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (target == null) { target = seer; } if (!IsMarshallTarget(seer) || !GetExpose(target)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(RoleColor), "★"); } private static bool VisibleToCrewmate(PlayerControl seer, PlayerControl target) { if (target.GetPlayerTaskState().IsTaskFinished && target.Is(CustomRoles.Marshall)) { return seer.Is(Custom_Team.Crewmate); } return false; } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return VisibleToCrewmate(seer, target); } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return VisibleToCrewmate(seer, target); } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (target.GetPlayerTaskState().IsTaskFinished) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessMarshallTask")); return true; } return false; } } internal class Mayor : RoleBase { private const int Id = 12000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem MayorAdditionalVote; private static OptionItem MayorHasPortableButton; private static OptionItem MayorNumOfUseButton; private static OptionItem MayorHideVote; private static OptionItem MayorRevealWhenDoneTasks; private static readonly Dictionary MayorUsedButtonCount = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase { get { if (!MayorHasPortableButton.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Collective"); } public override void SetupCustomOption() { Options.SetupRoleOptions(12000, TabGroup.CrewmateRoles, CustomRoles.Mayor); MayorAdditionalVote = IntegerOptionItem.Create(12010, "MayorAdditionalVote", new IntegerValueRule(1, 20, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mayor]).SetValueFormat(OptionFormat.Votes); MayorHasPortableButton = BooleanOptionItem.Create(12011, "MayorHasPortableButton", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mayor]); MayorNumOfUseButton = IntegerOptionItem.Create(12012, "MayorNumOfUseButton", new IntegerValueRule(1, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(MayorHasPortableButton).SetValueFormat(OptionFormat.Times); MayorHideVote = BooleanOptionItem.Create(12013, GeneralOption.HideAdditionalVotes, defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mayor]); MayorRevealWhenDoneTasks = BooleanOptionItem.Create(12014, "MayorRevealWhenDoneTasks", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mayor]); Options.OverrideTasksData.Create(12015, TabGroup.CrewmateRoles, CustomRoles.Mayor); } public override void Init() { playerIdList.Clear(); MayorUsedButtonCount.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); MayorUsedButtonCount[playerId] = 0; } public override void Remove(byte playerId) { playerIdList.Remove(playerId); MayorUsedButtonCount[playerId] = 0; } public override int AddRealVotesNum(PlayerVoteArea PVA) { return MayorAdditionalVote.GetInt(); } public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!MayorHideVote.GetBool()) { for (int i = 0; (float)i < MayorAdditionalVote.GetFloat(); i++) { statesList.Add(new VoterState { VoterId = votedPlayer.TargetPlayerId, VotedForId = votedPlayer.VotedFor }); } } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = ((!MayorUsedButtonCount.TryGetValue(playerId, out var value) || value < MayorNumOfUseButton.GetInt()) ? ((float)opt.GetInt((Int32OptionNames)4)) : 300f); AURoleOptions.EngineerInVentMaxTime = 1f; } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (!MayorHasPortableButton.GetBool() || CopyCat.playerIdList.Contains(pc.PlayerId) || !MayorUsedButtonCount.TryGetValue(pc.PlayerId, out var value) || value >= MayorNumOfUseButton.GetInt()) { return; } MayorUsedButtonCount[pc.PlayerId]++; if (pc != null) { PlayerPhysics myPhysics = pc.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(vent.Id); } } pc?.NoCheckStartMeeting(null); } public override bool CheckBootFromVent(PlayerPhysics physics, int ventId) { if (MayorUsedButtonCount.TryGetValue(physics.myPlayer.PlayerId, out var value)) { return value >= MayorNumOfUseButton.GetInt(); } return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (MayorRevealWhenDoneTasks.GetBool() && target.GetPlayerTaskState().IsTaskFinished) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessMayor")); return true; } return false; } public static bool VisibleToEveryone(PlayerControl target) { if (target.Is(CustomRoles.Mayor) && MayorRevealWhenDoneTasks.GetBool()) { return target.GetPlayerTaskState().IsTaskFinished; } return false; } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { return VisibleToEveryone(target); } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return VisibleToEveryone(target); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("MayorVentButtonText"); } } internal class Mechanic : RoleBase { private const int Id = 8500; private static OptionItem SkillLimit; private static OptionItem FixesDoors; private static OptionItem FixesReactors; private static OptionItem FixesOxygens; private static OptionItem FixesComms; private static OptionItem FixesElectrical; private static OptionItem SMAbilityUseGainWithEachTaskCompleted; private static OptionItem UsesUsedWhenFixingReactorOrO2; private static OptionItem UsesUsedWhenFixingLightsOrComms; private bool DoorsProgressing; public static bool HasEnabled => CustomRoles.Mechanic.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8500, TabGroup.CrewmateRoles, CustomRoles.Mechanic); SkillLimit = IntegerOptionItem.Create(8510, "MechanicSkillLimit", new IntegerValueRule(0, 100, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]).SetValueFormat(OptionFormat.Times); FixesDoors = BooleanOptionItem.Create(8511, "MechanicFixesDoors", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]); FixesReactors = BooleanOptionItem.Create(8512, "MechanicFixesReactors", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]); FixesOxygens = BooleanOptionItem.Create(8513, "MechanicFixesOxygens", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]); FixesComms = BooleanOptionItem.Create(8514, "MechanicFixesCommunications", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]); FixesElectrical = BooleanOptionItem.Create(8515, "MechanicFixesElectrical", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]); SMAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8516, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]).SetValueFormat(OptionFormat.Times); UsesUsedWhenFixingReactorOrO2 = FloatOptionItem.Create(8517, "SMUsesUsedWhenFixingReactorOrO2", new FloatValueRule(0f, 5f, 0.1f), 4f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]).SetValueFormat(OptionFormat.Times); UsesUsedWhenFixingLightsOrComms = FloatOptionItem.Create(8518, "SMUsesUsedWhenFixingLightsOrComms", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mechanic]).SetValueFormat(OptionFormat.Times); } public override void Add(byte playerId) { base.AbilityLimit = SkillLimit.GetInt(); } public override void UpdateSystem(ShipStatus __instance, SystemTypes systemType, byte amount, PlayerControl player) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Invalid comparison between Unknown and I4 if ((int)systemType <= 8) { if ((int)systemType != 3) { if ((int)systemType == 8 && FixesOxygens.GetBool() && (!(SkillLimit.GetFloat() > 0f) || !(base.AbilityLimit + UsesUsedWhenFixingReactorOrO2.GetFloat() - 1f <= 0f)) && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)8, (byte)67); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)8, (byte)66); base.AbilityLimit -= UsesUsedWhenFixingReactorOrO2.GetFloat(); SendSkillRPC(); } } else if (FixesReactors.GetBool() && (!(SkillLimit.GetFloat() > 0f) || !(base.AbilityLimit + UsesUsedWhenFixingReactorOrO2.GetFloat() - 1f <= 0f)) && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)3, (byte)16); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)3, (byte)17); base.AbilityLimit -= UsesUsedWhenFixingReactorOrO2.GetFloat(); SendSkillRPC(); } } else if ((int)systemType != 14) { if ((int)systemType != 16) { if ((int)systemType == 21 && FixesReactors.GetBool() && (!(SkillLimit.GetFloat() > 0f) || !(base.AbilityLimit + UsesUsedWhenFixingReactorOrO2.GetFloat() - 1f <= 0f)) && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)21, (byte)67); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)21, (byte)66); base.AbilityLimit -= UsesUsedWhenFixingReactorOrO2.GetFloat(); SendSkillRPC(); } } else if (FixesDoors.GetBool() && !DoorsProgressing) { int num = Utils.GetActiveMapId(); if ((int)((InnerNetClient)AmongUsClient.Instance).NetworkMode == 2) { num = AmongUsClient.Instance.TutorialMapId; } DoorsProgressing = true; switch (num) { case 2: UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 71, 72); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 67, 68); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 64, 66); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 73, 74); break; case 4: UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 64, 67); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 71, 73); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 74, 75); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 76, 78); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 68, 70); UpdateSystemPatch.CheckAndOpenDoorsRange(__instance, amount, 83, 84); break; } DoorsProgressing = false; } } else if (FixesComms.GetBool() && (!(SkillLimit.GetFloat() > 0f) || !(base.AbilityLimit + UsesUsedWhenFixingLightsOrComms.GetFloat() - 1f <= 0f)) && (uint)(amount - 64) <= 1u) { ShipStatus.Instance.RpcUpdateSystem((SystemTypes)14, (byte)16); ShipStatus.Instance.RpcUpdateSystem((SystemTypes)14, (byte)17); base.AbilityLimit -= UsesUsedWhenFixingLightsOrComms.GetFloat(); SendSkillRPC(); } Utils.NotifyRoles(player); } public override void SwitchSystemUpdate(SwitchSystem __instance, byte amount, PlayerControl player) { if (FixesElectrical.GetBool() && (!(SkillLimit.GetFloat() > 0f) || !(base.AbilityLimit + UsesUsedWhenFixingLightsOrComms.GetFloat() - 1f <= 0f))) { __instance.ActualSwitches = 0; __instance.ExpectedSwitches = 0; base.AbilityLimit -= UsesUsedWhenFixingLightsOrComms.GetFloat(); SendSkillRPC(); Logger.Info(player.GetNameWithRole().RemoveHtmlTags() + " instant - fix-lights", "SwitchSystem", escapeCRLF: true, 150, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Mechanic.cs"); } } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit <= 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += SMAbilityUseGainWithEachTaskCompleted.GetFloat(); SendSkillRPC(); } return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } } internal class Medic : RoleBase { private enum SelectOptionsList { Medic_SeeMedicAndTarget, Medic_SeeMedic, Medic_SeeTarget, Medic_SeeNoOne } private enum ShieldDeactivationIsVisibleList { MedicShieldDeactivationIsVisible_Immediately, MedicShieldDeactivationIsVisible_AfterMeeting, MedicShieldDeactivationIsVisible_OFF } private const int Id = 8600; private static OptionItem WhoCanSeeProtectOpt; private static OptionItem KnowShieldBrokenOpt; private static OptionItem ShieldDeactivatesWhenMedicDies; private static OptionItem ShieldDeactivationIsVisibleOpt; private static OptionItem ResetCooldown; public static OptionItem GuesserIgnoreShield; public static readonly List ProtectList = new List(); private static byte TempMarkProtected; public static bool HasEnabled => CustomRoles.Medic.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8600, TabGroup.CrewmateRoles, CustomRoles.Medic); WhoCanSeeProtectOpt = StringOptionItem.Create(8610, "MedicWhoCanSeeProtect", EnumHelper.GetAllNames(), 0, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]); KnowShieldBrokenOpt = StringOptionItem.Create(8616, "MedicKnowShieldBroken", EnumHelper.GetAllNames(), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]); ShieldDeactivatesWhenMedicDies = BooleanOptionItem.Create(8624, "MedicShieldDeactivatesWhenMedicDies", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]); ShieldDeactivationIsVisibleOpt = StringOptionItem.Create(8625, "MedicShielDeactivationIsVisible", EnumHelper.GetAllNames(), 0, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(ShieldDeactivatesWhenMedicDies); ResetCooldown = FloatOptionItem.Create(8630, "MedicResetCooldown", new FloatValueRule(0f, 120f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]).SetValueFormat(OptionFormat.Seconds); GuesserIgnoreShield = BooleanOptionItem.Create(8632, "MedicShieldedCanBeGuessed", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medic]); } public override void Init() { ProtectList.Clear(); TempMarkProtected = byte.MaxValue; } public override void Add(byte playerId) { base.AbilityLimit = 1f; if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private static void SendRPCForProtectList() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)170, (SendOption)1, -1); val.Write(TempMarkProtected); val.Write(ProtectList.Count); for (int i = 0; i < ProtectList.Count; i++) { val.Write(ProtectList[i]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPCForProtectList(MessageReader reader) { TempMarkProtected = reader.ReadByte(); int num = reader.ReadInt32(); ProtectList.Clear(); for (int i = 0; i < num; i++) { ProtectList.Add(reader.ReadByte()); } } public static bool InProtect(byte id) { if (ProtectList.Contains(id) && Main.PlayerStates.TryGetValue(id, out var value)) { return !value.IsDead; } return false; } public bool CheckKillButton(byte playerId) { if (!Main.PlayerStates[playerId].IsDead) { return base.AbilityLimit > 0f; } return false; } public override bool CanUseKillButton(PlayerControl pc) { return CheckKillButton(pc.PlayerId); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (CheckKillButton(id) ? 5f : 300f); } public override string GetProgressText(byte playerId, bool comms) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit(CheckKillButton(playerId) ? Utils.GetRoleColor(CustomRoles.Medic).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (!CheckKillButton(killer.PlayerId)) { return false; } if (ProtectList.Contains(target.PlayerId)) { return false; } base.AbilityLimit--; SendSkillRPC(); ProtectList.Add(target.PlayerId); TempMarkProtected = target.PlayerId; SendRPCForProtectList(); if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(); } switch (WhoCanSeeProtectOpt.GetValue()) { case 0: if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } killer.RPCPlayCustomSound("Shield"); target.RPCPlayCustomSound("Shield"); break; case 1: if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(target); } killer.RPCPlayCustomSound("Shield"); break; case 2: target.RPCPlayCustomSound("Shield"); break; } Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); Logger.Info($"{killer.GetNameWithRole()} : {base.AbilityLimit} shields left", "Medic", escapeCRLF: true, 138, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Medic.cs"); return false; } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { List playerListByRole = CustomRoles.Medic.GetPlayerListByRole(); if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || playerListByRole == null || !playerListByRole.Any()) { return true; } if (!ProtectList.Contains(target.PlayerId)) { return false; } SendRPCForProtectList(); killer.RpcGuardAndKill(target); killer.SetKillCooldown(ResetCooldown.GetFloat()); Utils.NotifyRoles(killer, target); Utils.NotifyRoles(target, killer); switch (KnowShieldBrokenOpt.GetValue()) { case 0: foreach (PlayerControl item in playerListByRole) { if (!((Object)(object)item == (Object)null) && item.IsAlive()) { item.Notify(Translator.GetString("MedicKillerTryBrokenShieldTargetForMedic")); } } target.RpcGuardAndKill(target); target.Notify(Translator.GetString("MedicKillerTryBrokenShieldTargetForTarget")); break; case 1: foreach (PlayerControl item2 in playerListByRole) { if (!((Object)(object)item2 == (Object)null) && item2.IsAlive()) { item2.Notify(Translator.GetString("MedicKillerTryBrokenShieldTargetForMedic")); } } break; case 2: target.RpcGuardAndKill(target); target.Notify(Translator.GetString("MedicKillerTryBrokenShieldTargetForTarget")); break; } Logger.Info(target.GetNameWithRole() + " : Shield Shatter from the Medic", "Medic", escapeCRLF: true, 182, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Medic.cs"); return true; } public override void AfterMeetingTasks() { if (ShieldDeactivatesWhenMedicDies.GetBool() && ShieldDeactivationIsVisibleOpt.GetInt() == 1) { TempMarkProtected = byte.MaxValue; SendRPCForProtectList(); Utils.NotifyRoles(); } } private static void IsDead(PlayerControl target) { if (target.Is(CustomRoles.Medic) && ShieldDeactivatesWhenMedicDies.GetBool()) { ProtectList.Clear(); Logger.Info(target.GetNameWithRole() + " : Medic is dead", "Medic", escapeCRLF: true, 202, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Medic.cs"); if (ShieldDeactivationIsVisibleOpt.GetInt() == 0) { TempMarkProtected = byte.MaxValue; } SendRPCForProtectList(); Utils.NotifyRoles(); } } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { IsDead(target); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override string GetMark(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) int @int = WhoCanSeeProtectOpt.GetInt(); if ((uint)@int <= 1u) { if (seer.PlayerId == target.PlayerId && (InProtect(seer.PlayerId) || TempMarkProtected == seer.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medic)), "✚"); } if (seer.PlayerId != target.PlayerId && (InProtect(target.PlayerId) || TempMarkProtected == target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medic)), "✚"); } } return string.Empty; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (!seer.Is(CustomRoles.Medic)) { bool flag = seer.PlayerId == target.PlayerId && (InProtect(seer.PlayerId) || TempMarkProtected == seer.PlayerId); if (flag) { int @int = WhoCanSeeProtectOpt.GetInt(); bool flag2 = ((@int == 0 || @int == 2) ? true : false); flag = flag2; } if (flag) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medic)), "✚"); } if (seer.PlayerId != target.PlayerId && !seer.IsAlive() && (InProtect(target.PlayerId) || TempMarkProtected == target.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medic)), "✚"); } } return string.Empty; } public override void SetAbilityButtonText(HudManager hud, byte id) { ReportButton reportButton = hud.ReportButton; if (reportButton != null) { ((ActionButton)reportButton).OverrideText(Translator.GetString("ReportButtonText")); } KillButton killButton = hud.KillButton; if (killButton != null) { ((ActionButton)killButton).OverrideText(Translator.GetString("MedicalerButtonText")); } } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Shield"); } } internal class Medium : RoleBase { private const int Id = 8700; private static OptionItem ContactLimitOpt; private static OptionItem OnlyReceiveMsgFromCrew; private static OptionItem MediumAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary ContactPlayer = new Dictionary(); public static bool HasEnabled => CustomRoles.Medium.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8700, TabGroup.CrewmateRoles, CustomRoles.Medium); ContactLimitOpt = IntegerOptionItem.Create(8710, "MediumContactLimit", new IntegerValueRule(0, 15, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medium]).SetValueFormat(OptionFormat.Times); OnlyReceiveMsgFromCrew = BooleanOptionItem.Create(8711, "MediumOnlyReceiveMsgFromCrew", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medium]); MediumAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(8712, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Medium]).SetValueFormat(OptionFormat.Times); } public override void Init() { ContactPlayer.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = ContactLimitOpt.GetFloat(); } public void SendRPC(byte playerId, byte targetId = byte.MaxValue, bool isUsed = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(base.AbilityLimit); val.Write(isUsed); if (isUsed) { val.Write(targetId); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte value = reader.ReadByte(); float abilityLimit = reader.ReadSingle(); bool num = reader.ReadBoolean(); base.AbilityLimit = abilityLimit; if (num) { byte key = reader.ReadByte(); ContactPlayer.Clear(); ContactPlayer.TryAdd(key, value); } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += MediumAbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPC(player.PlayerId); } return true; } public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInfo target) { ContactPlayer.Clear(); if (!((Object)(object)target == (Object)null) && !((Object)(object)target.Object == (Object)null) && !((Object)(object)base._Player == (Object)null) && base.AbilityLimit > 0f) { base.AbilityLimit--; ContactPlayer.TryAdd(target.PlayerId, base._Player.PlayerId); SendRPC(base._Player.PlayerId, target.PlayerId, isUsed: true); Logger.Info($"Psychics Make Connections: {new <>f__AnonymousDelegate0(base._Player.GetRealName)} => {target.PlayerName}", "Medium", escapeCRLF: true, 92, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Medium.cs"); } } public static bool MsMsg(PlayerControl pc, string msg) { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null) { return false; } if (!ContactPlayer.ContainsKey(pc.PlayerId)) { return false; } if (OnlyReceiveMsgFromCrew.GetBool() && !pc.GetCustomRole().IsCrewmate()) { return false; } if (pc.IsAlive()) { return false; } msg = msg.ToLower().Trim(); if (!CheckCommond(ref msg, "通灵|ms|mediumship|medium", exact: false)) { return false; } bool flag; if (msg.Contains('n') || msg.Contains(Translator.GetString("No")) || msg.Contains('错') || msg.Contains("不是")) { flag = false; } else { if (!msg.Contains('y') && !msg.Contains(Translator.GetString("Yes")) && !msg.Contains('对')) { Utils.SendMessage(Translator.GetString("MediumHelp"), pc.PlayerId); return true; } flag = true; } Utils.SendMessage(Translator.GetString("Medium" + (flag ? "Yes" : "No")), ContactPlayer[pc.PlayerId], Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("MediumTitle"))); Utils.SendMessage(Translator.GetString("MediumDone"), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("MediumTitle"))); ContactPlayer.Remove(pc.PlayerId); return true; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg == "/" + text) { return true; } } else if (msg.StartsWith("/" + text)) { msg = msg.Replace("/" + text, string.Empty); return true; } } return false; } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override void OnOthersMeetingHudStart(PlayerControl pc) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) if (ContactPlayer.ContainsValue(pc.PlayerId)) { MeetingHudStartPatch.AddMsg(string.Format(Translator.GetString("MediumNotifySelf"), Main.AllPlayerNames[ContactPlayer.Where((KeyValuePair x) => x.Value == pc.PlayerId).FirstOrDefault().Key], base.AbilityLimit), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("MediumTitle"))); } if (ContactPlayer.ContainsKey(pc.PlayerId) && (!OnlyReceiveMsgFromCrew.GetBool() || pc.GetCustomRole().IsCrewmate())) { MeetingHudStartPatch.AddMsg(string.Format(Translator.GetString("MediumNotifyTarget"), Main.AllPlayerNames[ContactPlayer[pc.PlayerId]]), pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Medium)), Translator.GetString("MediumTitle"))); } } } internal class Merchant : RoleBase { private const int Id = 8800; private static readonly HashSet playerIdList = new HashSet(); private static List addons = new List(); private static readonly Dictionary addonsSold = new Dictionary(); private static readonly Dictionary> bribedKiller = new Dictionary>(); private static readonly List helpfulAddons = new List(12) { CustomRoles.Watcher, CustomRoles.Seer, CustomRoles.Bait, CustomRoles.Cyber, CustomRoles.Trapper, CustomRoles.Tiebreaker, CustomRoles.Necroview, CustomRoles.Bewilder, CustomRoles.Burst, CustomRoles.Sleuth, CustomRoles.Autopsy, CustomRoles.Lucky }; private static readonly List harmfulAddons = new List(5) { CustomRoles.Oblivious, CustomRoles.VoidBallot, CustomRoles.Fragile, CustomRoles.Unreportable, CustomRoles.Unlucky }; private static readonly List neutralAddons = new List(8) { CustomRoles.Guesser, CustomRoles.Diseased, CustomRoles.Antidote, CustomRoles.Aware, CustomRoles.Gravestone, CustomRoles.Onbound, CustomRoles.Stubborn, CustomRoles.Rebound }; private static OptionItem OptionMaxSell; private static OptionItem OptionMoneyPerSell; private static OptionItem OptionMoneyRequiredToBribe; private static OptionItem OptionNotifyBribery; private static OptionItem OptionCanTargetCrew; private static OptionItem OptionCanTargetImpostor; private static OptionItem OptionCanTargetNeutral; private static OptionItem OptionCanSellHelpful; private static OptionItem OptionCanSellHarmful; private static OptionItem OptionCanSellNeutral; private static OptionItem OptionSellOnlyHarmfulToEvil; private static OptionItem OptionSellOnlyHelpfulToCrew; private static OptionItem OptionSellOnlyEnabledAddons; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; private static int GetCurrentAmountOfMoney(byte playerId) { return addonsSold[playerId] * OptionMoneyPerSell.GetInt() - bribedKiller[playerId].Count * OptionMoneyRequiredToBribe.GetInt(); } public override void SetupCustomOption() { Options.SetupRoleOptions(8800, TabGroup.CrewmateRoles, CustomRoles.Merchant); OptionMaxSell = IntegerOptionItem.Create(8802, "MerchantMaxSell", new IntegerValueRule(1, 99, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]).SetValueFormat(OptionFormat.Times); OptionMoneyPerSell = IntegerOptionItem.Create(8803, "MerchantMoneyPerSell", new IntegerValueRule(1, 99, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]).SetValueFormat(OptionFormat.Times); OptionMoneyRequiredToBribe = IntegerOptionItem.Create(8804, "MerchantMoneyRequiredToBribe", new IntegerValueRule(1, 99, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]).SetValueFormat(OptionFormat.Times); OptionNotifyBribery = BooleanOptionItem.Create(8805, "MerchantNotifyBribery", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanTargetCrew = BooleanOptionItem.Create(8806, "MerchantTargetCrew", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanTargetImpostor = BooleanOptionItem.Create(8807, "MerchantTargetImpostor", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanTargetNeutral = BooleanOptionItem.Create(8808, "MerchantTargetNeutral", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanSellHelpful = BooleanOptionItem.Create(8809, "MerchantSellHelpful", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanSellHarmful = BooleanOptionItem.Create(8810, "MerchantSellHarmful", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionCanSellNeutral = BooleanOptionItem.Create(8811, "MerchantSellMixed", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionSellOnlyHarmfulToEvil = BooleanOptionItem.Create(8813, "MerchantSellHarmfulToEvil", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionSellOnlyHelpfulToCrew = BooleanOptionItem.Create(8814, "MerchantSellHelpfulToCrew", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); OptionSellOnlyEnabledAddons = BooleanOptionItem.Create(8815, "MerchantSellOnlyEnabledAddons", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Merchant]); Options.OverrideTasksData.Create(8816, TabGroup.CrewmateRoles, CustomRoles.Merchant); } public override void Init() { playerIdList.Clear(); addons.Clear(); addonsSold.Clear(); bribedKiller.Clear(); if (OptionCanSellHelpful.GetBool()) { addons.AddRange(helpfulAddons); } if (OptionCanSellHarmful.GetBool()) { addons.AddRange(harmfulAddons); } if (OptionCanSellNeutral.GetBool()) { addons.AddRange(neutralAddons); } if (OptionSellOnlyEnabledAddons.GetBool()) { addons = addons.Where((CustomRoles role) => role.GetMode() != 0).ToList(); } } public override void Add(byte playerId) { playerIdList.Add(playerId); addonsSold.Add(playerId, 0); bribedKiller.Add(playerId, new HashSet()); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); addonsSold.Remove(playerId); bribedKiller.Remove(playerId); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { return !OnClientMurder(killer, target); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!player.IsAlive()) { return true; } if (addonsSold[player.PlayerId] >= OptionMaxSell.GetInt()) { return true; } if (addons.Count == 0) { player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("MerchantAddonSellFail"))); Logger.Info("No addons to sell.", "Merchant", escapeCRLF: true, 154, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Merchant.cs"); return true; } _ = IRandom.Instance; CustomRoles addon = addons.RandomElement(); List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != player.PlayerId && !x.Is(CustomRoles.Stubborn) && CustomRolesHelper.CheckAddonConfilct(addon, x, checkLimitAddons: false) && (!Cleanser.CantGetAddon() || (Cleanser.CantGetAddon() && !x.Is(CustomRoles.Cleansed))) && ((OptionCanTargetCrew.GetBool() && x.GetCustomRole().IsCrewmate()) || (OptionCanTargetImpostor.GetBool() && x.GetCustomRole().IsImpostor()) || (OptionCanTargetNeutral.GetBool() && x.GetCustomRole().IsNeutral()))).ToList(); if (list.Any()) { bool num = helpfulAddons.Contains(addon); bool flag = !num; if (num && OptionSellOnlyHarmfulToEvil.GetBool()) { list = list.Where((PlayerControl a) => a.GetCustomRole().IsCrewmate()).ToList(); } if (flag && OptionSellOnlyHelpfulToCrew.GetBool()) { list = list.Where((PlayerControl a) => a.GetCustomRole().IsImpostor() || a.GetCustomRole().IsNeutral()).ToList(); } if (list.Count == 0) { player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("MerchantAddonSellFail"))); Logger.Info("All Alive Player Count = 0", "Merchant", escapeCRLF: true, 203, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Merchant.cs"); return true; } PlayerControl obj = list.RandomElement(); obj.RpcSetCustomRole(addon); obj.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("MerchantAddonSell"))); player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("MerchantAddonDelivered"))); ExtendedPlayerControl.AddInSwitchAddons(obj, obj, addon, CustomRoles.NotAssigned); addonsSold[player.PlayerId]++; } return true; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (IsBribedKiller(pc, target)) { pc.ShowInfoMessage(isUI, Translator.GetString("BribedByMerchant2")); return true; } return false; } public static bool OnClientMurder(PlayerControl killer, PlayerControl target) { if (bribedKiller[target.PlayerId].Contains(killer.PlayerId)) { NotifyBribery(killer, target); return true; } if (GetCurrentAmountOfMoney(target.PlayerId) >= OptionMoneyRequiredToBribe.GetInt()) { NotifyBribery(killer, target); bribedKiller[target.PlayerId].Add(killer.PlayerId); return true; } return false; } public static bool IsBribedKiller(PlayerControl killer, PlayerControl target) { return bribedKiller[target.PlayerId].Contains(killer.PlayerId); } private static void NotifyBribery(PlayerControl killer, PlayerControl target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("BribedByMerchant"))); if (OptionNotifyBribery.GetBool()) { target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Merchant)), Translator.GetString("MerchantKillAttemptBribed"))); } } } internal class Mole : RoleBase { private const int Id = 26000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VentCooldown; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(26000, TabGroup.CrewmateRoles, CustomRoles.Mole); VentCooldown = FloatOptionItem.Create(26011, "MoleVentCooldown", new FloatValueRule(5f, 180f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mole]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override void OnExitVent(PlayerControl pc, int ventId) { new LateTask(time: (Utils.GetActiveMapId() != 5) ? 0.1f : 0.4f, action: delegate { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) Vent[] collection = ((IEnumerable)ShipStatus.Instance.AllVents).Where((Vent x) => x.Id != ventId).ToArray(); _ = IRandom.Instance; Vent val = collection.RandomElement(); Logger.Info($" {((Component)val).transform.position}", "Mole vent teleport", escapeCRLF: true, 50, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Mole.cs"); pc.RpcTeleport(new Vector2(((Component)val).transform.position.x, ((Component)val).transform.position.y + 0.3636f)); }, name: "Mole On Exit Vent"); } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.AbilityButton).OverrideText(Translator.GetString("MoleVentButtonText")); } } internal class Monarch : RoleBase { private const int Id = 12100; private static OptionItem KnightCooldown; private static OptionItem KnightMax; public static OptionItem HideAdditionalVotesForKnighted; public static bool HasEnabled => CustomRoles.Monarch.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(12100, TabGroup.CrewmateRoles, CustomRoles.Monarch); KnightCooldown = FloatOptionItem.Create(12110, "MonarchKnightCooldown", new FloatValueRule(0f, 180f, 2.5f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Monarch]).SetValueFormat(OptionFormat.Seconds); KnightMax = IntegerOptionItem.Create(12112, "MonarchKnightMax", new IntegerValueRule(1, 15, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Monarch]).SetValueFormat(OptionFormat.Times); HideAdditionalVotesForKnighted = BooleanOptionItem.Create(12113, "HideAdditionalVotesForKnighted", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Monarch]); } public override void Add(byte playerId) { base.AbilityLimit = KnightMax.GetInt(); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = KnightCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl player) { return base.AbilityLimit > 0f; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { return !CustomRoles.Knighted.RoleExist(); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) if (base.AbilityLimit <= 0f) { return false; } if (Mini.Age < 18 && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini))) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cultist)), Translator.GetString("CantRecruit"))); return false; } if (CanBeKnighted(target)) { base.AbilityLimit--; SendSkillRPC(); target.RpcSetCustomRole(CustomRoles.Knighted); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Monarch)), Translator.GetString("MonarchKnightedPlayer"))); target.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Monarch)), Translator.GetString("KnightedByMonarch"))); killer.ResetKillCooldown(); killer.SetKillCooldown(); target.RpcGuardAndKill(killer); target.SetKillCooldown(-1f, null, forceAnime: true); string[] obj = new string[6] { "设置职业:", null, null, null, null, null }; object obj2; if (target == null) { obj2 = null; } else { NetworkedPlayerInfo data = target.Data; obj2 = ((data != null) ? data.PlayerName : null); } obj[1] = (string)obj2; obj[2] = " = "; obj[3] = target.GetCustomRole().ToString(); obj[4] = " + "; obj[5] = CustomRoles.Knighted.ToString(); Logger.Info(string.Concat(obj), "Assign " + CustomRoles.Knighted, escapeCRLF: true, 73, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Monarch.cs"); if (base.AbilityLimit < 0f) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次招募机会", "Monarch", escapeCRLF: true, 76, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Monarch.cs"); return false; } if (base.AbilityLimit < 0f) { ((ActionButton)DestroyableSingleton.Instance.KillButton).OverrideText(Translator.GetString("KillButtonText") ?? ""); } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Monarch)), Translator.GetString("MonarchInvalidTarget"))); Logger.Info($"{killer.GetNameWithRole()} : 剩余{base.AbilityLimit}次招募机会", "Monarch", escapeCRLF: true, 83, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Monarch.cs"); return false; } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.Monarch && CustomRoles.Knighted.RoleExist()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessMonarch")); return true; } return false; } public override string GetProgressText(byte PlayerId, bool comms) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Color val = ((!(base.AbilityLimit > 0f)) ? Color.gray : Utils.GetRoleColor(CustomRoles.Monarch)); return Utils.ColorString(Color32.op_Implicit(val), $"({base.AbilityLimit})"); } private static bool CanBeKnighted(PlayerControl pc) { if ((Object)(object)pc != (Object)null && !pc.GetCustomRole().IsNotKnightable()) { return !pc.IsAnySubRole((CustomRoles x) => (x == CustomRoles.Knighted || x == CustomRoles.Stubborn || x == CustomRoles.TicketsStealer) ? true : false); } return false; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!seer.Is(CustomRoles.Monarch) || !target.Is(CustomRoles.Knighted)) { return ""; } return Main.roleColors[CustomRoles.Knighted]; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.Knighted) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessKnighted")); return true; } return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("MonarchKillButtonText")); } } internal class Mortician : RoleBase { private const int Id = 8900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ShowArrows; private static readonly Dictionary lastPlayerName = new Dictionary(); private static readonly Dictionary msgToSend = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(8900, TabGroup.CrewmateRoles, CustomRoles.Mortician); ShowArrows = BooleanOptionItem.Create(8902, "ShowArrows", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mortician]); } public override void Init() { playerIdList.Clear(); lastPlayerName.Clear(); msgToSend.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } private static void SendRPC(byte playerId, bool add, Vector3 loc = default(Vector3)) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)172, (SendOption)1, -1); val.Write(playerId); val.Write(add); if (add) { val.Write(loc.x); val.Write(loc.y); val.Write(loc.z); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte seer = reader.ReadByte(); if (reader.ReadBoolean()) { LocateArrow.Add(seer, new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); } else { LocateArrow.RemoveAllTarget(seer); } } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (inMeeting || target.IsDisconnected()) { return; } Vector2 val = Vector2.op_Implicit(((Component)target).transform.position); float num = float.MaxValue; string value = ""; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (val2.PlayerId != target.PlayerId) { float num2 = Vector2.Distance(Vector2.op_Implicit(((Component)val2).transform.position), val); if (num2 < num && num2 < 1.5f) { num = num2; value = val2.GetRealName(); } } } lastPlayerName.TryAdd(target.PlayerId, value); byte[] array = playerIdList.ToArray(); foreach (byte b in array) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { LocateArrow.Add(b, ((Component)target).transform.position); SendRPC(b, add: true, ((Component)target).transform.position); } } } public override void OnReportDeadBody(PlayerControl pc, NetworkedPlayerInfo target) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (byte playerId in playerIdList) { LocateArrow.RemoveAllTarget(playerId); SendRPC(playerId, add: false); } if (!((Object)(object)pc == (Object)null) && !((Object)(object)target == (Object)null) && !((Object)(object)target.Object == (Object)null) && pc.Is(CustomRoles.Mortician) && pc.PlayerId != target.PlayerId) { lastPlayerName.TryGetValue(target.PlayerId, out var value); if (value == "") { msgToSend.TryAdd(pc.PlayerId, string.Format(Translator.GetString("MorticianGetNoInfo"), target.PlayerName)); } else { msgToSend.TryAdd(pc.PlayerId, string.Format(Translator.GetString("MorticianGetInfo"), target.PlayerName, value)); } } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting) { return string.Empty; } if (ShowArrows.GetBool()) { if (!seer.Is(CustomRoles.Mortician)) { return ""; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return ""; } if (GameStates.IsMeeting) { return ""; } return Utils.ColorString(Color32.op_Implicit(Color.white), LocateArrow.GetArrows(seer)); } return ""; } public override void OnMeetingHudStart(PlayerControl pc) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (msgToSend.ContainsKey(pc.PlayerId)) { MeetingHudStartPatch.AddMsg(msgToSend[pc.PlayerId], pc.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Mortician)), Translator.GetString("MorticianCheckTitle"))); } } public override void MeetingHudClear() { msgToSend.Clear(); } } internal class NiceGuesser : RoleBase { private const int Id = 10900; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem GGCanGuessTime; private static OptionItem GGCanGuessCrew; private static OptionItem GGCanGuessAdt; private static OptionItem GGTryHideMsg; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) Options.SetupRoleOptions(10900, TabGroup.CrewmateRoles, CustomRoles.NiceGuesser); GGCanGuessTime = IntegerOptionItem.Create(10910, "GuesserCanGuessTimes", new IntegerValueRule(1, 15, 1), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceGuesser]).SetValueFormat(OptionFormat.Times); GGCanGuessCrew = BooleanOptionItem.Create(10911, "GGCanGuessCrew", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceGuesser]); GGCanGuessAdt = BooleanOptionItem.Create(10912, "GGCanGuessAdt", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceGuesser]); GGTryHideMsg = BooleanOptionItem.Create(10913, "GuesserTryHideMsg", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.NiceGuesser]).SetColor(Color.green); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.NiceGuesser)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public static bool NeedHideMsg(PlayerControl pc) { if (pc.Is(CustomRoles.NiceGuesser)) { return GGTryHideMsg.GetBool(); } return false; } public static bool HideTabInGuesserUI(int TabId) { if (!GGCanGuessCrew.GetBool() && TabId == 0) { return true; } if (!GGCanGuessAdt.GetBool() && TabId == 3) { return true; } return false; } public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (GuessManager.GuesserGuessed[guesser.PlayerId] >= GGCanGuessTime.GetInt()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GGGuessMax")); return true; } if (role.IsAdditionRole() && !GGCanGuessAdt.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessAdtRole")); return true; } if (target.Is(Custom_Team.Crewmate) && !GGCanGuessCrew.GetBool() && !guesser.Is(CustomRoles.Madmate)) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessCrewRole")); return true; } return false; } } internal class Observer : RoleBase { private const int Id = 9000; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9000, TabGroup.CrewmateRoles, CustomRoles.Observer); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public static void ActivateGuardAnimation(byte killerId, PlayerControl target) { byte[] array = playerIdList.ToArray(); foreach (byte b in array) { if (b != killerId) { PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { playerById.RpcGuardAndKill(target, forObserver: true); } } } } } internal class Oracle : RoleBase { private const int Id = 9100; private static OptionItem CheckLimitOpt; private static OptionItem HidesVote; private static OptionItem FailChance; private static OptionItem OracleAbilityUseGainWithEachTaskCompleted; private static OptionItem ChangeRecruitTeam; private readonly HashSet DidVote = new HashSet(); private static readonly Dictionary TempCheckLimit = new Dictionary(); public static bool HasEnabled => CustomRoles.Oracle.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9100, TabGroup.CrewmateRoles, CustomRoles.Oracle); CheckLimitOpt = IntegerOptionItem.Create(9110, "OracleSkillLimit", new IntegerValueRule(0, 10, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oracle]).SetValueFormat(OptionFormat.Times); HidesVote = BooleanOptionItem.Create(9112, "OracleHideVote", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oracle]); FailChance = IntegerOptionItem.Create(9113, "FailChance", new IntegerValueRule(0, 100, 5), 0, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oracle]).SetValueFormat(OptionFormat.Percent); OracleAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(9114, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oracle]).SetValueFormat(OptionFormat.Times); ChangeRecruitTeam = BooleanOptionItem.Create(9115, "OracleCheckAddons", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oracle]); } public override void Init() { TempCheckLimit.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = CheckLimitOpt.GetFloat(); } public override bool HideVote(PlayerVoteArea pva) { if (HidesVote.GetBool()) { return TempCheckLimit[pva.TargetPlayerId] > 0f; } return false; } public void SendRPC(byte playerId, bool isTemp = false) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(playerId); val.Write(isTemp); if (!isTemp) { val.Write(base.AbilityLimit); } else { val.Write(TempCheckLimit[playerId]); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { byte key = reader.ReadByte(); if (!reader.ReadBoolean()) { float abilityLimit = reader.ReadSingle(); base.AbilityLimit = abilityLimit; } else { float value = reader.ReadSingle(); TempCheckLimit[key] = value; } } public override void OnVote(PlayerControl player, PlayerControl target) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)target == (Object)null || DidVote.Contains(player.PlayerId)) { return; } DidVote.Add(player.PlayerId); if (base.AbilityLimit < 1f) { Utils.SendMessage(Translator.GetString("OracleCheckReachLimit"), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Oracle)), Translator.GetString("OracleCheckMsgTitle"))); return; } base.AbilityLimit -= 1f; SendRPC(player.PlayerId); if (player.PlayerId == target.PlayerId) { Utils.SendMessage(Translator.GetString("OracleCheckSelfMsg") + "\n\n" + string.Format(Translator.GetString("OracleCheckLimit"), base.AbilityLimit), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Oracle)), Translator.GetString("OracleCheckMsgTitle"))); return; } string text = "Crewmate"; if (!ChangeRecruitTeam.GetBool()) { text = ((target.GetCustomRole().IsImpostor() && !target.Is(CustomRoles.Trickster)) ? "Impostor" : ((!target.GetCustomRole().IsNeutral()) ? "Crewmate" : "Neutral")); } else if (target.Is(CustomRoles.Admired)) { text = "Crewmate"; } else if (target.GetCustomRole().IsImpostorTeamV2() || target.GetCustomSubRoles().Any((CustomRoles role) => role.IsImpostorTeamV2())) { text = "Impostor"; } else if (target.GetCustomRole().IsNeutralTeamV2() || target.GetCustomSubRoles().Any((CustomRoles role) => role.IsNeutralTeamV2())) { text = "Neutral"; } else if (target.GetCustomRole().IsCrewmateTeamV2() && (target.GetCustomSubRoles().Any((CustomRoles role) => role.IsCrewmateTeamV2()) || target.GetCustomSubRoles().Count == 0)) { text = "Crewmate"; } if (FailChance.GetInt() > 0 && HashRandom.Next(1, 100) <= FailChance.GetInt()) { int num = HashRandom.Next(1, 3); if (text == "Crewmate") { if (num == 1) { text = "Neutral"; } if (num == 2) { text = "Impostor"; } } if (text == "Neutral") { if (num == 1) { text = "Crewmate"; } if (num == 2) { text = "Impostor"; } } if (text == "Impostor") { if (num == 1) { text = "Neutral"; } if (num == 2) { text = "Crewmate"; } } } string text2 = string.Format(Translator.GetString("OracleCheck." + text), target.GetRealName()); Utils.SendMessage(Translator.GetString("OracleCheck") + "\n" + text2 + "\n\n" + string.Format(Translator.GetString("OracleCheckLimit"), base.AbilityLimit), player.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Oracle)), Translator.GetString("OracleCheckMsgTitle"))); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += OracleAbilityUseGainWithEachTaskCompleted.GetFloat(); SendRPC(player.PlayerId); } return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo tagret) { DidVote.Clear(); TempCheckLimit[_state.PlayerId] = base.AbilityLimit; SendRPC(_state.PlayerId, isTemp: true); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } } internal class Overseer : RoleBase { private const int Id = 12200; private static readonly HashSet playerIdList = new HashSet(); private static readonly Dictionary RandomRole = new Dictionary(); private static readonly Dictionary OverseerTimer = new Dictionary(); public static readonly Dictionary<(byte, byte), bool> IsRevealed = new Dictionary<(byte, byte), bool>(); private static OptionItem OverseerCooldown; private static OptionItem OverseerRevealTime; private static OptionItem Vision; private static readonly List randomRolesForTrickster = new List(36) { CustomRoles.Snitch, CustomRoles.LazyGuy, CustomRoles.SuperStar, CustomRoles.Celebrity, CustomRoles.TaskManager, CustomRoles.Mayor, CustomRoles.Psychic, CustomRoles.Mechanic, CustomRoles.Snitch, CustomRoles.Marshall, CustomRoles.Inspector, CustomRoles.Bastion, CustomRoles.Dictator, CustomRoles.Doctor, CustomRoles.Detective, CustomRoles.Lookout, CustomRoles.Telecommunication, CustomRoles.NiceGuesser, CustomRoles.Transporter, CustomRoles.TimeManager, CustomRoles.Veteran, CustomRoles.Bodyguard, CustomRoles.Grenadier, CustomRoles.Lighter, CustomRoles.FortuneTeller, CustomRoles.Oracle, CustomRoles.Tracefinder, CustomRoles.Judge, CustomRoles.Mortician, CustomRoles.Medium, CustomRoles.Observer, CustomRoles.Pacifist, CustomRoles.Coroner, CustomRoles.Retributionist, CustomRoles.Guardian, CustomRoles.Spiritualist }; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("prophecies"); } public override void SetupCustomOption() { Options.SetupRoleOptions(12200, TabGroup.CrewmateRoles, CustomRoles.Overseer); OverseerCooldown = FloatOptionItem.Create(12210, "OverseerRevealCooldown", new FloatValueRule(0f, 180f, 2.5f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overseer]).SetValueFormat(OptionFormat.Seconds); OverseerRevealTime = FloatOptionItem.Create(12211, "OverseerRevealTime", new FloatValueRule(0f, 60f, 1f), 10f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overseer]).SetValueFormat(OptionFormat.Seconds); Vision = FloatOptionItem.Create(12212, "OverseerVision", new FloatValueRule(0f, 5f, 0.05f), 0.25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overseer]).SetValueFormat(OptionFormat.Multiplier); } public override void Init() { playerIdList.Clear(); OverseerTimer.Clear(); RandomRole.Clear(); IsRevealed.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { IsRevealed.Add((playerId, val.PlayerId), value: false); } RandomRole.Add(playerId, GetRandomCrewRoleString()); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { OverseerTimer.Remove(playerId); RandomRole.Remove(playerId); } public override bool CanUseKillButton(PlayerControl pc) { return true; } private static void SendTimerRPC(byte RpcType, byte overseertId, PlayerControl target = null, float timer = 0f) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)182, (SendOption)1, -1); val.Write(RpcType); val.Write(overseertId); if ((Object)(object)target != (Object)null && RpcType == 1) { MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)target); val.Write(timer); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveTimerRPC(MessageReader reader) { byte b = reader.ReadByte(); byte key = reader.ReadByte(); switch (b) { case 0: OverseerTimer.Clear(); break; case 1: { PlayerControl item = MessageExtensions.ReadNetObject(reader); float item2 = reader.ReadSingle(); OverseerTimer.TryAdd(key, (item, item2)); break; } case 2: OverseerTimer.Remove(key); break; } } private static void SetRevealtPlayerRPC(PlayerControl player, PlayerControl target, bool isRevealed) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)181, (SendOption)1, -1); val.Write(player.PlayerId); val.Write(target.PlayerId); val.Write(isRevealed); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveSetRevealedPlayerRPC(MessageReader reader) { byte item = reader.ReadByte(); byte item2 = reader.ReadByte(); bool value = reader.ReadBoolean(); IsRevealed[(item, item2)] = value; } public static bool IsRevealedPlayer(PlayerControl player, PlayerControl target) { if ((Object)(object)player == (Object)null || (Object)(object)target == (Object)null || IsRevealed == null) { return false; } IsRevealed.TryGetValue((player.PlayerId, target.PlayerId), out var value); return value; } public static string GetRandomRole(byte playerId) { return RandomRole[playerId]; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, Vision.GetFloat()); opt.SetFloat((FloatOptionNames)3, Vision.GetFloat()); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = OverseerCooldown.GetFloat(); } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(OverseerRevealTime.GetFloat()); if (!IsRevealed[(killer.PlayerId, target.PlayerId)] && !OverseerTimer.ContainsKey(killer.PlayerId)) { OverseerTimer.TryAdd(killer.PlayerId, (target, 0f)); SendTimerRPC(1, killer.PlayerId, target); target.RpcSetSpecificScanner(killer, IsActive: true); Utils.NotifyRoles(killer); } return false; } public override void OnFixedUpdate(PlayerControl player) { //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if (!OverseerTimer.ContainsKey(player.PlayerId)) { return; } byte playerId = player.PlayerId; if (!player.IsAlive() || Pelican.IsEaten(playerId)) { OverseerTimer[playerId].Item1.RpcSetSpecificScanner(player, IsActive: false); OverseerTimer.Remove(playerId); SendTimerRPC(2, playerId); Utils.NotifyRoles(player); return; } var (val, num) = OverseerTimer[playerId]; if (!val.IsAlive()) { OverseerTimer.Remove(playerId); SendTimerRPC(2, playerId); val.RpcSetSpecificScanner(player, IsActive: false); return; } if (num >= OverseerRevealTime.GetFloat()) { player.SetKillCooldown(); OverseerTimer.Remove(playerId); SendTimerRPC(2, playerId); val.RpcSetSpecificScanner(player, IsActive: false); IsRevealed[(playerId, val.PlayerId)] = true; SetRevealtPlayerRPC(player, val, isRevealed: true); Utils.NotifyRoles(player); return; } float num2 = ((Il2CppArrayBase)(object)NormalGameOptionsV08.KillDistances)[Mathf.Clamp(player.Is(Reach.IsReach) ? 2 : Main.NormalOptions.KillDistance, 0, 2)] + 0.5f; if (Vector2.Distance(player.GetCustomPosition(), val.GetCustomPosition()) <= num2) { OverseerTimer[playerId] = (val, num + Time.fixedDeltaTime); return; } OverseerTimer.Remove(playerId); SendTimerRPC(2, playerId); val.RpcSetSpecificScanner(player, IsActive: false); Utils.NotifyRoles(player, val); Logger.Info("Canceled: " + player.GetNameWithRole(), "Overseer", escapeCRLF: true, 249, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Overseer.cs"); } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { OverseerTimer.Clear(); SendTimerRPC(0, byte.MaxValue); } private static string GetRandomCrewRoleString() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) CustomRoles role = randomRolesForTrickster.RandomElement(); string value = Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(role)), Translator.GetString(role.ToString())); return $"{value}"; } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { if (OverseerTimer.TryGetValue(seer.PlayerId, out var value) && (Object)(object)value.Item1 == (Object)(object)seen) { return "○"; } return string.Empty; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("OverseerKillButtonText")); } } internal class Pacifist : RoleBase { private const int Id = 9200; private static OptionItem PacifistCooldown; private static OptionItem PacifistMaxOfUseage; private static OptionItem PacifistAbilityUseGainWithEachTaskCompleted; public static bool HasEnabled => CustomRoles.Pacifist.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9200, TabGroup.CrewmateRoles, CustomRoles.Pacifist); PacifistCooldown = FloatOptionItem.Create(9210, "PacifistCooldown", new FloatValueRule(1f, 180f, 1f), 30f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pacifist]).SetValueFormat(OptionFormat.Seconds); PacifistMaxOfUseage = IntegerOptionItem.Create(9211, "PacifistMaxOfUseage", new IntegerValueRule(0, 20, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pacifist]).SetValueFormat(OptionFormat.Times); PacifistAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(9204, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Pacifist]).SetValueFormat(OptionFormat.Times); } public override void Add(byte playerId) { base.AbilityLimit = PacifistMaxOfUseage.GetInt(); } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (base.AbilityLimit < 1f) { PlayerControl obj = pc; if (obj != null) { PlayerPhysics myPhysics = obj.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(vent.Id); } } pc.Notify(Translator.GetString("PacifistMaxUsage")); return; } base.AbilityLimit -= 1f; if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(pc); } CollectionExtensions.Do(Main.AllAlivePlayerControls.Where(delegate(PlayerControl x) { if (!pc.Is(CustomRoles.Madmate)) { return x.CanUseKillButton(); } return x.CanUseKillButton() && x.GetCustomRole().IsCrewmate(); }), (Action)delegate(PlayerControl x) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) x.RPCPlayCustomSound("Dove"); x.ResetKillCooldown(); x.SetKillCooldown(); if (x.Is(CustomRoles.Mercenary)) { Mercenary.ClearSuicideTimer(); } x.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Pacifist)), Translator.GetString("PacifistSkillNotify"))); }); pc.RPCPlayCustomSound("Dove"); pc.Notify(string.Format(Translator.GetString("PacifistOnGuard"), base.AbilityLimit)); } public override bool CheckBootFromVent(PlayerPhysics physics, int ventId) { return base.AbilityLimit < 1f; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += PacifistAbilityUseGainWithEachTaskCompleted.GetFloat(); } return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = PacifistCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("PacifistVentButtonText"); } } internal class President : RoleBase { private const int Id = 12300; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem PresidentAbilityUses; private static OptionItem PresidentCanBeGuessedAfterRevealing; private static OptionItem HidePresidentEndCommand; private static OptionItem NeutralsSeePresident; private static OptionItem MadmatesSeePresident; private static OptionItem ImpsSeePresident; private static readonly Dictionary EndLimit = new Dictionary(); private static readonly Dictionary RevealLimit = new Dictionary(); private static readonly Dictionary CheckPresidentReveal = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(12300, TabGroup.CrewmateRoles, CustomRoles.President); PresidentAbilityUses = IntegerOptionItem.Create(12310, "PresidentAbilityUses", new IntegerValueRule(1, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]).SetValueFormat(OptionFormat.Times); PresidentCanBeGuessedAfterRevealing = BooleanOptionItem.Create(12311, "PresidentCanBeGuessedAfterRevealing", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]); NeutralsSeePresident = BooleanOptionItem.Create(12312, "NeutralsSeePresident", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]); MadmatesSeePresident = BooleanOptionItem.Create(12313, "MadmatesSeePresident", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]); ImpsSeePresident = BooleanOptionItem.Create(12314, "ImpsSeePresident", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]); HidePresidentEndCommand = BooleanOptionItem.Create(12315, "HidePresidentEndCommand", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.President]); } public override void Init() { playerIdList.Clear(); CheckPresidentReveal.Clear(); EndLimit.Clear(); RevealLimit.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); CheckPresidentReveal.Add(playerId, value: false); EndLimit.Add(playerId, PresidentAbilityUses.GetInt()); RevealLimit.Add(playerId, 1); } public override void Remove(byte playerId) { CheckPresidentReveal.Remove(playerId); EndLimit.Remove(playerId); RevealLimit.Remove(playerId); } public static bool CheckReveal(byte targetId) { bool value; return CheckPresidentReveal.TryGetValue(targetId, out value) && value; } public override string GetProgressText(byte PlayerId, bool comms) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) int value; return Utils.ColorString(Color32.op_Implicit((EndLimit[PlayerId] > 0) ? Utils.GetRoleColor(CustomRoles.President) : Color.gray), EndLimit.TryGetValue(PlayerId, out value) ? $"({value})" : "Invalid"); } public static void TryHideMsgForPresident() { ChatUpdatePatch.DoBlockChat = true; IRandom instance = IRandom.Instance; for (int i = 0; i < 20; i++) { string text = "/"; text = ((instance.Next(1, 100) >= 20) ? (text + "reveal") : (text + "finish")); PlayerControl val = Main.AllAlivePlayerControls.RandomElement(); DestroyableSingleton.Instance.Chat.AddChat(val, text, true); CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(text).EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } ChatUpdatePatch.DoBlockChat = false; } public static bool EndMsg(PlayerControl pc, string msg) { //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)pc == (Object)null || GameStates.IsExilling) { return false; } if (!pc.Is(CustomRoles.President)) { return false; } msg = msg.ToLower().TrimStart().TrimEnd(); int num; if (CheckCommond(ref msg, "finish|结束|结束会议|結束|結束會議")) { num = 1; } else { if (!CheckCommond(ref msg, "reveal|展示")) { return false; } num = 2; } if (!pc.IsAlive()) { Utils.SendMessage(Translator.GetString("PresidentDead"), pc.PlayerId); return false; } switch (num) { case 1: { if (HidePresidentEndCommand.GetBool()) { TryHideMsgForPresident(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (EndLimit[pc.PlayerId] < 1) { Utils.SendMessage(Translator.GetString("PresidentEndMax"), pc.PlayerId); return true; } EndLimit[pc.PlayerId]--; foreach (PlayerVoteArea item in (Il2CppArrayBase)(object)MeetingHud.Instance.playerStates) { if (!((Object)(object)item == (Object)null) && item.VotedFor < 253) { MeetingHud.Instance.RpcClearVote((int)item.TargetPlayerId); } } List list = new List(); MeetingHud.Instance.RpcVotingComplete(Il2CppStructArray.op_Implicit(list.ToArray()), (NetworkedPlayerInfo)null, true); MeetingHud.Instance.RpcClose(); break; } case 2: { if (HidePresidentEndCommand.GetBool()) { TryHideMsgForPresident(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (RevealLimit[pc.PlayerId] < 1) { Utils.SendMessage(Translator.GetString("PresidentRevealMax"), pc.PlayerId); return true; } RevealLimit[pc.PlayerId]--; CheckPresidentReveal[pc.PlayerId] = true; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if ((MadmatesSeePresident.GetBool() || !val.Is(CustomRoles.Madmate) || !((Object)(object)val != (Object)(object)pc)) && (NeutralsSeePresident.GetBool() || !val.GetCustomRole().IsNeutral()) && (ImpsSeePresident.GetBool() || (!val.GetCustomRole().IsImpostor() && !val.Is(CustomRoles.Crewpostor)))) { Utils.SendMessage(string.Format(Translator.GetString("PresidentRevealed"), pc.GetRealName()), val.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.President)), Translator.GetString("PresidentRevealTitle"))); } } SendRPC(pc.PlayerId, isEnd: false); break; } } return true; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); for (int i = 0; i < array.Length; i++) { if (exact) { if (msg == "/" + array[i]) { return true; } } else if (msg.StartsWith("/" + array[i])) { return true; } } return false; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (CheckPresidentReveal[target.PlayerId]) { killer.SetKillCooldown(0.9f); } return true; } private static void SendRPC(byte playerId, bool isEnd = true) { if (!isEnd) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)176, (SendOption)1, -1); val.Write(playerId); val.Write(CheckPresidentReveal[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } else { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)175, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void ReceiveRPC(MessageReader reader, PlayerControl pc, bool isEnd = true) { byte key = reader.ReadByte(); if (!isEnd) { bool value = reader.ReadBoolean(); if (CheckPresidentReveal.ContainsKey(key)) { CheckPresidentReveal[key] = value; } else { CheckPresidentReveal.Add(key, value: false); } } else { EndMsg(pc, "/finish"); } } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { if (CheckPresidentReveal[target.PlayerId] && !PresidentCanBeGuessedAfterRevealing.GetBool()) { guesser.ShowInfoMessage(isUI, Translator.GetString("GuessPresident")); return true; } return false; } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { if ((!target.Is(CustomRoles.President) || !seer.GetCustomRole().IsCrewmate() || seer.Is(CustomRoles.Madmate) || !CheckPresidentReveal[target.PlayerId]) && (!target.Is(CustomRoles.President) || !seer.Is(CustomRoles.Madmate) || !MadmatesSeePresident.GetBool() || !CheckPresidentReveal[target.PlayerId]) && (!target.Is(CustomRoles.President) || !seer.GetCustomRole().IsNeutral() || !NeutralsSeePresident.GetBool() || !CheckPresidentReveal[target.PlayerId])) { if (target.Is(CustomRoles.President) && seer.GetCustomRole().IsImpostor() && ImpsSeePresident.GetBool()) { return CheckPresidentReveal[target.PlayerId]; } return false; } return true; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return KnowRoleTarget(seer, target); } } internal class Psychic : RoleBase { private const int Id = 9400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem CanSeeNum; private static OptionItem Fresh; private static OptionItem CkshowEvil; private static OptionItem NBshowEvil; private static OptionItem NEshowEvil; private static OptionItem NCshowEvil; private static readonly HashSet RedPlayer = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9400, TabGroup.CrewmateRoles, CustomRoles.Psychic); CanSeeNum = IntegerOptionItem.Create(9402, "PsychicCanSeeNum", new IntegerValueRule(1, 15, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]).SetValueFormat(OptionFormat.Pieces); Fresh = BooleanOptionItem.Create(9406, "PsychicFresh", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]); CkshowEvil = BooleanOptionItem.Create(9403, "CrewKillingRed", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]); NBshowEvil = BooleanOptionItem.Create(9404, "NBareRed", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]); NEshowEvil = BooleanOptionItem.Create(9405, "NEareRed", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]); NCshowEvil = BooleanOptionItem.Create(9407, "NCareRed", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Psychic]); } public override void Init() { playerIdList.Clear(); RedPlayer.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } private static void SendRPC() { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)171, (SendOption)1, -1); val.Write(RedPlayer.Count); foreach (byte item in RedPlayer) { val.Write(item); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { int num = reader.ReadInt32(); RedPlayer.Clear(); for (int i = 0; i < num; i++) { RedPlayer.Add(reader.ReadByte()); } } public static bool IsRedForPsy(PlayerControl target, PlayerControl seer) { if ((Object)(object)target == (Object)null || (Object)(object)seer == (Object)null) { return false; } CustomRoles customRole = target.GetCustomRole(); if (seer.Is(CustomRoles.Madmate)) { if (!customRole.IsNK() && !customRole.IsNE()) { return customRole.IsCrewKiller(); } return true; } if (RedPlayer != null) { return RedPlayer.Contains(target.PlayerId); } return false; } public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInfo target) { if (Fresh.GetBool() || RedPlayer == null || RedPlayer.Count < 1) { GetRedName(); } } public static void GetRedName() { if (!HasEnabled || !((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => (x.Is(Custom_Team.Impostor) && !x.Is(CustomRoles.Trickster)) || x.Is(CustomRoles.Madmate) || x.Is(CustomRoles.Rascal) || x.Is(CustomRoles.Recruit) || x.Is(CustomRoles.Charmed) || x.Is(CustomRoles.Infected) || !x.Is(CustomRoles.Admired) || x.Is(CustomRoles.Contagious) || (x.GetCustomRole().IsCrewKiller() && CkshowEvil.GetBool()) || (x.GetCustomRole().IsNE() && NEshowEvil.GetBool()) || (x.GetCustomRole().IsNC() && NCshowEvil.GetBool()) || (x.GetCustomRole().IsNB() && NBshowEvil.GetBool())).ToList(); List BadList = new List(); CollectionExtensions.Do((IEnumerable)list, (Action)delegate(PlayerControl x) { BadList.Add(x.PlayerId); }); List AllList = new List(); CollectionExtensions.Do(Main.AllAlivePlayerControls.Where((PlayerControl x) => !BadList.Contains(x.PlayerId) && !x.Is(CustomRoles.Psychic)), (Action)delegate(PlayerControl x) { AllList.Add(x.PlayerId); }); int num = 1; for (int i = 1; i < CanSeeNum.GetInt(); i++) { if (IRandom.Instance.Next(0, 100) < 18) { num++; } } int val = CanSeeNum.GetInt() - num; num = Math.Min(num, BadList.Count); val = Math.Min(val, AllList.Count); if (num >= 1) { RedPlayer.Clear(); for (int j = 0; j < num; j++) { if (BadList.Count < 1) { break; } RedPlayer.Add(BadList[IRandom.Instance.Next(0, BadList.Count)]); BadList.RemoveAll(RedPlayer.Contains); } AllList.RemoveAll(RedPlayer.Contains); for (int k = 0; k < val; k++) { if (AllList.Count < 1) { break; } RedPlayer.Add(AllList[IRandom.Instance.Next(0, AllList.Count)]); AllList.RemoveAll(RedPlayer.Contains); } } Logger.Info($"需要{CanSeeNum.GetInt()}个红名,其中需要{num}个邪恶。计算后显示红名{RedPlayer.Count}个", "Psychic", escapeCRLF: true, 118, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Psychic.cs"); CollectionExtensions.Do((IEnumerable)RedPlayer, (Action)delegate(byte x) { Logger.Info($"红名:{x}: {Main.AllPlayerNames[x]}", "Psychic", escapeCRLF: true, 119, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Psychic.cs"); }); SendRPC(); } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!IsForMeeting || !IsRedForPsy(target, seer) || !seer.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), TargetPlayerName); } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!IsRedForPsy(target, seer) || !seer.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), ((TMP_Text)pva.NameText).text); } } internal class Randomizer : RoleBase { private const int Id = 7500; private static readonly HashSet playerIdList = new HashSet(); public static OptionItem BecomeBaitDelayNotify; public static OptionItem BecomeBaitDelayMin; public static OptionItem BecomeBaitDelayMax; public static OptionItem BecomeTrapperBlockMoveTime; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(7500, TabGroup.CrewmateRoles, CustomRoles.Randomizer); BecomeBaitDelayNotify = BooleanOptionItem.Create(7510, "BecomeBaitDelayNotify", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); BecomeBaitDelayMin = FloatOptionItem.Create(7511, "BaitDelayMin", new FloatValueRule(0f, 5f, 1f), 0f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]).SetValueFormat(OptionFormat.Seconds); BecomeBaitDelayMax = FloatOptionItem.Create(7512, "BaitDelayMax", new FloatValueRule(0f, 10f, 1f), 0f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]).SetValueFormat(OptionFormat.Seconds); BecomeTrapperBlockMoveTime = FloatOptionItem.Create(7513, "BecomeTrapperBlockMoveTime", new FloatValueRule(1f, 180f, 1f), 5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) { //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) if (inMeeting || isSuicide) { return; } switch (IRandom.Instance.Next(1, 5)) { case 1: { if (isSuicide && (Object)(object)target.GetRealKiller() != (Object)null) { if (!target.GetRealKiller().IsAlive()) { break; } killer = target.GetRealKiller(); } if (killer.PlayerId == target.PlayerId || killer.Is(CustomRoles.KillingMachine) || (killer.Is(CustomRoles.Oblivious) && Oblivious.ObliviousBaitImmune.GetBool())) { break; } bool flag = !isSuicide; if (!flag) { bool flag2; switch (target.GetRealKiller()?.GetCustomRole()) { case CustomRoles.Swooper: case CustomRoles.Wraith: flag2 = true; break; default: flag2 = false; break; } flag = flag2; } if (!flag && killer.Is(CustomRoles.KillingMachine) && killer.Is(CustomRoles.Oblivious) && (!killer.Is(CustomRoles.Oblivious) || Oblivious.ObliviousBaitImmune.GetBool())) { break; } killer.RPCPlayCustomSound("Congrats"); target.RPCPlayCustomSound("Congrats"); float val = ((!(BecomeBaitDelayMax.GetFloat() < BecomeBaitDelayMin.GetFloat())) ? ((float)IRandom.Instance.Next((int)BecomeBaitDelayMin.GetFloat(), (int)BecomeBaitDelayMax.GetFloat() + 1)) : 0f); val = Math.Max(val, 0.15f); if (val > 0.15f && BecomeBaitDelayNotify.GetBool()) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Bait)), string.Format(Translator.GetString("KillBaitNotify"), (int)val)), val); } Logger.Info(killer.GetNameWithRole() + " 击杀了萧暮触发自动报告 => " + target.GetNameWithRole(), "Randomizer", escapeCRLF: true, 88, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Randomizer.cs"); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Randomizer)), Translator.GetString("YouKillRandomizer1"))); new LateTask(delegate { if (GameStates.IsInTask) { killer.CmdReportDeadBody(target.Data); } }, val, "Bait Self Report"); break; } case 2: { Logger.Info(killer.GetNameWithRole() + " 击杀了萧暮触发暂时无法移动 => " + target.GetNameWithRole(), "Randomizer", escapeCRLF: true, 100, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Randomizer.cs"); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Randomizer)), Translator.GetString("YouKillRandomizer2"))); float tmpSpeed = Main.AllPlayerSpeed[killer.PlayerId]; Main.AllPlayerSpeed[killer.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[killer.PlayerId] = false; killer.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[killer.PlayerId] = Main.AllPlayerSpeed[killer.PlayerId] - 0.0001f + tmpSpeed; ReportDeadBodyPatch.CanReport[killer.PlayerId] = true; killer.MarkDirtySettings(); RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); }, BecomeTrapperBlockMoveTime.GetFloat(), "Trapper BlockMove"); break; } case 3: Logger.Info(killer.GetNameWithRole() + " 击杀了萧暮触发凶手CD变成600 => " + target.GetNameWithRole(), "Randomizer", escapeCRLF: true, 118, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Randomizer.cs"); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Randomizer)), Translator.GetString("YouKillRandomizer3"))); Main.AllPlayerKillCooldown[killer.PlayerId] = 600f; killer.SyncSettings(); break; case 4: { Logger.Info(killer.GetNameWithRole() + " 击杀了萧暮触发随机复仇 => " + target.GetNameWithRole(), "Randomizer", escapeCRLF: true, 125, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Randomizer.cs"); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Randomizer)), Translator.GetString("YouKillRandomizer4"))); List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.PlayerId != target.PlayerId && target.RpcCheckAndMurder(x, check: true)).ToList(); PlayerControl obj = list[IRandom.Instance.Next(0, list.Count)]; obj.SetDeathReason(PlayerState.DeathReason.Revenge); obj.RpcMurderPlayer(obj); obj.SetRealKiller(target); break; } } } } internal class Retributionist : RoleBase { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { if (PlayerControl.LocalPlayer.Is(CustomRoles.Retributionist) && !PlayerControl.LocalPlayer.IsAlive()) { CreateJudgeButton(__instance); } } } private const int Id = 11000; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem RetributionistCanKillNum; private static OptionItem MinimumPlayersAliveToRetri; private static OptionItem CanOnlyRetributeWithTasksDone; private static readonly Dictionary RetributionistRevenged = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(11000, TabGroup.CrewmateRoles, CustomRoles.Retributionist); RetributionistCanKillNum = IntegerOptionItem.Create(11010, "RetributionistCanKillNum", new IntegerValueRule(1, 15, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Retributionist]).SetValueFormat(OptionFormat.Players); MinimumPlayersAliveToRetri = IntegerOptionItem.Create(11011, "MinimumPlayersAliveToRetri", new IntegerValueRule(0, 15, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Retributionist]).SetValueFormat(OptionFormat.Players); CanOnlyRetributeWithTasksDone = BooleanOptionItem.Create(11012, "CanOnlyRetributeWithTasksDone", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Retributionist]); Options.OverrideTasksData.Create(11013, TabGroup.CrewmateRoles, CustomRoles.Retributionist); } public override void Init() { playerIdList.Clear(); RetributionistRevenged.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); RetributionistRevenged[playerId] = 0; } public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (seen == null) { seen = seer; } if (!seer.IsAlive() && seen.IsAlive()) { return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Retributionist)), " " + seen.PlayerId) + " "; } return string.Empty; } public static bool RetributionistMsgCheck(PlayerControl pc, string msg, bool isUI = false) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsInGame || (Object)(object)pc == (Object)null) { return false; } if (!pc.Is(CustomRoles.Retributionist)) { return false; } msg = msg.Trim().ToLower(); if (msg.Length < 4 || msg.Substring(0, 4) != "/ret") { return false; } if (RetributionistCanKillNum.GetInt() < 1) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillDisable")); return true; } if (Main.AllAlivePlayerControls.Length <= MinimumPlayersAliveToRetri.GetInt() && !pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillTooManyDead")); return true; } if (CanOnlyRetributeWithTasksDone.GetBool() && !pc.GetPlayerTaskState().IsTaskFinished && !pc.IsAlive() && !CopyCat.playerIdList.Contains(pc.PlayerId) && !Main.TasklessCrewmate.Contains(pc.PlayerId)) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillDisable")); return true; } if (pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistAliveKill")); return true; } if (msg == "/ret") { string text = Translator.GetString("PlayerIdList"); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { text = text + "\n" + val.PlayerId + " → (" + val.GetDisplayRoleAndSubName(val) + ") " + val.GetRealName(); } Utils.SendMessage(text, pc.PlayerId); return true; } if (RetributionistRevenged.TryGetValue(pc.PlayerId, out var value) && value >= RetributionistCanKillNum.GetInt()) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillMax")); return true; } RetributionistRevenged.TryAdd(pc.PlayerId, 0); PlayerControl target; try { int playerId = int.Parse(msg.Replace("/ret", string.Empty)); target = Utils.GetPlayerById(playerId); } catch { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillDead")); return true; } if ((Object)(object)target == (Object)null || !target.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("RetributionistKillDead")); return true; } if (target.Is(CustomRoles.Pestilence)) { pc.ShowInfoMessage(isUI, Translator.GetString("PestilenceImmune")); return true; } if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessMini")); return true; } if (target.Is(CustomRoles.Solsticer)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSolsticer")); return true; } if (target.Is(CustomRoles.Jinx) || target.Is(CustomRoles.CursedWolf)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessImmune")); return true; } if (!pc.RpcCheckAndMurder(target, check: true)) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessImmune")); return true; } Logger.Info(pc.GetNameWithRole() + " revenge " + target.GetNameWithRole(), "Retributionist", escapeCRLF: true, 162, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Retributionist.cs"); string Name = target.GetRealName(); RetributionistRevenged[pc.PlayerId]++; CustomSoundsManager.RPCPlayCustomSoundAll("AWP"); new LateTask(delegate { target.SetDeathReason(PlayerState.DeathReason.Revenge); if (GameStates.IsMeeting) { Main.PlayersDiedInMeeting.Add(target.PlayerId); target.RpcGuesserMurderPlayer(); MurderPlayerPatch.AfterPlayerDeathTasks(pc, target, inMeeting: true); } else { target.RpcMurderPlayer(target); Utils.NotifyRoles(null, null, isForMeeting: false, NoCache: true); } target.SetRealKiller(pc); new LateTask(delegate { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Utils.SendMessage(string.Format(Translator.GetString("RetributionistKillSucceed"), Name), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Retributionist)), Translator.GetString("RetributionistRevengeTitle")), logforChatManager: true); }, 0.6f, "Retributionist Kill"); }, 0.2f, "Retributionist Start Kill"); return true; } private static void SendRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)122, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC_Custom(MessageReader reader, PlayerControl pc) { int value = reader.ReadByte(); RetributionistMsgCheck(pc, $"/ret {value}", isUI: true); } private static void RetributionistOnClick(byte playerId) { Logger.Msg($"Click: ID {playerId}", "Retributionist UI", escapeCRLF: true, 208, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Retributionist.cs"); PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && GameStates.IsVoting) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { RetributionistMsgCheck(PlayerControl.LocalPlayer, $"/ret {playerId}", isUI: true); } else { SendRPC(playerId); } } } public override void OnMeetingHudStart(PlayerControl pc) { if (!pc.IsAlive()) { MeetingHudStartPatch.AddMsg(Translator.GetString("RetributionistDeadMsg"), pc.PlayerId); } } public static void CreateJudgeButton(MeetingHud __instance) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) PlayerVoteArea[] array = ((IEnumerable)__instance.playerStates).ToArray(); foreach (PlayerVoteArea pva in array) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); obj.GetComponent().sprite = CustomButton.Get("MeetingKillButton"); PassiveButton component = obj.GetComponent(); ((UnityEventBase)component.OnClick).RemoveAllListeners(); ((UnityEvent)component.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { RetributionistOnClick(pva.TargetPlayerId); })); } } } } internal class Reverie : RoleBase { private const int Id = 11100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem DefaultKillCooldown; private static OptionItem ReduceKillCooldown; private static OptionItem IncreaseKillCooldown; private static OptionItem MinKillCooldown; private static OptionItem MaxKillCooldown; private static OptionItem MisfireSuicide; private static OptionItem ResetCooldownMeeting; private static OptionItem ConvertedReverieRogue; private static readonly Dictionary NowCooldown = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(11100, TabGroup.CrewmateRoles, CustomRoles.Reverie); DefaultKillCooldown = FloatOptionItem.Create(11110, GeneralOption.DefaultKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 30f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]).SetValueFormat(OptionFormat.Seconds); ReduceKillCooldown = FloatOptionItem.Create(11111, GeneralOption.ReduceKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 7.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]).SetValueFormat(OptionFormat.Seconds); MinKillCooldown = FloatOptionItem.Create(11112, GeneralOption.MinKillCooldown, new FloatValueRule(0f, 180f, 2.5f), 2.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]).SetValueFormat(OptionFormat.Seconds); IncreaseKillCooldown = FloatOptionItem.Create(11113, "ReverieIncreaseKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]).SetValueFormat(OptionFormat.Seconds); MaxKillCooldown = FloatOptionItem.Create(11114, "ReverieMaxKillCooldown", new FloatValueRule(0f, 180f, 2.5f), 40f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]).SetValueFormat(OptionFormat.Seconds); MisfireSuicide = BooleanOptionItem.Create(11115, "ReverieMisfireSuicide", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]); ResetCooldownMeeting = BooleanOptionItem.Create(11116, "ReverieResetCooldownMeeting", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]); ConvertedReverieRogue = BooleanOptionItem.Create(11117, "ConvertedReverieKillAll", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Reverie]); } public override void Init() { playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); NowCooldown.Remove(playerId); } public override void OnReportDeadBody(PlayerControl HES, NetworkedPlayerInfo HIM) { foreach (byte key in NowCooldown.Keys) { if (ResetCooldownMeeting.GetBool()) { NowCooldown[key] = DefaultKillCooldown.GetFloat(); } } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = NowCooldown[id]; } public override bool CanUseImpostorVentButton(PlayerControl pc) { return false; } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool CanUseSabotage(PlayerControl pc) { return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return true; } float value = (((target.GetCustomRole().IsCrewmate() || target.Is(CustomRoles.Trickster)) && (!ConvertedReverieRogue.GetBool() || !killer.GetCustomSubRoles().Any((CustomRoles subrole) => subrole.IsConverted() || subrole == CustomRoles.Madmate))) ? (NowCooldown[killer.PlayerId] + IncreaseKillCooldown.GetFloat()) : (NowCooldown[killer.PlayerId] - ReduceKillCooldown.GetFloat())); NowCooldown[killer.PlayerId] = Math.Clamp(value, MinKillCooldown.GetFloat(), MaxKillCooldown.GetFloat()); killer.ResetKillCooldown(); killer.SyncSettings(); if (NowCooldown[killer.PlayerId] >= MaxKillCooldown.GetFloat() && MisfireSuicide.GetBool()) { killer.SetDeathReason(PlayerState.DeathReason.Misfire); killer.RpcMurderPlayer(killer); } return true; } } internal class Sheriff : RoleBase { private enum KillOptionList { SheriffCanKillAll, SheriffCanKillSeparately } private const int Id = 11200; private static OptionItem KillCooldown; private static OptionItem MisfireKillsTarget; private static OptionItem ShotLimitOpt; private static OptionItem ShowShotLimit; private static OptionItem CanKillAllAlive; private static OptionItem CanKillNeutrals; private static OptionItem CanKillNeutralsMode; private static OptionItem CanKillMadmate; private static OptionItem CanKillCharmed; private static OptionItem CanKillLovers; private static OptionItem CanKillSidekicks; private static OptionItem CanKillEgoists; private static OptionItem CanKillInfected; private static OptionItem CanKillContagious; private static OptionItem SidekickSheriffCanGoBerserk; private static OptionItem SetNonCrewCanKill; private static OptionItem NonCrewCanKillCrew; private static OptionItem NonCrewCanKillImp; private static OptionItem NonCrewCanKillNeutral; private float CurrentKillCooldown; private static readonly Dictionary KillTargetOptions = new Dictionary(); public static bool HasEnabled => CustomRoles.Sheriff.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(11200, TabGroup.CrewmateRoles, CustomRoles.Sheriff); KillCooldown = FloatOptionItem.Create(11210, GeneralOption.KillCooldown, new FloatValueRule(0f, 60f, 2.5f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]).SetValueFormat(OptionFormat.Seconds); MisfireKillsTarget = BooleanOptionItem.Create(11211, "SheriffMisfireKillsTarget", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); ShotLimitOpt = IntegerOptionItem.Create(11212, "SheriffShotLimit", new IntegerValueRule(1, 15, 1), 6, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]).SetValueFormat(OptionFormat.Times); ShowShotLimit = BooleanOptionItem.Create(11213, "SheriffShowShotLimit", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillAllAlive = BooleanOptionItem.Create(11215, "SheriffCanKillAllAlive", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillMadmate = BooleanOptionItem.Create(11217, "SheriffCanKillMadmate", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillCharmed = BooleanOptionItem.Create(11222, "SheriffCanKillCharmed", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillLovers = BooleanOptionItem.Create(11224, "SheriffCanKillLovers", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillSidekicks = BooleanOptionItem.Create(11223, "SheriffCanKillSidekick", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillEgoists = BooleanOptionItem.Create(11225, "SheriffCanKillEgoist", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillInfected = BooleanOptionItem.Create(11226, "SheriffCanKillInfected", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillContagious = BooleanOptionItem.Create(11227, "SheriffCanKillContagious", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillNeutrals = BooleanOptionItem.Create(11216, "SheriffCanKillNeutrals", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); CanKillNeutralsMode = StringOptionItem.Create(11214, "SheriffCanKillNeutralsMode", EnumHelper.GetAllNames(), 0, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(CanKillNeutrals); SetUpNeutralOptions(11230); SidekickSheriffCanGoBerserk = BooleanOptionItem.Create(11228, "SidekickSheriffCanGoBerserk", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); SetNonCrewCanKill = BooleanOptionItem.Create(11218, "SheriffSetMadCanKill", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sheriff]); NonCrewCanKillImp = BooleanOptionItem.Create(11219, "SheriffMadCanKillImp", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(SetNonCrewCanKill); NonCrewCanKillCrew = BooleanOptionItem.Create(11221, "SheriffMadCanKillCrew", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(SetNonCrewCanKill); NonCrewCanKillNeutral = BooleanOptionItem.Create(11220, "SheriffMadCanKillNeutral", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(SetNonCrewCanKill); } public override void Add(byte playerId) { CurrentKillCooldown = KillCooldown.GetFloat(); base.AbilityLimit = ShotLimitOpt.GetInt(); Logger.Info($"{Utils.GetPlayerById(playerId)?.GetNameWithRole()} : limit: {base.AbilityLimit}", "Sheriff", escapeCRLF: true, 78, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Sheriff.cs"); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } private static void SetUpNeutralOptions(int Id) { CustomRoles[] array = CustomRolesHelper.AllRoles.Where((CustomRoles x) => x.IsNeutral() && x != CustomRoles.Pestilence && x != CustomRoles.Glitch).ToArray(); for (int i = 0; i < array.Length; i++) { SetUpKillTargetOption(array[i], Id, defaultValue: true, CanKillNeutralsMode); Id++; } } private static void SetUpKillTargetOption(CustomRoles role, int Id, bool defaultValue = true, OptionItem parent = null) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (parent == null) { parent = Options.CustomRoleSpawnChances[CustomRoles.Sheriff]; } string roleName = Utils.GetRoleName(role); Dictionary replacementDictionary = new Dictionary { { "%role%", Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(role)), roleName) } }; KillTargetOptions[role] = BooleanOptionItem.Create(Id, "SheriffCanKill%role%", defaultValue, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(parent); KillTargetOptions[role].ReplacementDictionary = replacementDictionary; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = (IsUseKillButton(Utils.GetPlayerById(id)) ? CurrentKillCooldown : 300f); } public override bool CanUseKillButton(PlayerControl pc) { return IsUseKillButton(pc); } public bool IsUseKillButton(PlayerControl pc) { if (pc.IsAlive() && (CanKillAllAlive.GetBool() || GameStates.AlreadyDied)) { return base.AbilityLimit > 0f; } return false; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { base.AbilityLimit--; Logger.Info($"{killer.GetNameWithRole()} : Number of kills left: {base.AbilityLimit}", "Sheriff", escapeCRLF: true, 111, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Sheriff.cs"); SendSkillRPC(); if ((CanBeKilledBySheriff(target) && (!SetNonCrewCanKill.GetBool() || !killer.IsNonCrewSheriff()) && (!SidekickSheriffCanGoBerserk.GetBool() || !killer.Is(CustomRoles.Recruit))) || (SidekickSheriffCanGoBerserk.GetBool() && killer.Is(CustomRoles.Recruit)) || (SetNonCrewCanKill.GetBool() && killer.IsNonCrewSheriff() && ((target.GetCustomRole().IsImpostor() && NonCrewCanKillImp.GetBool()) || (target.GetCustomRole().IsCrewmate() && NonCrewCanKillCrew.GetBool()) || (target.GetCustomRole().IsNeutral() && NonCrewCanKillNeutral.GetBool())))) { killer.ResetKillCooldown(); if (base.AbilityLimit < 1f) { killer.SetKillCooldown(); } return true; } killer.SetDeathReason(PlayerState.DeathReason.Misfire); killer.RpcMurderPlayer(killer); return MisfireKillsTarget.GetBool(); } public override string GetProgressText(byte playerId, bool computervirus) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (!ShowShotLimit.GetBool()) { return ""; } return Utils.ColorString(Color32.op_Implicit(IsUseKillButton(Utils.GetPlayerById(playerId)) ? Utils.GetRoleColor(CustomRoles.Sheriff).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public static bool CanBeKilledBySheriff(PlayerControl player) { CustomRoles customRole = player.GetCustomRole(); List customSubRoles = player.GetCustomSubRoles(); bool flag = false; foreach (CustomRoles item in customSubRoles) { if (item == CustomRoles.Madmate) { flag = CanKillMadmate.GetBool(); } if (item == CustomRoles.Charmed) { flag = CanKillCharmed.GetBool(); } if (item == CustomRoles.Lovers) { flag = CanKillLovers.GetBool(); } if (item == CustomRoles.Recruit) { flag = CanKillSidekicks.GetBool(); } if (item == CustomRoles.Egoist) { flag = CanKillEgoists.GetBool(); } if (item == CustomRoles.Infected) { flag = CanKillInfected.GetBool(); } if (item == CustomRoles.Contagious) { flag = CanKillContagious.GetBool(); } if (item == CustomRoles.Rascal) { flag = true; } if (item == CustomRoles.Admired) { flag = false; } } OptionItem value; return customRole switch { CustomRoles.Trickster => false, CustomRoles.Pestilence => true, _ => customRole.GetCustomRoleTeam() switch { Custom_Team.Impostor => true, Custom_Team.Neutral => CanKillNeutrals.GetBool() && (CanKillNeutralsMode.GetValue() == 0 || !KillTargetOptions.TryGetValue(customRole, out value) || value.GetBool()), _ => flag, }, }; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("SheriffKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Kill"); } } internal class Snitch : RoleBase { private const int Id = 9500; private static readonly HashSet playerIdList = new HashSet(); private static readonly Color RoleColor = Utils.GetRoleColor(CustomRoles.Snitch); private static OptionItem OptionEnableTargetArrow; private static OptionItem OptionCanGetColoredArrow; private static OptionItem OptionCanFindNeutralKiller; private static OptionItem OptionCanFindMadmate; private static OptionItem OptionRemainingTasks; private static bool EnableTargetArrow; private static bool CanGetColoredArrow; private static bool CanFindNeutralKiller; private static bool CanFindMadmate; private static int RemainingTasksToBeFound; private static readonly Dictionary IsExposed = new Dictionary(); private static readonly Dictionary IsComplete = new Dictionary(); private static readonly HashSet TargetList = new HashSet(); private static readonly Dictionary TargetColorlist = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9500, TabGroup.CrewmateRoles, CustomRoles.Snitch); OptionEnableTargetArrow = BooleanOptionItem.Create(9510, "SnitchEnableTargetArrow", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Snitch]); OptionCanGetColoredArrow = BooleanOptionItem.Create(9511, "SnitchCanGetArrowColor", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(OptionEnableTargetArrow); OptionCanFindNeutralKiller = BooleanOptionItem.Create(9512, "SnitchCanFindNeutralKiller", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Snitch]); OptionCanFindMadmate = BooleanOptionItem.Create(9514, "SnitchCanFindMadmate", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Snitch]); OptionRemainingTasks = IntegerOptionItem.Create(9513, "SnitchRemainingTaskFound", new IntegerValueRule(0, 10, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Snitch]); Options.OverrideTasksData.Create(9520, TabGroup.CrewmateRoles, CustomRoles.Snitch); } public override void Init() { playerIdList.Clear(); EnableTargetArrow = OptionEnableTargetArrow.GetBool(); CanGetColoredArrow = OptionCanGetColoredArrow.GetBool(); CanFindNeutralKiller = OptionCanFindNeutralKiller.GetBool(); CanFindMadmate = OptionCanFindMadmate.GetBool(); RemainingTasksToBeFound = OptionRemainingTasks.GetInt(); IsExposed.Clear(); IsComplete.Clear(); TargetList.Clear(); TargetColorlist.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); IsExposed[playerId] = false; IsComplete[playerId] = false; } public override void Remove(byte playerId) { playerIdList.Remove(playerId); IsExposed.Remove(playerId); IsComplete.Remove(playerId); } private static bool IsThisRole(byte playerId) { return playerIdList.Contains(playerId); } private static bool GetExpose(PlayerControl pc) { if (!IsThisRole(pc.PlayerId) || !pc.IsAlive() || pc.Is(CustomRoles.Madmate)) { return false; } byte playerId = pc.PlayerId; return IsExposed[playerId]; } private static bool IsSnitchTarget(PlayerControl target) { if (HasEnabled) { if ((!target.Is(Custom_Team.Impostor) || target.Is(CustomRoles.Trickster)) && (!target.IsNeutralKiller() || !CanFindNeutralKiller) && (!target.Is(CustomRoles.Madmate) || !CanFindMadmate)) { if (target.Is(CustomRoles.Rascal)) { return CanFindMadmate; } return false; } return true; } return false; } private void CheckTask(PlayerControl snitch) { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (!snitch.IsAlive() || snitch.Is(CustomRoles.Madmate)) { return; } byte playerId = snitch.PlayerId; TaskState playerTaskState = snitch.GetPlayerTaskState(); PlayerControl[] allAlivePlayerControls; if (!IsExposed[playerId] && playerTaskState.RemainingTasksCount <= RemainingTasksToBeFound) { allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (IsSnitchTarget(val)) { TargetArrow.Add(val.PlayerId, playerId); } } IsExposed[playerId] = true; SendRPC(0, playerId); } if (IsComplete[playerId] || !playerTaskState.IsTaskFinished) { return; } allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (!IsSnitchTarget(val2)) { continue; } byte playerId2 = val2.PlayerId; NameColorManager.Add(playerId, playerId2); if (!EnableTargetArrow) { continue; } TargetArrow.Add(playerId, playerId2); if (!TargetList.Contains(playerId2)) { TargetList.Add(playerId2); if (CanGetColoredArrow) { TargetColorlist.Add(playerId2, val2.GetRoleColor()); } } } snitch.Notify(Translator.GetString("SnitchDoneTasks")); IsComplete[playerId] = true; SendRPC(1, playerId); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (!IsThisRole(player.PlayerId) || player.Is(CustomRoles.Madmate)) { return true; } CheckTask(player); return true; } private void SendRPC(byte RpcTypeId, byte snitchId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)115, (SendOption)1, -1); MessageExtensions.WriteNetObject(val, (InnerNetObject)(object)base._Player); val.Write(RpcTypeId); val.Write(snitchId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) byte b = reader.ReadByte(); byte b2 = reader.ReadByte(); switch (b) { case 0: { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (IsSnitchTarget(val2)) { TargetArrow.Add(val2.PlayerId, b2); } } IsExposed[b2] = true; break; } case 1: if (EnableTargetArrow) { PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!IsSnitchTarget(val)) { continue; } byte playerId = val.PlayerId; TargetArrow.Add(b2, playerId); if (!TargetList.Contains(playerId)) { TargetList.Add(playerId); if (CanGetColoredArrow) { TargetColorlist.Add(playerId, val.GetRoleColor()); } } } } IsComplete[b2] = true; break; } } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)seen == (Object)(object)seer) { return string.Empty; } if (!IsSnitchTarget(seen) || !IsComplete[seer.PlayerId]) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(RoleColor), "⚠"); } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (!EnableTargetArrow || isForMeeting || seer.Is(CustomRoles.Madmate)) { return string.Empty; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return string.Empty; } string text = ""; foreach (byte target2 in TargetList) { string arrows = TargetArrow.GetArrows(seer, target2); text += (CanGetColoredArrow ? Utils.ColorString(Color32.op_Implicit(TargetColorlist[target2]), arrows) : arrows); } return text; } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return string.Empty; } if (!IsSnitchTarget(seer) || !GetExpose(target)) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(RoleColor), "⚠"); } public override string GetSuffixOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return string.Empty; } if (!IsSnitchTarget(seer) || isForMeeting) { return string.Empty; } byte[] array = playerIdList.Where((byte s) => !Main.PlayerStates[s].IsDead && IsExposed[s]).ToArray(); if (array.Length == 0) { return string.Empty; } string text = "⚠"; if (EnableTargetArrow) { string text2 = text; int num = 0; byte[] array2 = new byte[array.Length]; byte[] array3 = array; foreach (byte b in array3) { array2[num] = b; num++; } text = text2 + TargetArrow.GetArrows(seer, array2); } return Utils.ColorString(Color32.op_Implicit(RoleColor), text); } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (target.GetPlayerTaskState().IsTaskFinished) { pc.ShowInfoMessage(isUI, Translator.GetString("EGGuessSnitchTaskDone")); return true; } return false; } } internal class Spiritualist : RoleBase { private const int Id = 9600; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem ShowGhostArrowEverySeconds; private static OptionItem ShowGhostArrowForSeconds; private static byte SpiritualistTarget = 0; private static readonly Dictionary ShowGhostArrowUntil = new Dictionary(); private static readonly Dictionary LastGhostArrowShowTime = new Dictionary(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9600, TabGroup.CrewmateRoles, CustomRoles.Spiritualist); ShowGhostArrowEverySeconds = FloatOptionItem.Create(9610, "SpiritualistShowGhostArrowEverySeconds", new FloatValueRule(1f, 60f, 1f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritualist]).SetValueFormat(OptionFormat.Seconds); ShowGhostArrowForSeconds = FloatOptionItem.Create(9611, "SpiritualistShowGhostArrowForSeconds", new FloatValueRule(1f, 60f, 1f), 2f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spiritualist]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); LastGhostArrowShowTime.Clear(); ShowGhostArrowUntil.Clear(); SpiritualistTarget = 0; } public override void Add(byte playerId) { playerIdList.Add(playerId); SpiritualistTarget = byte.MaxValue; LastGhostArrowShowTime.Add(playerId, 0L); ShowGhostArrowUntil.Add(playerId, 0L); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); LastGhostArrowShowTime.Remove(playerId); ShowGhostArrowUntil.Remove(playerId); } private static bool ShowArrow(byte playerId) { long timeStamp = Utils.GetTimeStamp(); if (LastGhostArrowShowTime[playerId] == 0L || LastGhostArrowShowTime[playerId] + (long)ShowGhostArrowEverySeconds.GetFloat() <= timeStamp) { LastGhostArrowShowTime[playerId] = timeStamp; ShowGhostArrowUntil[playerId] = timeStamp + (long)ShowGhostArrowForSeconds.GetFloat(); return true; } if (ShowGhostArrowUntil[playerId] >= timeStamp) { return true; } return false; } public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInfo target) { if (!((Object)(object)target == (Object)null)) { if (SpiritualistTarget != byte.MaxValue) { RemoveTarget(SpiritualistTarget); } SpiritualistTarget = target.PlayerId; } } public override void AfterMeetingTasks() { foreach (byte spiritualist in playerIdList) { if (((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.PlayerId == spiritualist)).IsAlive()) { LastGhostArrowShowTime[spiritualist] = 0L; ShowGhostArrowUntil[spiritualist] = 0L; PlayerControl val = ((IEnumerable)Main.AllPlayerControls).FirstOrDefault((Func)((PlayerControl a) => a.PlayerId == SpiritualistTarget)); if (!((Object)(object)val == (Object)null)) { TargetArrow.Add(spiritualist, val.PlayerId); CustomRpcSender customRpcSender = CustomRpcSender.Create("SpiritualistSendMessage", (SendOption)0); customRpcSender.StartMessage(val.GetClientId()); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(Translator.GetString("SpiritualistNoticeTitle")) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(Translator.GetString("SpiritualistNoticeMessage")).EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(val.Data.PlayerName) .EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } } } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!seer.Is(CustomRoles.Spiritualist) || !seer.IsAlive()) { return ""; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return ""; } if (GameStates.IsMeeting) { return ""; } if (SpiritualistTarget != byte.MaxValue && ShowArrow(seer.PlayerId)) { return Utils.ColorString(Color32.op_Implicit(seer.GetRoleColor()), TargetArrow.GetArrows(seer, SpiritualistTarget)); } return ""; } public static void RemoveTarget(byte player) { if (SpiritualistTarget != player) { return; } foreach (byte playerId in playerIdList) { TargetArrow.Remove(playerId, SpiritualistTarget); } SpiritualistTarget = byte.MaxValue; } } internal class Spy : RoleBase { private const int Id = 9700; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem SpyRedNameDur; private static OptionItem UseLimitOpt; private static OptionItem SpyAbilityUseGainWithEachTaskCompleted; private static OptionItem SpyInteractionBlocked; private static readonly Dictionary SpyRedNameList = new Dictionary(); private static bool change = false; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(9700, TabGroup.CrewmateRoles, CustomRoles.Spy); UseLimitOpt = IntegerOptionItem.Create(9710, "AbilityUseLimit", new IntegerValueRule(1, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spy]).SetValueFormat(OptionFormat.Times); SpyRedNameDur = FloatOptionItem.Create(9711, "SpyRedNameDur", new FloatValueRule(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spy]).SetValueFormat(OptionFormat.Seconds); SpyAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(9712, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spy]).SetValueFormat(OptionFormat.Times); SpyInteractionBlocked = BooleanOptionItem.Create(9713, "SpyInteractionBlocked", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Spy]); } public override void Init() { playerIdList.Clear(); SpyRedNameList.Clear(); change = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); base.AbilityLimit = UseLimitOpt.GetInt(); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public static void SendRPC(byte susId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)188, (SendOption)1, -1); val.Write(susId); val.Write(SpyRedNameList[susId].ToString()); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void SendRPC(byte susId, bool changeColor) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)189, (SendOption)1, -1); val.Write(susId); val.Write(changeColor); Logger.Info($"RPC to remove player {susId} from red name list and change `change` to {changeColor}", "Spy", escapeCRLF: true, 67, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Spy.cs"); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader, bool isRemove = false) { if (isRemove) { SpyRedNameList.Remove(reader.ReadByte()); change = reader.ReadBoolean(); return; } byte key = reader.ReadByte(); if (long.TryParse(reader.ReadString(), out var result)) { SpyRedNameList[key] = result; } } public bool OnKillAttempt(PlayerControl killer, PlayerControl target) { if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null) { return false; } if (killer.PlayerId == target.PlayerId) { return true; } if (base.AbilityLimit >= 1f && killer.IsAlive()) { base.AbilityLimit -= 1f; SendSkillRPC(); SpyRedNameList.TryAdd(killer.PlayerId, Utils.GetTimeStamp()); SendRPC(killer.PlayerId); if (SpyInteractionBlocked.GetBool()) { killer.SetKillCooldown(10f); } Utils.NotifyRoles(target); return false; } return true; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { return OnKillAttempt(killer, target); } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if ((Object)(object)pc == (Object)null || SpyRedNameList.Count == 0) { return; } change = false; foreach (KeyValuePair spyRedName in SpyRedNameList) { if ((spyRedName.Value + SpyRedNameDur.GetInt() < Utils.GetTimeStamp() || !GameStates.IsInTask) && SpyRedNameList.ContainsKey(spyRedName.Key)) { SpyRedNameList.Remove(spyRedName.Key); change = true; SendRPC(spyRedName.Key, change); } } if (change && GameStates.IsInTask) { Utils.NotifyRoles(pc); } } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += SpyAbilityUseGainWithEachTaskCompleted.GetFloat(); SendSkillRPC(); } return true; } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); return string.Concat(str1: Utils.ColorString(Color32.op_Implicit((!(base.AbilityLimit < 1f)) ? Color.white : Color.red), $" - {Math.Round(base.AbilityLimit, 1)}"), str0: "" + Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { if (!seer.Is(CustomRoles.Spy) || !SpyRedNameList.ContainsKey(target.PlayerId)) { return ""; } return "#BA4A00"; } } internal class SuperStar : RoleBase { private const int Id = 7150; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem EveryOneKnowSuperStar; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(7150, TabGroup.CrewmateRoles, CustomRoles.SuperStar); EveryOneKnowSuperStar = BooleanOptionItem.Create(7152, "EveryOneKnowSuperStar", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.SuperStar]); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!seen.Is(CustomRoles.SuperStar) || (seer.PlayerId != seen.PlayerId && !EveryOneKnowSuperStar.GetBool())) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.SuperStar)), "★"); } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { return !Main.AllAlivePlayerControls.Any((PlayerControl x) => x.PlayerId != killer.PlayerId && x.PlayerId != target.PlayerId && Vector2.Distance(Vector2.op_Implicit(((Component)x).transform.position), Vector2.op_Implicit(((Component)target).transform.position)) < 2f); } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { if (role == CustomRoles.SuperStar) { pc.ShowInfoMessage(isUI, Translator.GetString("GuessSuperStar")); return true; } return false; } public static bool VisibleToEveryone(PlayerControl target) { if (target.Is(CustomRoles.SuperStar)) { return EveryOneKnowSuperStar.GetBool(); } return false; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) { return VisibleToEveryone(target); } } internal class Swapper : RoleBase { [HarmonyPatch(typeof(MeetingHud), "Start")] private class StartMeetingPatch { public static void Postfix(MeetingHud __instance) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if (PlayerControl.LocalPlayer.GetRoleClass() is Swapper swapper && PlayerControl.LocalPlayer.IsAlive()) { swapper.CreateSwapperButton(__instance); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } Vote.Clear(); VoteTwo.Clear(); PlayerControl[] array = Main.AllAlivePlayerControls.ToArray(); foreach (PlayerControl val in array) { if (val.Is(CustomRoles.Swapper) && val.IsAlive()) { Vote.Add(val.PlayerId, 253); VoteTwo.Add(val.PlayerId, 253); MeetingHudStartPatch.msgToSend.Add((Translator.GetString("SwapHelp"), val.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle")))); if (val.GetRoleClass() is Swapper swapper2) { swapper2.SendSkillRPC(); } ResultSent.Clear(); } } } } private const int Id = 12400; private static OptionItem SwapMax; private static OptionItem CanSwapSelf; private static OptionItem OptCanStartMeeting; private static OptionItem TryHideMsg; private static readonly HashSet ResultSent = new HashSet(); private static readonly Dictionary Vote = new Dictionary(); private static readonly Dictionary VoteTwo = new Dictionary(); public static bool HasEnabled => CustomRoles.Swapper.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; private static List PlayerIdList => (from x in Main.PlayerStates.Values where x.MainRole == CustomRoles.Swapper select x into p select p.PlayerId).ToList(); public override void SetupCustomOption() { Options.SetupRoleOptions(12400, TabGroup.CrewmateRoles, CustomRoles.Swapper); SwapMax = IntegerOptionItem.Create(12403, "SwapperMax", new IntegerValueRule(1, 999, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]).SetValueFormat(OptionFormat.Times); CanSwapSelf = BooleanOptionItem.Create(12402, "CanSwapSelfVotes", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]); OptCanStartMeeting = BooleanOptionItem.Create(12404, GeneralOption.CanUseMeetingButton, defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]); TryHideMsg = BooleanOptionItem.Create(12405, "SwapperTryHideMsg", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Swapper]); } public override void Init() { Vote.Clear(); VoteTwo.Clear(); ResultSent.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = SwapMax.GetInt(); } public override bool OnCheckStartMeeting(PlayerControl reporter) { return OptCanStartMeeting.GetBool(); } public override string GetProgressText(byte PlayerId, bool comms) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Swapper).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!IsForMeeting || !seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), target.PlayerId.ToString()) + " " + TargetPlayerName; } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!seer.IsAlive() || !target.IsAlive()) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), target.PlayerId.ToString()) + " " + ((TMP_Text)pva.NameText).text; } public bool SwapMsg(PlayerControl pc, string msg, bool isUI = false) { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0833: Unknown result type (might be due to invalid IL or missing references) //IL_0838: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_07fa: Unknown result type (might be due to invalid IL or missing references) //IL_07ff: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_073c: Unknown result type (might be due to invalid IL or missing references) //IL_05c7: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Unknown result type (might be due to invalid IL or missing references) //IL_06b0: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_06fe: Unknown result type (might be due to invalid IL or missing references) //IL_0703: Unknown result type (might be due to invalid IL or missing references) string text = msg; if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (!GameStates.IsMeeting || (Object)(object)base._Player == (Object)null || GameStates.IsExilling) { return false; } msg = msg.ToLower().TrimStart().TrimEnd(); int num; if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id|編號|玩家編號")) { num = 1; } else { if (!CheckCommond(ref msg, "sw|换票|换|換票|換|swap|st", exact: false)) { return false; } num = 2; } if (!pc.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("SwapDead")); return true; } switch (num) { case 1: Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId); return true; case 2: { if (TryHideMsg.GetBool()) { GuessManager.TryHideMsg(); ChatManager.SendPreviousMessagesToAll(); } else if (((InnerNetObject)pc).AmOwner && !isUI) { Utils.SendMessage(text, byte.MaxValue, pc.GetRealName()); } if (!MsgToPlayerAndRole(msg, out var id, out var error) && id != 253) { Utils.SendMessage(error, pc.PlayerId); return true; } if (id == 253) { Vote.TryAdd(pc.PlayerId, 253); VoteTwo.TryAdd(pc.PlayerId, 253); Vote[pc.PlayerId] = 253; VoteTwo[pc.PlayerId] = 253; pc.ShowInfoMessage(isUI, Translator.GetString("CancelSwap"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } PlayerControl playerById = Utils.GetPlayerById(id); if ((Object)(object)playerById != (Object)null) { if (base.AbilityLimit <= 0f) { pc.ShowInfoMessage(isUI, Translator.GetString("SwapperTrialMax"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } if (!Vote.ContainsKey(pc.PlayerId) || !VoteTwo.ContainsKey(pc.PlayerId)) { Vote.TryAdd(pc.PlayerId, 253); VoteTwo.TryAdd(pc.PlayerId, 253); Vote[pc.PlayerId] = 253; VoteTwo[pc.PlayerId] = 253; pc.ShowInfoMessage(isUI, Translator.GetString("SwapNull"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } PlayerControl val = playerById; if (pc.PlayerId == val.PlayerId && !CanSwapSelf.GetBool()) { pc.ShowInfoMessage(isUI, Translator.GetString("CantSwapSelf"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } if ((Object)(object)val == (Object)null || !val.IsAlive()) { pc.ShowInfoMessage(isUI, Translator.GetString("SwapNull"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } if (Vote[pc.PlayerId] != 253 && VoteTwo[pc.PlayerId] != 253) { PlayerControl playerById2 = Utils.GetPlayerById(Vote[pc.PlayerId]); PlayerControl playerById3 = Utils.GetPlayerById(VoteTwo[pc.PlayerId]); if ((Object)(object)playerById2 == (Object)null || (Object)(object)playerById3 == (Object)null || !playerById2.IsAlive() || !playerById3.IsAlive()) { Vote.TryAdd(pc.PlayerId, 253); VoteTwo.TryAdd(pc.PlayerId, 253); Vote[pc.PlayerId] = 253; VoteTwo[pc.PlayerId] = 253; pc.ShowInfoMessage(isUI, Translator.GetString("CancelSwapDueToTarget"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } else { pc.ShowInfoMessage(isUI, string.Format(Translator.GetString("SwapperPreResult"), playerById2.GetRealName(), playerById3.GetRealName()), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } return true; } if (Vote[pc.PlayerId] == 253 && VoteTwo[pc.PlayerId] == 253) { Vote[pc.PlayerId] = val.PlayerId; pc.ShowInfoMessage(isUI, Translator.GetString("Swap1"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } if (Vote[pc.PlayerId] != 253 && VoteTwo[pc.PlayerId] == 253) { if (val.PlayerId != Vote[pc.PlayerId]) { VoteTwo[pc.PlayerId] = val.PlayerId; pc.ShowInfoMessage(isUI, Translator.GetString("Swap2"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); PlayerControl playerById4 = Utils.GetPlayerById(Vote[pc.PlayerId]); PlayerControl playerById5 = Utils.GetPlayerById(VoteTwo[pc.PlayerId]); if ((Object)(object)playerById4 == (Object)null || (Object)(object)playerById5 == (Object)null || !playerById4.IsAlive() || !playerById5.IsAlive()) { Vote.TryAdd(pc.PlayerId, 253); VoteTwo.TryAdd(pc.PlayerId, 253); Vote[pc.PlayerId] = 253; VoteTwo[pc.PlayerId] = 253; pc.ShowInfoMessage(isUI, Translator.GetString("CancelSwapDueToTarget"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } else { pc.ShowInfoMessage(isUI, string.Format(Translator.GetString("SwapperPreResult"), playerById4.GetRealName(), playerById5.GetRealName()), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } } else { pc.ShowInfoMessage(isUI, Translator.GetString("Swap1=Swap2"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } return true; } if (Vote[pc.PlayerId] == 253 && VoteTwo[pc.PlayerId] != 253) { Vote.TryAdd(pc.PlayerId, 253); VoteTwo.TryAdd(pc.PlayerId, 253); Vote[pc.PlayerId] = 253; VoteTwo[pc.PlayerId] = 253; pc.ShowInfoMessage(isUI, Translator.GetString("CancelSwapDueToTarget"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); return true; } } else { pc.ShowInfoMessage(isUI, Translator.GetString("SwapNull"), Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } break; } } return true; } public static void CheckSwapperTarget(byte deadid) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (deadid == 253) { return; } foreach (byte playerId in PlayerIdList) { if (Vote.TryGetValue(playerId, out var value) && VoteTwo.TryGetValue(playerId, out var value2) && (value == deadid || value2 == deadid)) { Vote.TryAdd(playerId, 253); VoteTwo.TryAdd(playerId, 253); Vote[playerId] = 253; VoteTwo[playerId] = 253; Utils.SendMessage(Translator.GetString("CancelSwapDueToTarget"), playerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); } } } public void SwapVotes(MeetingHud __instance) { //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) byte playerId = _state.PlayerId; if (ResultSent.Contains(playerId)) { return; } PlayerControl playerById = Utils.GetPlayerById(playerId); if ((Object)(object)playerById == (Object)null || !playerById.IsAlive() || !Vote.TryGetValue(playerById.PlayerId, out var value) || !VoteTwo.TryGetValue(playerById.PlayerId, out var value2) || value == 253 || value2 == 253 || value == value2) { return; } PlayerControl playerById2 = Utils.GetPlayerById(value); PlayerControl playerById3 = Utils.GetPlayerById(value2); if ((Object)(object)playerById2 == (Object)null || (Object)(object)playerById3 == (Object)null || !playerById2.IsAlive() || !playerById3.IsAlive()) { return; } List list = new List(); PlayerVoteArea[] array = ((IEnumerable)__instance.playerStates).ToArray(); foreach (PlayerVoteArea val in array) { if (val.VotedFor == playerById2.PlayerId && !val.AmDead) { list.Add(val.TargetPlayerId); val.VotedFor = playerById3.PlayerId; CheckForEndVotingPatch.ReturnChangedPva(val); } } array = ((IEnumerable)__instance.playerStates).ToArray(); foreach (PlayerVoteArea val2 in array) { if (val2.VotedFor == playerById3.PlayerId && !val2.AmDead && !list.Contains(val2.TargetPlayerId)) { val2.VotedFor = playerById2.PlayerId; CheckForEndVotingPatch.ReturnChangedPva(val2); } } if (!ResultSent.Contains(playerId)) { ResultSent.Add(playerId); Utils.SendMessage(string.Format(Translator.GetString("SwapVote"), playerById2.GetRealName(), playerById3.GetRealName()), byte.MaxValue, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Swapper)), Translator.GetString("SwapTitle"))); base.AbilityLimit -= 1f; SendSkillRPC(); } } private static bool MsgToPlayerAndRole(string msg, out byte id, out string error) { if (msg.StartsWith("/")) { msg = msg.Replace("/", string.Empty); } MatchCollection matchCollection = new Regex("\\d+").Matches(msg); string text = string.Empty; for (int i = 0; i < matchCollection.Count; i++) { text += matchCollection[i]; } if (int.TryParse(text, out var result) && result <= 255) { id = Convert.ToByte(result); PlayerControl playerById = Utils.GetPlayerById(id); if ((Object)(object)playerById == (Object)null || !playerById.IsAlive()) { error = Translator.GetString("SwapNull"); return false; } error = string.Empty; return true; } id = 0; error = Translator.GetString("SwapHelp"); return false; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); for (int i = 0; i < array.Length; i++) { if (exact) { if (msg == "/" + array[i]) { return true; } } else if (msg.StartsWith("/" + array[i])) { msg = msg.Replace("/" + array[i], string.Empty); return true; } } return false; } private static void SendSwapRPC(byte playerId) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)167, (SendOption)1, -1); val.Write(playerId); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveSwapRPC(MessageReader reader, PlayerControl pc) { byte value = reader.ReadByte(); if (Main.PlayerStates[pc.PlayerId].RoleClass is Swapper swapper) { swapper.SwapMsg(pc, $"/sw {value}"); } } private void SwapperOnClick(byte playerId, MeetingHud __instance) { Logger.Msg($"Click: ID {playerId}", "Swapper UI", escapeCRLF: true, 349, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Swapper.cs"); PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive() && GameStates.IsVoting) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { SwapMsg(PlayerControl.LocalPlayer, $"/sw {playerId}", isUI: true); } else { SendSwapRPC(playerId); } if (PlayerControl.LocalPlayer.Is(CustomRoles.Swapper) && PlayerControl.LocalPlayer.IsAlive()) { CreateSwapperButton(__instance); } } } public void CreateSwapperButton(MeetingHud __instance) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) foreach (PlayerVoteArea pva in (Il2CppArrayBase)(object)__instance.playerStates) { PlayerControl playerById = Utils.GetPlayerById(pva.TargetPlayerId); _ = PlayerControl.LocalPlayer; if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { GameObject obj = Object.Instantiate(((Component)pva.Buttons.transform.Find("CancelButton")).gameObject, ((Component)pva).transform); ((Object)obj).name = "ShootButton"; obj.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); SpriteRenderer component = obj.GetComponent(); PassiveButton component2 = obj.GetComponent(); component.sprite = CustomButton.Get("SwapNo"); ((UnityEventBase)component2.OnClick).RemoveAllListeners(); ((UnityEvent)component2.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { SwapperOnClick(pva.TargetPlayerId, __instance); })); } } } } internal class TaskManager : RoleBase { private const int Id = 7200; private static readonly HashSet playerIdList = new HashSet(); public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(7200, TabGroup.CrewmateRoles, CustomRoles.TaskManager); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override string GetProgressText(byte PlayerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[PlayerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); string value2 = (comms ? "?" : $"{GameData.Instance.CompletedTasks}"); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(50, 2, stringBuilder2); handler.AppendLiteral(" - "); handler.AppendFormatted(value2); handler.AppendLiteral("/"); handler.AppendFormatted(GameData.Instance.TotalTasks); handler.AppendLiteral(""); stringBuilder2.Append(ref handler); return stringBuilder.ToString(); } } internal class Telecommunication : RoleBase { private const int Id = 12500; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem CanCheckCamera; private static OptionItem CanVent; private static bool IsAdminWatch; private static bool IsVitalWatch; private static bool IsDoorLogWatch; private static bool IsCameraWatch; private static int Count = 0; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase { get { if (!CanVent.GetBool()) { return CustomRoles.Crewmate; } return CustomRoles.Engineer; } } public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; public override void SetupCustomOption() { Options.SetupRoleOptions(12500, TabGroup.CrewmateRoles, CustomRoles.Telecommunication); CanCheckCamera = BooleanOptionItem.Create(12510, "CanCheckCamera", defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Telecommunication]); CanVent = BooleanOptionItem.Create(12514, GeneralOption.CanVent, defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Telecommunication]); } public override void Init() { playerIdList.Clear(); IsAdminWatch = false; IsVitalWatch = false; IsDoorLogWatch = false; IsCameraWatch = false; } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } public static bool CanUseVent() { return CanVent.GetBool(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } public override void OnFixedUpdateLowLoad(PlayerControl player) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) Count--; if (Count > 0) { return; } Count = 5; bool flag = false; bool flag2 = false; bool flag3 = false; bool flag4 = false; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (Pelican.IsEaten(val.PlayerId) || val.inVent) { continue; } try { Vector2 val2 = Vector2.op_Implicit(((Component)val).transform.position); byte activeMapId = Utils.GetActiveMapId(); MapNames map = (MapNames)activeMapId; switch (activeMapId) { case 0: if (!Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["SkeldAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableSkeldCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["SkeldCamera"]) <= DisableDevice.UsableDistance(map); } break; case 1: if (!Options.DisableMiraHQAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["MiraHQAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableMiraHQDoorLog.GetBool()) { flag3 |= Vector2.Distance(val2, DisableDevice.DevicePos["MiraHQDoorLog"]) <= DisableDevice.UsableDistance(map); } break; case 2: if (!Options.DisablePolusAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusLeftAdmin"]) <= DisableDevice.UsableDistance(map); flag |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusRightAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisablePolusCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisablePolusVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["PolusVital"]) <= DisableDevice.UsableDistance(map); } break; case 3: if (!Options.DisableSkeldAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["DleksAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableSkeldCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["DleksCamera"]) <= DisableDevice.UsableDistance(map); } break; case 4: if (!Options.DisableAirshipCockpitAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipCockpitAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipRecordsAdmin.GetBool()) { flag |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipRecordsAdmin"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipCamera.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableAirshipVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["AirshipVital"]) <= DisableDevice.UsableDistance(map); } break; case 5: if (!Options.DisableFungleBinoculars.GetBool()) { flag2 |= Vector2.Distance(val2, DisableDevice.DevicePos["FungleCamera"]) <= DisableDevice.UsableDistance(map); } if (!Options.DisableFungleVital.GetBool()) { flag4 |= Vector2.Distance(val2, DisableDevice.DevicePos["FungleVital"]) <= DisableDevice.UsableDistance(map); } break; } } catch (Exception ex) { Logger.Error(ex.ToString(), "AntiAdmin", escapeCRLF: true, 126, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Telecommunication.cs"); } } bool flag5 = false; flag5 |= IsAdminWatch != flag; IsAdminWatch = flag; flag5 |= IsVitalWatch != flag4; IsVitalWatch = flag4; flag5 |= IsDoorLogWatch != flag3; IsDoorLogWatch = flag3; if (CanCheckCamera.GetBool()) { flag5 |= IsCameraWatch != flag2; IsCameraWatch = flag2; } if (!flag5) { return; } foreach (byte playerId in playerIdList) { Utils.NotifyRoles(Utils.GetPlayerById(playerId), null, isForMeeting: false, NoCache: false, ForceLoop: false); } } public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) if (seer.PlayerId != seen.PlayerId || isForMeeting) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); if (IsAdminWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), "★")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), Translator.GetString("AdminWarning"))); } if (IsVitalWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), "★")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), Translator.GetString("VitalsWarning"))); } if (IsDoorLogWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), "★")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), Translator.GetString("DoorlogWarning"))); } if (IsCameraWatch) { stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), "★")).Append(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Telecommunication)), Translator.GetString("CameraWarning"))); } return stringBuilder.ToString(); } } internal class TimeManager : RoleBase { private const int Id = 9800; private static readonly HashSet playerIdList = new HashSet(); public static OptionItem IncreaseMeetingTime; public static OptionItem MeetingTimeLimit; public static OptionItem MadMinMeetingTimeLimit; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9800, TabGroup.CrewmateRoles, CustomRoles.TimeManager); IncreaseMeetingTime = IntegerOptionItem.Create(9810, "TimeManagerIncreaseMeetingTime", new IntegerValueRule(5, 30, 1), 15, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeManager]).SetValueFormat(OptionFormat.Seconds); MeetingTimeLimit = IntegerOptionItem.Create(9811, "TimeManagerLimitMeetingTime", new IntegerValueRule(100, 900, 10), 300, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeManager]).SetValueFormat(OptionFormat.Seconds); MadMinMeetingTimeLimit = IntegerOptionItem.Create(9812, "MadTimeManagerLimitMeetingTime", new IntegerValueRule(5, 150, 5), 30, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeManager]).SetValueFormat(OptionFormat.Seconds); Options.OverrideTasksData.Create(9813, TabGroup.CrewmateRoles, CustomRoles.TimeManager); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } private static int AdditionalTime(byte id) { PlayerControl playerById = Utils.GetPlayerById(id); if (!playerIdList.Contains(id) || !playerById.IsAlive()) { return 0; } return IncreaseMeetingTime.GetInt() * playerById.GetPlayerTaskState().CompletedTasksCount; } public static int TotalIncreasedMeetingTime() { int num = 0; foreach (byte playerId in playerIdList) { num = ((!Utils.GetPlayerById(playerId).Is(CustomRoles.Madmate)) ? (num + AdditionalTime(playerId)) : (num - AdditionalTime(playerId))); } Logger.Info($"{num}second", "TimeManager.TotalIncreasedMeetingTime", escapeCRLF: true, 55, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\TimeManager.cs"); return num; } } internal class TimeMaster : RoleBase { private const int Id = 9900; private static OptionItem TimeMasterSkillCooldown; private static OptionItem TimeMasterSkillDuration; private static OptionItem TimeMasterMaxUses; private static OptionItem TimeMasterAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary TimeMasterBackTrack = new Dictionary(); private static readonly Dictionary TimeMasterNum = new Dictionary(); private static readonly Dictionary TimeMasterInProtect = new Dictionary(); public static bool HasEnabled => CustomRoles.TimeMaster.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupRoleOptions(9900, TabGroup.CrewmateRoles, CustomRoles.TimeMaster); TimeMasterSkillCooldown = FloatOptionItem.Create(9910, "TimeMasterSkillCooldown", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeMaster]).SetValueFormat(OptionFormat.Seconds); TimeMasterSkillDuration = FloatOptionItem.Create(9911, "TimeMasterSkillDuration", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeMaster]).SetValueFormat(OptionFormat.Seconds); TimeMasterMaxUses = IntegerOptionItem.Create(9912, "TimeMasterMaxUses", new IntegerValueRule(0, 20, 1), 1, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeMaster]).SetValueFormat(OptionFormat.Times); TimeMasterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(9913, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TimeMaster]).SetValueFormat(OptionFormat.Times); } public override void Init() { TimeMasterBackTrack.Clear(); TimeMasterNum.Clear(); TimeMasterInProtect.Clear(); } public override void Add(byte playerId) { TimeMasterNum.TryAdd(playerId, 0); base.AbilityLimit = TimeMasterMaxUses.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = TimeMasterSkillCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += TimeMasterAbilityUseGainWithEachTaskCompleted.GetFloat(); } return true; } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.ReportButton).OverrideText(Translator.GetString("ReportButtonText")); ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("TimeMasterVentButtonText"); } public override void OnFixedUpdateLowLoad(PlayerControl player) { if (TimeMasterInProtect.TryGetValue(player.PlayerId, out var value) && value + TimeMasterSkillDuration.GetInt() < Utils.GetTimeStamp()) { TimeMasterInProtect.Remove(player.PlayerId); if (!Options.DisableShieldAnimations.GetBool()) { player.RpcGuardAndKill(); } else { player.RpcResetAbilityCooldown(); } player.Notify(Translator.GetString("TimeMasterSkillStop")); } } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (TimeMasterInProtect.ContainsKey(target.PlayerId) && killer.PlayerId != target.PlayerId && TimeMasterInProtect[target.PlayerId] + TimeMasterSkillDuration.GetInt() >= Utils.GetTimeStamp(DateTime.UtcNow)) { PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!killer.Is(CustomRoles.Pestilence) && TimeMasterBackTrack.TryGetValue(val.PlayerId, out var value) && val.CanBeTeleported()) { val.RpcTeleport(value); } } killer.SetKillCooldown(-1f, target, forceAnime: true); return false; } return true; } public override void OnEnterVent(PlayerControl pc, Vent AirConditioning) { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (!(base.AbilityLimit >= 1f)) { return; } base.AbilityLimit -= 1f; TimeMasterInProtect.Remove(pc.PlayerId); TimeMasterInProtect.Add(pc.PlayerId, Utils.GetTimeStamp()); if (!pc.IsModClient()) { pc.RpcGuardAndKill(pc); } pc.Notify(Translator.GetString("TimeMasterOnGuard"), TimeMasterSkillDuration.GetFloat()); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (TimeMasterBackTrack.TryGetValue(val.PlayerId, out var value)) { if (val.CanBeTeleported() && val.PlayerId != pc.PlayerId) { val.RpcTeleport(value); } else if ((Object)(object)pc == (Object)(object)val && val != null) { PlayerPhysics myPhysics = val.MyPhysics; if (myPhysics != null) { myPhysics.RpcBootFromVent(Main.LastEnteredVent.TryGetValue(val.PlayerId, out var value2) ? value2.Id : val.PlayerId); } } TimeMasterBackTrack.Remove(val.PlayerId); } else { TimeMasterBackTrack.Add(val.PlayerId, val.GetCustomPosition()); } } } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Time Master"); } } internal class Tracefinder : RoleBase { private const int Id = 7300; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VitalsDuration; private static OptionItem VitalsCooldown; private static OptionItem ArrowDelayMin; private static OptionItem ArrowDelayMax; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(7300, TabGroup.CrewmateRoles, CustomRoles.Tracefinder); VitalsCooldown = FloatOptionItem.Create(7310, GeneralOption.ScientistBase_BatteryCooldown, new FloatValueRule(1f, 60f, 1f), 5f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tracefinder]).SetValueFormat(OptionFormat.Seconds); VitalsDuration = FloatOptionItem.Create(7311, GeneralOption.ScientistBase_BatteryDuration, new FloatValueRule(1f, 30f, 1f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tracefinder]).SetValueFormat(OptionFormat.Seconds); ArrowDelayMin = FloatOptionItem.Create(7312, "ArrowDelayMin", new FloatValueRule(0f, 30f, 1f), 2f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tracefinder]).SetValueFormat(OptionFormat.Seconds); ArrowDelayMax = FloatOptionItem.Create(7313, "ArrowDelayMax", new FloatValueRule(0f, 30f, 1f), 7f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tracefinder]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } public override void Remove(byte playerId) { playerIdList.Remove(playerId); } private static void SendRPC(byte playerId, bool add, Vector3 loc = default(Vector3)) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)174, (SendOption)1, -1); val.Write(playerId); val.Write(add); if (add) { val.Write(loc.x); val.Write(loc.y); val.Write(loc.z); } ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public override void ApplyGameOptions(IGameOptions opt, byte playerid) { AURoleOptions.ScientistCooldown = VitalsCooldown.GetFloat(); AURoleOptions.ScientistBatteryCharge = VitalsDuration.GetFloat(); } public static void ReceiveRPC(MessageReader reader) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) byte seer = reader.ReadByte(); if (reader.ReadBoolean()) { LocateArrow.Add(seer, new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle())); } else { LocateArrow.RemoveAllTarget(seer); } } public override void OnReportDeadBody(PlayerControl GODZILLA_VS, NetworkedPlayerInfo KINGKONG) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (byte playerId in playerIdList) { LocateArrow.RemoveAllTarget(playerId); SendRPC(playerId, add: false); } } public static void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (inMeeting || target.IsDisconnected()) { return; } target.GetCustomPosition(); float val = ((!(ArrowDelayMax.GetFloat() < ArrowDelayMin.GetFloat())) ? ((float)IRandom.Instance.Next((int)ArrowDelayMin.GetFloat(), (int)ArrowDelayMax.GetFloat() + 1)) : 0f); val = Math.Max(val, 0.15f); Vector3 tempPositionTarget = ((Component)target).transform.position; new LateTask(delegate { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsMeeting && GameStates.IsInTask) { foreach (byte playerId in playerIdList) { PlayerControl playerById = Utils.GetPlayerById(playerId); if (!((Object)(object)playerById == (Object)null) && playerById.IsAlive()) { LocateArrow.Add(playerId, tempPositionTarget); SendRPC(playerId, add: true, tempPositionTarget); Utils.NotifyRoles(playerById); } } } }, val, "Get Arrow Tracefinder"); } public override string GetSuffix(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || seer.PlayerId != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Color.white), LocateArrow.GetArrows(seer)); } } internal class Transporter : RoleBase { private const int Id = 7400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem TransporterTeleportMax; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; public override void SetupCustomOption() { Options.SetupRoleOptions(7400, TabGroup.CrewmateRoles, CustomRoles.Transporter); TransporterTeleportMax = IntegerOptionItem.Create(7402, "TransporterTeleportMax", new IntegerValueRule(1, 100, 1), 5, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Transporter]).SetValueFormat(OptionFormat.Times); Options.OverrideTasksData.Create(7410, TabGroup.CrewmateRoles, CustomRoles.Transporter); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (player.IsAlive() && completedTaskCount + 1 <= TransporterTeleportMax.GetInt()) { Logger.Info("Transporter: " + player.GetNameWithRole().RemoveHtmlTags() + " completed the task", "Transporter", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Transporter.cs"); _ = IRandom.Instance; List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => x.CanBeTeleported()).ToList(); if (list.Count >= 2) { PlayerControl val = list.RandomElement(); Vector2 customPosition = val.GetCustomPosition(); list.Remove(val); PlayerControl val2 = list.RandomElement(); Vector2 customPosition2 = val2.GetCustomPosition(); val.RpcTeleport(customPosition2); val2.RpcTeleport(customPosition); list.Clear(); val.RPCPlayCustomSound("Teleport"); val2.RPCPlayCustomSound("Teleport"); val.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Transporter)), string.Format(Translator.GetString("TeleportedByTransporter"), val2.GetRealName()))); val2.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Transporter)), string.Format(Translator.GetString("TeleportedByTransporter"), val.GetRealName()))); } else { player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Impostor)), Translator.GetString("ErrorTeleport"))); } } return true; } } internal class Veteran : RoleBase { private const int Id = 11350; private static OptionItem VeteranSkillCooldown; private static OptionItem VeteranSkillDuration; private static OptionItem VeteranSkillMaxOfUseage; private static OptionItem VeteranAbilityUseGainWithEachTaskCompleted; private static readonly Dictionary VeteranInProtect = new Dictionary(); public static bool HasEnabled => CustomRoles.Veteran.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(11350, TabGroup.CrewmateRoles, CustomRoles.Veteran); VeteranSkillCooldown = FloatOptionItem.Create(11360, "VeteranSkillCooldown", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Veteran]).SetValueFormat(OptionFormat.Seconds); VeteranSkillDuration = FloatOptionItem.Create(11361, "VeteranSkillDuration", new FloatValueRule(1f, 180f, 1f), 20f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Veteran]).SetValueFormat(OptionFormat.Seconds); VeteranSkillMaxOfUseage = IntegerOptionItem.Create(11362, "VeteranSkillMaxOfUseage", new IntegerValueRule(0, 20, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Veteran]).SetValueFormat(OptionFormat.Times); VeteranAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(11363, "AbilityUseGainWithEachTaskCompleted", new FloatValueRule(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Veteran]).SetValueFormat(OptionFormat.Times); } public override void Init() { VeteranInProtect.Clear(); } public override void Add(byte playerId) { base.AbilityLimit = VeteranSkillMaxOfUseage.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VeteranSkillCooldown.GetFloat(); AURoleOptions.EngineerInVentMaxTime = 1f; } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) { base.AbilityLimit += VeteranAbilityUseGainWithEachTaskCompleted.GetFloat(); } SendSkillRPC(); return true; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { bool flag; switch (killer.GetCustomRole()) { case CustomRoles.Bodyguard: case CustomRoles.Crusader: case CustomRoles.Deputy: case CustomRoles.Taskinator: flag = true; break; default: flag = false; break; } if (flag) { return true; } if (killer.PlayerId != target.PlayerId && VeteranInProtect.TryGetValue(target.PlayerId, out var value) && value + VeteranSkillDuration.GetInt() >= Utils.GetTimeStamp()) { if (killer.Is(CustomRoles.Pestilence)) { killer.RpcMurderPlayer(target); target.SetRealKiller(killer); Logger.Info(killer.GetRealName() + " kill " + target.GetRealName() + " because killer Pestilence", "Veteran", escapeCRLF: true, 79, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Veteran.cs"); return false; } if (killer.Is(CustomRoles.Jinx)) { target.RpcCheckAndMurder(killer); Logger.Info(killer.GetRealName() + " is Jinx try kill " + target.GetRealName() + " but it is canceled", "Veteran", escapeCRLF: true, 85, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Veteran.cs"); return false; } target.RpcMurderPlayer(killer); killer.SetRealKiller(target); Logger.Info(target.GetRealName() + " kill " + killer.GetRealName(), "Veteran", escapeCRLF: true, 92, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Crewmate\\Veteran.cs"); return false; } return true; } public override void OnFixedUpdateLowLoad(PlayerControl pc) { if (VeteranInProtect.TryGetValue(pc.PlayerId, out var value) && value + VeteranSkillDuration.GetInt() < Utils.GetTimeStamp()) { VeteranInProtect.Remove(pc.PlayerId); if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(); } else { pc.RpcResetAbilityCooldown(); } pc.Notify(string.Format(Translator.GetString("VeteranOffGuard"), base.AbilityLimit)); } } public override void OnEnterVent(PlayerControl pc, Vent vent) { if (base.AbilityLimit <= 0f) { pc.Notify(Translator.GetString("VeteranMaxUsage")); } else if (!VeteranInProtect.ContainsKey(pc.PlayerId)) { VeteranInProtect.Remove(pc.PlayerId); VeteranInProtect.Add(pc.PlayerId, Utils.GetTimeStamp(DateTime.Now)); base.AbilityLimit -= 1f; SendSkillRPC(); if (!Options.DisableShieldAnimations.GetBool()) { pc.RpcGuardAndKill(pc); } pc.RPCPlayCustomSound("Gunload"); pc.Notify(Translator.GetString("VeteranOnGuard"), VeteranSkillDuration.GetFloat()); } } public override bool CheckBootFromVent(PlayerPhysics physics, int ventId) { return base.AbilityLimit < 1f; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { VeteranInProtect.Clear(); } public override string GetProgressText(byte playerId, bool comms) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); TaskState taskState = Main.PlayerStates?[playerId].TaskState; Color green = Color.green; Color yellow = Color.yellow; Color val = (taskState.IsTaskFinished ? green : yellow); Color val2 = (comms ? Color.gray : val); string value = (comms ? "?" : $"{taskState.CompletedTasksCount}"); Color val3 = ((!(base.AbilityLimit < 1f)) ? Color.white : Color.red); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val2), $"({value}/{taskState.AllTasksCount})")); stringBuilder.Append(Utils.ColorString(Color32.op_Implicit(val3), $" - {Math.Round(base.AbilityLimit, 1)}")); return stringBuilder.ToString(); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((TMP_Text)((ActionButton)hud.AbilityButton).buttonLabelText).text = Translator.GetString("VeteranVentButtonText"); } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Veteran"); } } internal class Vigilante : RoleBase { private const int Id = 11400; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem VigilanteKillCooldown; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; public override void SetupCustomOption() { Options.SetupRoleOptions(11400, TabGroup.CrewmateRoles, CustomRoles.Vigilante); VigilanteKillCooldown = FloatOptionItem.Create(11402, GeneralOption.KillCooldown, new FloatValueRule(5f, 180f, 2.5f), 30f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vigilante]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = VigilanteKillCooldown.GetFloat(); } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (killer.Is(CustomRoles.Madmate)) { return true; } if (target.GetCustomRole().IsCrewmate() && !target.Is(CustomRoles.Madmate) && !target.GetCustomRole().IsConverted()) { killer.RpcSetCustomRole(CustomRoles.Madmate); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Madmate)), Translator.GetString("VigilanteNotify"))); Utils.MarkEveryoneDirtySettings(); } return true; } } internal class Witness : RoleBase { private const int Id = 10100; private static readonly HashSet playerIdList = new HashSet(); private static OptionItem WitnessCD; private static OptionItem WitnessTime; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(10100, TabGroup.CrewmateRoles, CustomRoles.Witness); WitnessCD = FloatOptionItem.Create(10110, "AbilityCD", new FloatValueRule(0f, 60f, 2.5f), 15f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Witness]).SetValueFormat(OptionFormat.Seconds); WitnessTime = IntegerOptionItem.Create(10111, "WitnessTime", new IntegerValueRule(1, 30, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Witness]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { playerIdList.Clear(); } public override void Add(byte playerId) { playerIdList.Add(playerId); if (!Main.ResetCamPlayerList.Contains(playerId)) { Main.ResetCamPlayerList.Add(playerId); } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateLowLoadOthers); } } public override bool CanUseKillButton(PlayerControl pc) { return true; } public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = WitnessCD.GetFloat(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { opt.SetVision(HasImpVision: false); } public override void SetAbilityButtonText(HudManager hud, byte id) { ((ActionButton)hud.KillButton).OverrideText(Translator.GetString("WitnessButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) { return CustomButton.Get("Examine"); } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(); if (Main.AllKillers.ContainsKey(target.PlayerId)) { killer.Notify(Translator.GetString("WitnessFoundKiller")); } else { killer.Notify(Translator.GetString("WitnessFoundInnocent")); } return false; } public static void OnFixedUpdateLowLoadOthers(PlayerControl player) { if (Main.AllKillers.TryGetValue(player.PlayerId, out var value) && value + WitnessTime.GetInt() < Utils.GetTimeStamp()) { Main.AllKillers.Remove(player.PlayerId); } } } } namespace TOHE.Roles.Core { public static class CustomRoleManager { public static readonly Dictionary RoleClass = new Dictionary(); public static bool OtherCollectionsSet = false; public static HashSet> CheckDeadBodyOthers = new HashSet>(); public static HashSet> OnFixedUpdateOthers = new HashSet>(); public static HashSet> OnFixedUpdateLowLoadOthers = new HashSet>(); private static HashSet> MarkOthers = new HashSet>(); private static HashSet> LowerOthers = new HashSet>(); private static HashSet> SuffixOthers = new HashSet>(); public static List AllEnabledRoles => Main.PlayerStates.Values.Select((PlayerState x) => x.RoleClass).ToList(); public static RoleBase GetStaticRoleClass(this CustomRoles role) { if (!(RoleClass.TryGetValue(role, out var value) && value != null)) { return new DefaultSetup(); } return value; } public static bool HasEnabled(this CustomRoles role) { return role.GetStaticRoleClass().IsEnable; } public static List GetNormalOptions(Custom_RoleType type) { List list = new List(); foreach (RoleBase value in RoleClass.Values) { if (!value.GetType().IsOptBlackListed() && !value.IsExperimental && value.ThisRoleType == type) { list.Add(value); } } return list; } public static List GetExperimentalOptions(Custom_Team team) { List result = new List(); switch (team) { case Custom_Team.Crewmate: result = (from r in RoleClass where r.Value.IsExperimental && r.Key.IsCrewmate() select r.Value).ToList(); break; case Custom_Team.Impostor: result = (from r in RoleClass where r.Value.IsExperimental && r.Key.IsImpostorTeam() select r.Value).ToList(); break; case Custom_Team.Neutral: result = (from r in RoleClass where r.Value.IsExperimental && r.Key.IsNeutralTeamV2() select r.Value).ToList(); break; default: Logger.Info("Unsupported team was sent.", "GetExperimentalOptions", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); break; } return result; } public static bool IsOptBlackListed(this Type role) { return CustomRolesHelper.DuplicatedRoles.ContainsValue(role); } public static RoleBase GetRoleClass(this PlayerControl player) { return player.PlayerId.GetRoleClassById(); } public static RoleBase GetRoleClassById(this byte playerId) { if (!Main.PlayerStates.TryGetValue(playerId, out var value) || value == null) { return new DefaultSetup(); } return value.RoleClass; } public static RoleBase CreateRoleClass(this CustomRoles role) { return (RoleBase)Activator.CreateInstance(role.GetStaticRoleClass().GetType()); } public static bool OnCheckMurderAsTargetOnOthers(PlayerControl killer, PlayerControl target) { return !AllEnabledRoles.Any((RoleBase RoleClass) => RoleClass.CheckMurderOnOthersTarget(killer, target)); } public static void BuildCustomGameOptions(this PlayerControl player, ref IGameOptions opt) { if (player.IsAnySubRole((CustomRoles x) => x == CustomRoles.EvilSpirit)) { AURoleOptions.GuardianAngelCooldown = Spiritcaller.SpiritAbilityCooldown.GetFloat(); } player.GetRoleClass()?.ApplyGameOptions(opt, player.PlayerId); if (NoisemakerTOHE.HasEnabled) { NoisemakerTOHE.ApplyGameOptionsForOthers(player); } if (DollMaster.HasEnabled && DollMaster.IsDoll(player.PlayerId)) { DollMaster.ApplySettingsToDoll(opt, player); return; } if (Grenadier.HasEnabled) { Grenadier.ApplyGameOptionsForOthers(opt, player); } if (Dazzler.HasEnabled) { Dazzler.SetDazzled(player, opt); } if (Deathpact.HasEnabled) { Deathpact.SetDeathpactVision(player, opt); } if (Spiritcaller.HasEnabled) { Spiritcaller.ReduceVision(opt, player); } if (Pitfall.HasEnabled) { Pitfall.SetPitfallTrapVision(opt, player); } List customSubRoles = player.GetCustomSubRoles(); if (customSubRoles.Any()) { CustomRoles[] array = customSubRoles.ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.Watcher: Watcher.RevealVotes(opt); break; case CustomRoles.Flash: Flash.SetSpeed(player.PlayerId, clearAddOn: false); break; case CustomRoles.Torch: Torch.ApplyGameOptions(opt); break; case CustomRoles.Tired: Tired.ApplyGameOptions(opt, player); break; case CustomRoles.Bewilder: Bewilder.ApplyVisionOptions(opt); break; case CustomRoles.Reach: Reach.ApplyGameOptions(opt); break; case CustomRoles.Madmate: Madmate.ApplyGameOptions(opt); break; case CustomRoles.Mare: Mare.ApplyGameOptions(player.PlayerId); break; } } } if (Glow.IsEnable) { Glow.ApplyGameOptions(opt, player); } if (Bewilder.IsEnable) { Bewilder.ApplyGameOptions(opt, player); } if (Ghoul.IsEnable) { Ghoul.ApplyGameOptions(player); } } public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl target, ref bool __state) { if ((Object)(object)killer == (Object)(object)target) { return true; } if ((Object)(object)target != (Object)null && target.Is(CustomRoles.Fragile) && Fragile.KillFragile(killer, target)) { Logger.Info("Fragile killed in OnCheckMurder, returning false", "Fragile", escapeCRLF: true, 155, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); return false; } bool flag = false; bool flag2 = false; RoleBase roleClass = killer.GetRoleClass(); List customSubRoles = killer.GetCustomSubRoles(); target = DollMaster.SwapPlayerInfo(target); Logger.Info("Start", "PlagueBearer.CheckAndInfect", escapeCRLF: true, 168, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); if (PlagueBearer.HasEnabled && !killer.Is(CustomRoles.PlagueBearer)) { PlagueBearer.CheckAndInfect(killer, target); } Logger.Info("Start", "ForcedCheckMurderAsKiller", escapeCRLF: true, 175, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); if (!roleClass.ForcedCheckMurderAsKiller(killer, target)) { __state = true; Logger.Info("Cancels because for killer no need kill target", "ForcedCheckMurderAsKiller", escapeCRLF: true, 181, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); return false; } Logger.Info("Start", "OnCheckMurder.RpcCheckAndMurder", escapeCRLF: true, 185, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); if (!killer.RpcCheckAndMurder(target, check: true)) { __state = true; Logger.Info("Cancels because target cancel kill", "OnCheckMurder.RpcCheckAndMurder", escapeCRLF: true, 191, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); return false; } Logger.Info("Start foreach", "KillerSubRoles", escapeCRLF: true, 195, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); if (customSubRoles.Any()) { CustomRoles[] array = customSubRoles.ToArray(); foreach (CustomRoles customRoles in array) { if (customRoles <= CustomRoles.Madmate) { if (customRoles != CustomRoles.Clumsy) { if (customRoles != CustomRoles.Infected) { if (customRoles != CustomRoles.Madmate || !target.Is(Custom_Team.Impostor) || Madmate.MadmateCanKillImp.GetBool()) { continue; } } else if ((!target.Is(CustomRoles.Infected) || Infectious.TargetKnowOtherTargets) && !target.Is(CustomRoles.Infectious)) { continue; } flag = true; } else if (!Clumsy.OnCheckMurder(killer)) { flag = true; } continue; } switch (customRoles) { case CustomRoles.Unlucky: if (Unlucky.SuicideRand(killer, Unlucky.StateSuicide.TryKill)) { flag = true; } break; case CustomRoles.Tired: Tired.AfterActionTasks(killer); break; case CustomRoles.Mare: if (Mare.IsLightsOut) { flag = true; } break; case CustomRoles.Swift: if (!Swift.OnCheckMurder(killer, target)) { flag2 = true; } break; } } } Logger.Info("Start", "OnCheckMurderAsKiller", escapeCRLF: true, 234, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); if (!roleClass.OnCheckMurderAsKiller(killer, target)) { __state = true; if (flag2 && target.IsAlive() && !DoubleTrigger.FirstTriggerTimer.TryGetValue(killer.PlayerId, out var _)) { target.RpcMurderPlayer(target); target.SetRealKiller(killer); Oiiai.OnMurderPlayer(killer, target); } Logger.Info("Cancels because for killer no need kill target", "OnCheckMurderAsKiller", escapeCRLF: true, 248, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\CustomRoleManager.cs"); return false; } if (DollMaster.HasEnabled && killer.Is(CustomRoles.Sheriff) && (Object)(object)target == (Object)(object)DollMaster.DollMasterTarget) { target = DollMaster.SwapPlayerInfo(target); } if (DollMaster.HasEnabled && DollMaster.IsControllingPlayer && !((Object)(object)DollMaster.DollMasterTarget == (Object)null) && !((Object)(object)DollMaster.controllingTarget == (Object)null) && ((Object)(object)target == (Object)(object)DollMaster.DollMasterTarget || (Object)(object)target == (Object)(object)DollMaster.controllingTarget)) { DollMaster.CheckMurderAsPossessed(killer, target); return false; } if (flag) { return false; } if (flag2) { target.RpcMurderPlayer(target); target.SetRealKiller(killer); Oiiai.OnMurderPlayer(killer, target); return false; } return true; } public static void OnMurderPlayer(PlayerControl killer, PlayerControl target, bool inMeeting) { PlayerControl killer2 = killer; killer = DollMaster.SwapPlayerInfo(killer); RoleBase roleClass = killer.GetRoleClass(); RoleBase roleClass2 = target.GetRoleClass(); List customSubRoles = killer.GetCustomSubRoles(); List customSubRoles2 = target.GetCustomSubRoles(); bool flag = killer.PlayerId == target.PlayerId; roleClass2.OnMurderPlayerAsTarget(killer, target, inMeeting, flag); if (customSubRoles2.Any()) { CustomRoles[] array = customSubRoles2.ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.Cyber: Cyber.AfterCyberDeadTask(target, inMeeting); break; case CustomRoles.Bait: if (!inMeeting) { Bait.BaitAfterDeathTasks(killer2, target); } break; case CustomRoles.Trapper: if (!inMeeting && !flag && !killer.Is(CustomRoles.KillingMachine)) { killer.TrapperKilled(target); } break; case CustomRoles.Avanger: if (!inMeeting && !flag) { Avanger.OnMurderPlayer(target); } break; case CustomRoles.Burst: if (killer.IsAlive() && !inMeeting && !flag && !killer.Is(CustomRoles.KillingMachine)) { Burst.AfterBurstDeadTasks(killer, target); } break; case CustomRoles.Oiiai: if (!flag) { Oiiai.OnMurderPlayer(killer, target); } break; case CustomRoles.EvilSpirit: if (!inMeeting && !flag) { target.RpcSetRole((RoleTypes)4, false); } break; } } } roleClass.OnMurderPlayerAsKiller(killer, target, inMeeting, flag); if (customSubRoles.Any()) { CustomRoles[] array = customSubRoles.ToArray(); for (int i = 0; i < array.Length; i++) { switch (array[i]) { case CustomRoles.TicketsStealer: if (!inMeeting && !flag) { Stealer.OnMurderPlayer(killer); } break; case CustomRoles.Tricky: Tricky.AfterPlayerDeathTasks(target); break; } } } CheckDeadBody(killer, target, inMeeting); if (killer.PlayerId != target.PlayerId || !target.IsDisconnected()) { FixedUpdateInNormalGamePatch.LoversSuicide(target.PlayerId, inMeeting); } } public static void OthersCompleteThisTask(PlayerControl player, PlayerTask task) { CollectionExtensions.Do((IEnumerable)AllEnabledRoles, (Action)delegate(RoleBase RoleClass) { RoleClass.OnOthersTaskComplete(player, task); }); } public static void CheckDeadBody(PlayerControl killer, PlayerControl deadBody, bool inMeeting) { if (CheckDeadBodyOthers.Any()) { Action[] array = CheckDeadBodyOthers.ToArray(); for (int i = 0; i < array.Length; i++) { array[i](killer, deadBody, inMeeting); } } } public static void OnFixedUpdate(PlayerControl player) { player.GetRoleClass()?.OnFixedUpdate(player); if (OnFixedUpdateOthers.Any()) { Action[] array = OnFixedUpdateOthers.ToArray(); for (int i = 0; i < array.Length; i++) { array[i](player); } } } public static void OnFixedUpdateLowLoad(PlayerControl player) { player.GetRoleClass()?.OnFixedUpdateLowLoad(player); if (OnFixedUpdateLowLoadOthers.Any()) { Action[] array = OnFixedUpdateLowLoadOthers.ToArray(); for (int i = 0; i < array.Length; i++) { array[i](player); } } } public static bool OthersCoEnterVent(PlayerPhysics physics, int ventId) { return AllEnabledRoles.Any((RoleBase RoleClass) => RoleClass.OnCoEnterVentOthers(physics, ventId)); } public static string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { StringBuilder stringBuilder = new StringBuilder(100); foreach (Func markOther in MarkOthers) { stringBuilder.Append(markOther(seer, seen, isForMeeting)); } return stringBuilder.ToString(); } public static string GetLowerTextOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false, bool isForHud = false) { StringBuilder stringBuilder = new StringBuilder(100); foreach (Func lowerOther in LowerOthers) { stringBuilder.Append(lowerOther(seer, seen, isForMeeting, isForHud)); } return stringBuilder.ToString(); } public static string GetSuffixOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { StringBuilder stringBuilder = new StringBuilder(100); foreach (Func suffixOther in SuffixOthers) { stringBuilder.Append(suffixOther(seer, seen, isForMeeting)); } return stringBuilder.ToString(); } public static void Initialize() { OtherCollectionsSet = false; OnFixedUpdateOthers.Clear(); OnFixedUpdateLowLoadOthers.Clear(); CheckDeadBodyOthers.Clear(); } public static void Add() { MarkOthers = ((IEnumerable)AllEnabledRoles).Select((Func>)((RoleBase mark) => mark.GetMarkOthers)).FilterDuplicates(); LowerOthers = ((IEnumerable)AllEnabledRoles).Select((Func>)((RoleBase lower) => lower.GetLowerTextOthers)).FilterDuplicates(); SuffixOthers = ((IEnumerable)AllEnabledRoles).Select((Func>)((RoleBase suffix) => suffix.GetSuffixOthers)).FilterDuplicates(); OtherCollectionsSet = true; } } } namespace TOHE.Roles.Core.AssignManager { public static class AddonAssign { public static List AddonRolesList = new List(); private static bool NotAssignAddOnInGameStarted(CustomRoles role) { switch (role) { case CustomRoles.LastImpostor: case CustomRoles.Lovers: case CustomRoles.Workhorse: return true; case CustomRoles.Autopsy: if (!Options.EveryoneCanSeeDeathReason.GetBool()) { break; } goto IL_0071; case CustomRoles.Madmate: if (Madmate.MadmateSpawnMode.GetInt() == 0) { break; } goto IL_0071; case CustomRoles.Glow: case CustomRoles.Mare: { if (!GameStates.FungleIsActive) { break; } goto IL_0071; } IL_0071: return true; } return false; } public static void StartSelect() { if (Options.CurrentGameMode == CustomGameMode.FFA) { return; } AddonRolesList = new List(); CustomRoles[] allRoles = CustomRolesHelper.AllRoles; for (int i = 0; i < allRoles.Length; i++) { CustomRoles customRoles = allRoles[i]; CustomRoles customRoles2 = (CustomRoles)Enum.Parse(typeof(CustomRoles), customRoles.ToString()); if (customRoles2.IsAdditionRole() && !NotAssignAddOnInGameStarted(customRoles2)) { AddonRolesList.Add(customRoles2); } } } public static void StartSortAndAssign() { if (Options.CurrentGameMode == CustomGameMode.FFA) { return; } IRandom instance = IRandom.Instance; List list = new List(); List list2 = new List(); Dictionary source = Options.CustomAdtRoleSpawnRate.OrderByDescending((KeyValuePair role) => role.Value.GetFloat()).ToDictionary((KeyValuePair x) => x.Key, (KeyValuePair x) => x.Value); KeyValuePair[] array = source.Where((KeyValuePair a) => a.Key.IsEnable()).ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair keyValuePair = array[i]; if (!NotAssignAddOnInGameStarted(keyValuePair.Key)) { list2.Add(keyValuePair.Key); } } Logger.Info($"Number enabled of add-ons (before priority): {list2.Count}", "Check Add-ons Count", escapeCRLF: true, 68, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\AddonAssign.cs"); array = source.Where((KeyValuePair a) => a.Key.IsEnable() && a.Value.GetFloat() >= 90f).ToArray(); foreach (KeyValuePair keyValuePair2 in array) { CustomRoles key = keyValuePair2.Key; if (AddonRolesList.Contains(key)) { list.Add(key); list2.Remove(key); } } if (list.Count > 2) { list = list.Shuffle(instance).ToList(); } Logger.Info($"Number enabled of add-ons (after priority): {list2.Count}", "Check Add-ons Count", escapeCRLF: true, 85, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\AddonAssign.cs"); while (list2.Any()) { CustomRoles item = list2.RandomElement(); if (!list.Contains(item) && AddonRolesList.Contains(item)) { list.Add(item); } list2.Remove(item); } Logger.Info(" Is Started", "Assign Add-ons", escapeCRLF: true, 102, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\AddonAssign.cs"); CustomRoles[] array2 = list.ToArray(); foreach (CustomRoles customRoles in array2) { if ((float)instance.Next(1, 101) <= (Options.CustomAdtRoleSpawnRate.TryGetValue(customRoles, out var value) ? value.GetFloat() : 0f)) { AssignSubRoles(customRoles); } } } public static void AssignSubRoles(CustomRoles role, int RawCount = -1) { List list = Main.AllAlivePlayerControls.Where((PlayerControl x) => CustomRolesHelper.CheckAddonConfilct(role, x)).ToList(); int num = Math.Clamp(RawCount, 0, list.Count); if (RawCount == -1) { num = Math.Clamp(role.GetCount(), 0, list.Count); } if (num <= 0) { return; } for (int i = 0; i < num; i++) { if (!list.Any()) { break; } PlayerControl val = list.RandomElement(); list.Remove(val); Main.PlayerStates[val.PlayerId].SetSubRole(role); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 3); defaultInterpolatedStringHandler.AppendLiteral("Registered Add-on: "); object value; if (val == null) { value = null; } else { NetworkedPlayerInfo data = val.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" = "); defaultInterpolatedStringHandler.AppendFormatted(val.GetCustomRole()); defaultInterpolatedStringHandler.AppendLiteral(" + "); defaultInterpolatedStringHandler.AppendFormatted(role); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), $"Assign {role}", escapeCRLF: true, 130, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\AddonAssign.cs"); } } public static void InitAndStartAssignLovers() { IRandom instance = IRandom.Instance; if (CustomRoles.Lovers.IsEnable() && (CustomRoles.Hater.IsEnable() ? (-1) : instance.Next(1, 100)) <= Options.LoverSpawnChances.GetInt()) { Main.LoversPlayers.Clear(); Main.isLoversDead = false; AssignLovers(); } } private static void AssignLovers(int RawCount = -1) { List list = new List(); PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if (!val.Is(CustomRoles.GM) && (!val.HasSubRole() || val.GetCustomSubRoles().Count < Options.NoLimitAddonsNumMax.GetInt()) && !val.Is(CustomRoles.Dictator) && !val.Is(CustomRoles.God) && !val.Is(CustomRoles.Hater) && !val.Is(CustomRoles.Sunnyboy) && !val.Is(CustomRoles.Bomber) && !val.Is(CustomRoles.Provocateur) && !val.Is(CustomRoles.RuthlessRomantic) && !val.Is(CustomRoles.Romantic) && !val.Is(CustomRoles.VengefulRomantic) && !val.Is(CustomRoles.Workaholic) && !val.Is(CustomRoles.Solsticer) && !val.Is(CustomRoles.Mini) && !val.Is(CustomRoles.NiceMini) && !val.Is(CustomRoles.EvilMini) && (!val.GetCustomRole().IsCrewmate() || Options.CrewCanBeInLove.GetBool()) && (!val.GetCustomRole().IsNeutral() || Options.NeutralCanBeInLove.GetBool()) && (!val.GetCustomRole().IsImpostor() || Options.ImpCanBeInLove.GetBool())) { list.Add(val); } } CustomRoles customRoles = CustomRoles.Lovers; int num = Math.Clamp(RawCount, 0, list.Count); if (RawCount == -1) { num = Math.Clamp(customRoles.GetCount(), 0, list.Count); } if (num <= 0 || list.Count <= 1) { return; } for (int j = 0; j < num; j++) { PlayerControl val2 = list.RandomElement(); Main.LoversPlayers.Add(val2); list.Remove(val2); Main.PlayerStates[val2.PlayerId].SetSubRole(customRoles); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(25, 3); defaultInterpolatedStringHandler.AppendLiteral("Registered Lovers: "); object value; if (val2 == null) { value = null; } else { NetworkedPlayerInfo data = val2.Data; value = ((data != null) ? data.PlayerName : null); } defaultInterpolatedStringHandler.AppendFormatted((string?)value); defaultInterpolatedStringHandler.AppendLiteral(" = "); defaultInterpolatedStringHandler.AppendFormatted(val2.GetCustomRole()); defaultInterpolatedStringHandler.AppendLiteral(" + "); defaultInterpolatedStringHandler.AppendFormatted(customRoles); Logger.Info(defaultInterpolatedStringHandler.ToStringAndClear(), "Assign Lovers", escapeCRLF: true, 185, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\AddonAssign.cs"); } if (Main.LoversPlayers.Any()) { RPC.SyncLoversPlayers(); } } } public static class GhostRoleAssign { public static Dictionary GhostGetPreviousRole = new Dictionary(); private static readonly Dictionary getCount = new Dictionary(); private static readonly IRandom Rnd = IRandom.Instance; private static int ImpCount = 0; private static int CrewCount = 0; public static Dictionary forceRole = new Dictionary(); private static readonly List HauntedList = new List(); private static readonly List ImpHauntedList = new List(); private static bool GetChance(this CustomRoles role) { if (role.GetMode() != 100) { return Rnd.Next(1, 100) <= role.GetMode(); } return true; } public static void GhostAssignPatch(PlayerControl player) { if (GameStates.IsHideNSeek || Options.CurrentGameMode == CustomGameMode.FFA || (Object)(object)player == (Object)null || player.Data.Disconnected || GhostGetPreviousRole.ContainsKey(player.PlayerId) || player.GetCustomRole().IsDesyncRole()) { return; } if (forceRole.TryGetValue(player.PlayerId, out var value)) { Logger.Info($" Debug set {player.GetRealName()}'s role to {value}", "GhostAssignPatch", escapeCRLF: true, 26, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\GhostRoleAssign.cs"); player.GetRoleClass()?.OnRemove(player.PlayerId); player.RpcSetCustomRole(value); player.GetRoleClass().OnAdd(player.PlayerId); forceRole.Remove(player.PlayerId); getCount[value]--; return; } CustomRoles customRole = player.GetCustomRole(); bool flag; switch (customRole) { case CustomRoles.Nemesis: case CustomRoles.NiceMini: case CustomRoles.Retributionist: case CustomRoles.GM: flag = true; break; default: flag = false; break; } if (flag) { return; } bool flag2 = !player.IsAnySubRole((CustomRoles x) => x.IsConverted()) || Options.ConvertedCanBecomeGhost.GetBool(); bool flag3 = (customRole.IsCrewmate() || player.Is(CustomRoles.Admired)) && flag2; bool flag4 = customRole.IsImpostor() && (flag2 || player.Is(CustomRoles.Madmate)); if (customRole.IsGhostRole() || player.IsAnySubRole((CustomRoles x) => x.IsGhostRole() || x == CustomRoles.Gravestone) || !Options.CustomGhostRoleCounts.Any() || (flag4 && ImpCount >= Options.MaxImpGhost.GetInt()) || (flag3 && CrewCount >= Options.MaxCrewGhost.GetInt())) { return; } GhostGetPreviousRole.TryAdd(player.PlayerId, customRole); HauntedList.Clear(); ImpHauntedList.Clear(); CustomRoles customRoles = CustomRoles.NotAssigned; foreach (CustomRoles item in getCount.Keys.Where((CustomRoles x) => x.GetMode() > 0)) { if (item.IsCrewmate()) { if (HauntedList.Contains(item) && getCount[item] <= 0) { HauntedList.Remove(item); } if (HauntedList.Contains(item) || getCount[item] <= 0) { continue; } if (item.GetChance()) { HauntedList.Add(item); } } if (item.IsImpostor()) { if (ImpHauntedList.Contains(item) && getCount[item] <= 0) { ImpHauntedList.Remove(item); } if (!ImpHauntedList.Contains(item) && getCount[item] > 0 && item.GetChance()) { ImpHauntedList.Add(item); } } } if (flag3) { if (HauntedList.Any()) { int index = IRandom.Instance.Next(HauntedList.Count); customRoles = HauntedList[index]; } if (customRoles.IsGhostRole()) { CrewCount++; getCount[customRoles]--; player.GetRoleClass().OnRemove(player.PlayerId); player.RpcSetCustomRole(customRoles); player.GetRoleClass().OnAdd(player.PlayerId); } } else if (flag4) { if (ImpHauntedList.Any()) { int index2 = IRandom.Instance.Next(ImpHauntedList.Count); customRoles = ImpHauntedList[index2]; } if (customRoles.IsGhostRole()) { ImpCount++; getCount[customRoles]--; player.GetRoleClass().OnRemove(player.PlayerId); player.RpcSetCustomRole(customRoles); player.GetRoleClass().OnAdd(player.PlayerId); } } } public static void Init() { CrewCount = 0; ImpCount = 0; getCount.Clear(); GhostGetPreviousRole.Clear(); } public static void Add() { if (Options.CustomGhostRoleCounts.Any()) { CollectionExtensions.Do((IEnumerable)Options.CustomGhostRoleCounts.Keys, (Action)delegate(CustomRoles ghostRole) { getCount.TryAdd(ghostRole, ghostRole.GetCount()); }); } foreach (KeyValuePair item in getCount) { Logger.Info($"Logged: {item.Key} / {item.Value}", "GhostAssignPatch.Add.GetCount", escapeCRLF: true, 139, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\GhostRoleAssign.cs"); } } } public class RoleAssign { private enum RoleAssignType { Impostor, NeutralKilling, NonKillingNeutral, Crewmate } public class RoleAssignInfo { [CompilerGenerated] private CustomRoles P; [CompilerGenerated] private int P; [CompilerGenerated] private int P; [CompilerGenerated] private int P; public CustomRoles Role { get { return P; } set { P = value; } } public int SpawnChance { get { return P; } set { P = value; } } public int MaxCount { get { return P; } set { P = value; } } public int AssignedCount { get { return P; } set { P = value; } } public RoleAssignInfo(CustomRoles role, int spawnChance, int maxCount, int assignedCount = 0) { P = role; P = spawnChance; P = maxCount; P = assignedCount; base..ctor(); } } public static Dictionary SetRoles = new Dictionary(); public static Dictionary RoleResult; public static int AddScientistNum; public static int AddEngineerNum; public static int AddShapeshifterNum; public static int AddNoisemakerNum; public static int AddPhantomNum; public static int AddTrackerNum; public static CustomRoles[] AllRoles { get { Dictionary.ValueCollection values = RoleResult.Values; int num = 0; CustomRoles[] array = new CustomRoles[values.Count]; foreach (CustomRoles item in values) { array[num] = item; num++; } return array; } } public static void GetNeutralCounts(int NKmaxOpt, int NKminOpt, int NNKmaxOpt, int NNKminOpt, ref int ResultNKnum, ref int ResultNNKnum) { IRandom instance = IRandom.Instance; if (NNKmaxOpt > 0 && NNKmaxOpt >= NNKminOpt) { ResultNNKnum = instance.Next(NNKminOpt, NNKmaxOpt + 1); } if (NKmaxOpt > 0 && NKmaxOpt >= NKminOpt) { ResultNKnum = instance.Next(NKminOpt, NKmaxOpt + 1); } } public static void StartSelect() { if (Options.CurrentGameMode == CustomGameMode.FFA) { RoleResult = new Dictionary(); PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl key in allAlivePlayerControls) { RoleResult.Add(key, CustomRoles.Killer); } return; } RoleResult = new Dictionary(); IRandom instance = IRandom.Instance; int num = Main.AllAlivePlayerControls.Length; int @int = Main.RealOptionsData.GetInt((Int32OptionNames)1); int ResultNNKnum = 0; int ResultNKnum = 0; GetNeutralCounts(Options.NeutralKillingRolesMaxPlayer.GetInt(), Options.NeutralKillingRolesMinPlayer.GetInt(), Options.NonNeutralKillingRolesMaxPlayer.GetInt(), Options.NonNeutralKillingRolesMinPlayer.GetInt(), ref ResultNKnum, ref ResultNNKnum); int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; List list = new List(); Dictionary> Roles = new Dictionary>(); Roles[RoleAssignType.Impostor] = new List(); Roles[RoleAssignType.NeutralKilling] = new List(); Roles[RoleAssignType.NonKillingNeutral] = new List(); Roles[RoleAssignType.Crewmate] = new List(); byte[] array = SetRoles.Keys.Where((byte id) => (Object)(object)Utils.GetPlayerById(id) == (Object)null).ToArray(); foreach (byte key2 in array) { SetRoles.Remove(key2); } CustomRoles[] allValues = EnumHelper.GetAllValues(); foreach (CustomRoles customRoles in allValues) { int mode = customRoles.GetMode(); if (customRoles.IsVanilla() || mode == 0 || customRoles.IsAdditionRole() || customRoles.IsGhostRole()) { continue; } CustomRoles customRoles2 = customRoles; if (customRoles2 <= CustomRoles.RuthlessRomantic) { if (customRoles2 <= CustomRoles.Doctor) { if (customRoles2 == CustomRoles.EvilMini || (customRoles2 == CustomRoles.Doctor && Options.EveryoneCanSeeDeathReason.GetBool())) { continue; } } else if (customRoles2 == CustomRoles.NiceMini || customRoles2 == CustomRoles.RuthlessRomantic) { continue; } } else if (customRoles2 <= CustomRoles.VengefulRomantic) { if (customRoles2 != CustomRoles.Stalker) { if (customRoles2 == CustomRoles.VengefulRomantic) { continue; } } else if (GameStates.FungleIsActive) { continue; } } else if (customRoles2 == CustomRoles.GM || customRoles2 == CustomRoles.NotAssigned) { continue; } int count = customRoles.GetCount(); RoleAssignInfo item6 = new RoleAssignInfo(customRoles, mode, count); if (customRoles == CustomRoles.Mini) { if (Mini.CheckSpawnEvilMini()) { item6 = new RoleAssignInfo(CustomRoles.EvilMini, mode, count); Roles[RoleAssignType.Impostor].Add(item6); } else { item6 = new RoleAssignInfo(CustomRoles.NiceMini, mode, count); Roles[RoleAssignType.Crewmate].Add(item6); } } else if (customRoles.IsImpostor()) { Roles[RoleAssignType.Impostor].Add(item6); } else if (customRoles.IsNK()) { Roles[RoleAssignType.NeutralKilling].Add(item6); } else if (customRoles.IsNonNK()) { Roles[RoleAssignType.NonKillingNeutral].Add(item6); } else { Roles[RoleAssignType.Crewmate].Add(item6); } } Logger.Info($"Number of NKs: {ResultNKnum}, Number of NonNKs: {ResultNNKnum}", "NeutralNum", escapeCRLF: true, 131, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Msg("=====================================================", "AllActiveRoles", escapeCRLF: true, 132, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.Impostor].Select((RoleAssignInfo x) => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "ImpRoles", escapeCRLF: true, 133, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.NeutralKilling].Select((RoleAssignInfo x) => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "NKRoles", escapeCRLF: true, 134, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.NonKillingNeutral].Select((RoleAssignInfo x) => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "NonNKRoles", escapeCRLF: true, 135, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.Crewmate].Select((RoleAssignInfo x) => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "CrewRoles", escapeCRLF: true, 136, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Msg("=====================================================", "AllActiveRoles", escapeCRLF: true, 137, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); IEnumerable collection = Roles[RoleAssignType.Impostor].Where((RoleAssignInfo x) => x.SpawnChance == 100); IEnumerable collection2 = Roles[RoleAssignType.NeutralKilling].Where((RoleAssignInfo x) => x.SpawnChance == 100); IEnumerable collection3 = Roles[RoleAssignType.NonKillingNeutral].Where((RoleAssignInfo x) => x.SpawnChance == 100); IEnumerable collection4 = Roles[RoleAssignType.Crewmate].Where((RoleAssignInfo x) => x.SpawnChance == 100); Roles[RoleAssignType.Impostor] = Roles[RoleAssignType.Impostor].Shuffle(instance).Take(@int).ToList(); Roles[RoleAssignType.NeutralKilling] = Roles[RoleAssignType.NeutralKilling].Shuffle(instance).Take(ResultNKnum).ToList(); Roles[RoleAssignType.NonKillingNeutral] = Roles[RoleAssignType.NonKillingNeutral].Shuffle(instance).Take(ResultNNKnum).ToList(); Roles[RoleAssignType.Crewmate] = Roles[RoleAssignType.Crewmate].Shuffle(instance).Take(num).ToList(); Roles[RoleAssignType.Impostor].AddRange(collection); Roles[RoleAssignType.NeutralKilling].AddRange(collection2); Roles[RoleAssignType.NonKillingNeutral].AddRange(collection3); Roles[RoleAssignType.Crewmate].AddRange(collection4); Roles[RoleAssignType.Impostor] = Roles[RoleAssignType.Impostor].DistinctBy((RoleAssignInfo x) => x.Role).ToList(); Roles[RoleAssignType.NeutralKilling] = Roles[RoleAssignType.NeutralKilling].DistinctBy((RoleAssignInfo x) => x.Role).ToList(); Roles[RoleAssignType.NonKillingNeutral] = Roles[RoleAssignType.NonKillingNeutral].DistinctBy((RoleAssignInfo x) => x.Role).ToList(); Roles[RoleAssignType.Crewmate] = Roles[RoleAssignType.Crewmate].DistinctBy((RoleAssignInfo x) => x.Role).ToList(); Logger.Msg("======================================================", "SelectedRoles", escapeCRLF: true, 163, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.Impostor].Select((RoleAssignInfo x) => x.Role.ToString())), "Selected-Impostor-Roles", escapeCRLF: true, 164, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.NeutralKilling].Select((RoleAssignInfo x) => x.Role.ToString())), "Selected-NK-Roles", escapeCRLF: true, 165, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.NonKillingNeutral].Select((RoleAssignInfo x) => x.Role.ToString())), "Selected-NonNK-Roles", escapeCRLF: true, 166, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Info(string.Join(", ", Roles[RoleAssignType.Crewmate].Select((RoleAssignInfo x) => x.Role.ToString())), "Selected-Crew-Roles", escapeCRLF: true, 167, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); Logger.Msg("======================================================", "SelectedRoles", escapeCRLF: true, 168, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); List list2 = Main.AllAlivePlayerControls.ToList(); if (BanManager.CheckEACList(PlayerControl.LocalPlayer.FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid())) { Main.EnableGM.Value = true; RoleResult[PlayerControl.LocalPlayer] = CustomRoles.GM; list2.Remove(PlayerControl.LocalPlayer); } if (Main.EnableGM.Value) { RoleResult[PlayerControl.LocalPlayer] = CustomRoles.GM; list2.Remove(PlayerControl.LocalPlayer); SetRoles.Remove(PlayerControl.LocalPlayer.PlayerId); } foreach (KeyValuePair item5 in SetRoles) { PlayerControl val = ((IEnumerable)list2).FirstOrDefault((Func)((PlayerControl x) => x.PlayerId == item5.Key)); if ((Object)(object)val == (Object)null) { continue; } RoleResult[val] = item5.Value; list2.Remove(val); if (item5.Value.IsImpostor()) { CollectionExtensions.Do(Roles[RoleAssignType.Impostor].Where((RoleAssignInfo x) => x.Role == item5.Value), (Action)delegate(RoleAssignInfo x) { x.AssignedCount++; }); num3++; } else if (item5.Value.IsNK()) { CollectionExtensions.Do(Roles[RoleAssignType.NeutralKilling].Where((RoleAssignInfo x) => x.Role == item5.Value), (Action)delegate(RoleAssignInfo x) { x.AssignedCount++; }); num5++; } else if (item5.Value.IsNonNK()) { CollectionExtensions.Do(Roles[RoleAssignType.NonKillingNeutral].Where((RoleAssignInfo x) => x.Role == item5.Value), (Action)delegate(RoleAssignInfo x) { x.AssignedCount++; }); num4++; } num2++; Logger.Warn($"Pre-Set Role Assigned: {val.GetRealName()} => {item5.Value}", "RoleAssign", escapeCRLF: true, 212, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } RoleAssignInfo[] array2 = Array.Empty(); RoleAssignInfo[] source = Array.Empty(); RoleAssignInfo[] source2 = Array.Empty(); RoleAssignInfo[] source3 = Array.Empty(); List list3 = new List(); List list4 = new List(); for (int j = 0; j < Roles[RoleAssignType.Impostor].Count; j++) { RoleAssignInfo item4 = Roles[RoleAssignType.Impostor][j]; if (item4.SpawnChance == 100) { for (int k = 0; k < item4.MaxCount; k++) { if (SetRoles.ContainsValue(item4.Role)) { byte key3 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item4.Role).Key; SetRoles.Remove(key3); } else { list3.Add(item4.Role); } } continue; } for (int l = 0; l < item4.MaxCount; l++) { if (SetRoles.ContainsValue(item4.Role)) { byte key4 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item4.Role).Key; SetRoles.Remove(key4); } else { for (int m = 0; m < item4.SpawnChance / 5; m++) { list4.Add(item4.Role); } } } } RoleAssignInfo[] array3 = CollectionExtensions.AddRangeToArray(list3.Distinct().Select(GetAssignInfo).ToArray(), list4.Distinct().Select(GetAssignInfo).ToArray()); array2 = array3; if (num3 < @int) { while (list3.Any()) { CustomRoles selected8 = list3.RandomElement(); RoleAssignInfo roleAssignInfo = array3.FirstOrDefault((RoleAssignInfo x) => x.Role == selected8); list3.Remove(selected8); if (roleAssignInfo.AssignedCount >= roleAssignInfo.MaxCount) { continue; } list.Add(selected8); roleAssignInfo.AssignedCount++; num2++; num3++; array2 = array3; if (num2 < num) { if (num3 >= @int) { break; } continue; } goto IL_19be; } } if (num2 < num && num3 < @int) { while (list4.Any()) { CustomRoles selected7 = list4.RandomElement(); RoleAssignInfo roleAssignInfo2 = array3.FirstOrDefault((RoleAssignInfo x) => x.Role == selected7); for (int n = 0; n < roleAssignInfo2.SpawnChance / 5; n++) { list4.Remove(selected7); } list.Add(selected7); roleAssignInfo2.AssignedCount++; num2++; num3++; array2 = array3; if (roleAssignInfo2.AssignedCount >= roleAssignInfo2.MaxCount) { while (list4.Contains(selected7)) { list4.Remove(selected7); } } if (num2 < num) { if (num3 >= @int) { break; } continue; } goto IL_19be; } } List list5 = new List(); List list6 = new List(); for (int num6 = 0; num6 < Roles[RoleAssignType.NonKillingNeutral].Count; num6++) { RoleAssignInfo item3 = Roles[RoleAssignType.NonKillingNeutral][num6]; if (item3.SpawnChance == 100) { for (int num7 = 0; num7 < item3.MaxCount; num7++) { if (SetRoles.ContainsValue(item3.Role)) { byte key5 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item3.Role).Key; SetRoles.Remove(key5); } else { list5.Add(item3.Role); } } continue; } for (int num8 = 0; num8 < item3.MaxCount; num8++) { if (SetRoles.ContainsValue(item3.Role)) { byte key6 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item3.Role).Key; SetRoles.Remove(key6); } else { for (int num9 = 0; num9 < item3.SpawnChance / 5; num9++) { list6.Add(item3.Role); } } } } RoleAssignInfo[] array4 = CollectionExtensions.AddRangeToArray(list5.Distinct().Select(GetAssignInfo).ToArray(), list6.Distinct().Select(GetAssignInfo).ToArray()); source = array4; if (num4 < ResultNNKnum) { while (list5.Any() && ResultNNKnum > 0) { CustomRoles selected6 = list5.RandomElement(); RoleAssignInfo roleAssignInfo3 = array4.FirstOrDefault((RoleAssignInfo x) => x.Role == selected6); list5.Remove(selected6); if (roleAssignInfo3.AssignedCount >= roleAssignInfo3.MaxCount) { continue; } list.Add(selected6); roleAssignInfo3.AssignedCount++; num2++; num4++; source = array4; if (num2 < num) { if (num4 >= ResultNNKnum) { break; } continue; } goto IL_19be; } } if (num2 < num && num4 < ResultNNKnum) { while (list6.Any() && ResultNNKnum > 0) { CustomRoles selected5 = list6.RandomElement(); RoleAssignInfo roleAssignInfo4 = array4.FirstOrDefault((RoleAssignInfo x) => x.Role == selected5); for (int num10 = 0; num10 < roleAssignInfo4.SpawnChance / 5; num10++) { list6.Remove(selected5); } list.Add(selected5); roleAssignInfo4.AssignedCount++; num2++; num4++; source = array4; if (roleAssignInfo4.AssignedCount >= roleAssignInfo4.MaxCount) { while (list6.Contains(selected5)) { list6.Remove(selected5); } } if (num2 < num) { if (num4 >= ResultNNKnum) { break; } continue; } goto IL_19be; } } List list7 = new List(); List list8 = new List(); for (int num11 = 0; num11 < Roles[RoleAssignType.NeutralKilling].Count; num11++) { RoleAssignInfo item2 = Roles[RoleAssignType.NeutralKilling][num11]; if (item2.SpawnChance == 100) { for (int num12 = 0; num12 < item2.MaxCount; num12++) { if (SetRoles.ContainsValue(item2.Role)) { byte key7 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item2.Role).Key; SetRoles.Remove(key7); } else { list7.Add(item2.Role); } } continue; } for (int num13 = 0; num13 < item2.MaxCount; num13++) { if (SetRoles.ContainsValue(item2.Role)) { byte key8 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item2.Role).Key; SetRoles.Remove(key8); } else { for (int num14 = 0; num14 < item2.SpawnChance / 5; num14++) { list8.Add(item2.Role); } } } } RoleAssignInfo[] array5 = CollectionExtensions.AddRangeToArray(list7.Distinct().Select(GetAssignInfo).ToArray(), list8.Distinct().Select(GetAssignInfo).ToArray()); source2 = array5; if (num5 < ResultNKnum) { while (list7.Any() && ResultNKnum > 0) { CustomRoles selected4 = list7.RandomElement(); RoleAssignInfo roleAssignInfo5 = array5.FirstOrDefault((RoleAssignInfo x) => x.Role == selected4); list7.Remove(selected4); if (roleAssignInfo5.AssignedCount >= roleAssignInfo5.MaxCount) { continue; } list.Add(selected4); roleAssignInfo5.AssignedCount++; num2++; num5++; source2 = array5; if (num2 < num) { if (num5 >= ResultNKnum) { break; } continue; } goto IL_19be; } } if (num2 < num && num5 < ResultNKnum) { while (list8.Any() && ResultNKnum > 0) { CustomRoles selected3 = list8.RandomElement(); RoleAssignInfo roleAssignInfo6 = array5.FirstOrDefault((RoleAssignInfo x) => x.Role == selected3); for (int num15 = 0; num15 < roleAssignInfo6.SpawnChance / 5; num15++) { list8.Remove(selected3); } list.Add(selected3); roleAssignInfo6.AssignedCount++; num2++; num5++; source2 = array5; if (roleAssignInfo6.AssignedCount >= roleAssignInfo6.MaxCount) { while (list8.Contains(selected3)) { list8.Remove(selected3); } } if (num2 < num) { if (num5 >= ResultNKnum) { break; } continue; } goto IL_19be; } } List list9 = new List(); List list10 = new List(); for (int num16 = 0; num16 < Roles[RoleAssignType.Crewmate].Count; num16++) { RoleAssignInfo item = Roles[RoleAssignType.Crewmate][num16]; if (item.SpawnChance == 100) { for (int num17 = 0; num17 < item.MaxCount; num17++) { if (SetRoles.ContainsValue(item.Role)) { byte key9 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item.Role).Key; SetRoles.Remove(key9); } else { list9.Add(item.Role); } } continue; } for (int num18 = 0; num18 < item.MaxCount; num18++) { if (SetRoles.ContainsValue(item.Role)) { byte key10 = SetRoles.FirstOrDefault((KeyValuePair x) => x.Value == item.Role).Key; SetRoles.Remove(key10); } else { for (int num19 = 0; num19 < item.SpawnChance / 5; num19++) { list10.Add(item.Role); } } } } RoleAssignInfo[] array6 = CollectionExtensions.AddRangeToArray(list9.Distinct().Select(GetAssignInfo).ToArray(), list10.Distinct().Select(GetAssignInfo).ToArray()); source3 = array6; if (num2 < num) { while (list9.Any()) { CustomRoles selected2 = list9.RandomElement(); RoleAssignInfo roleAssignInfo7 = array6.FirstOrDefault((RoleAssignInfo x) => x.Role == selected2); list9.Remove(selected2); if (roleAssignInfo7.AssignedCount >= roleAssignInfo7.MaxCount) { continue; } list.Add(selected2); roleAssignInfo7.AssignedCount++; num2++; source3 = array6; if (num2 < num) { continue; } goto IL_19be; } } if (num2 < num) { while (list10.Any()) { CustomRoles selected = list10.RandomElement(); RoleAssignInfo roleAssignInfo8 = array6.FirstOrDefault((RoleAssignInfo x) => x.Role == selected); for (int num20 = 0; num20 < roleAssignInfo8.SpawnChance / 5; num20++) { list10.Remove(selected); } list.Add(selected); roleAssignInfo8.AssignedCount++; num2++; source3 = array6; if (roleAssignInfo8.AssignedCount >= roleAssignInfo8.MaxCount) { while (list10.Contains(selected)) { list10.Remove(selected); } } if (num2 >= num) { break; } } } goto IL_19be; IL_19be: if (array2.Any()) { Logger.Info(string.Join(", ", array2.Select((RoleAssignInfo x) => $"{x.Role} - {x.AssignedCount}/{x.MaxCount} ({x.SpawnChance}%)")), "ImpRoleResult", escapeCRLF: true, 617, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } if (source.Any()) { Logger.Info(string.Join(", ", source.Select((RoleAssignInfo x) => $"{x.Role} - {x.AssignedCount}/{x.MaxCount} ({x.SpawnChance}%)")), "NNKRoleResult", escapeCRLF: true, 618, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } if (source2.Any()) { Logger.Info(string.Join(", ", source2.Select((RoleAssignInfo x) => $"{x.Role} - {x.AssignedCount}/{x.MaxCount} ({x.SpawnChance}%)")), "NKRoleResult", escapeCRLF: true, 619, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } if (source3.Any()) { Logger.Info(string.Join(", ", source3.Select((RoleAssignInfo x) => $"{x.Role} - {x.AssignedCount}/{x.MaxCount} ({x.SpawnChance}%)")), "CrewRoleResult", escapeCRLF: true, 620, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } if (Sunnyboy.CheckSpawn() && list.Remove(CustomRoles.Jester)) { list.Add(CustomRoles.Sunnyboy); } if (Bard.CheckSpawn() && list.Remove(CustomRoles.Arrogance)) { list.Add(CustomRoles.Bard); } if (Romantic.HasEnabled && list.Contains(CustomRoles.Romantic) && list.Contains(CustomRoles.Lovers)) { list.Remove(CustomRoles.Lovers); } if (list2.Count > list.Count) { while (list.Count < list2.Count) { list.Add(CustomRoles.CrewmateTOHE); } } Logger.Info(string.Join(", ", list.Select((CustomRoles x) => x.ToString())), "RoleResults", escapeCRLF: true, 640, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); while (list2.Any() && list.Any()) { if (list2.Count > 2) { list2 = list2.Shuffle(instance).ToList(); } if (list.Count > 2) { list = list.Shuffle(instance).ToList(); } PlayerControl val2 = list2.RandomElement(); CustomRoles customRoles3 = list.RandomElement(); RoleResult[val2] = customRoles3; Logger.Info($"Player:{val2.GetRealName()} => {customRoles3}", "RoleAssign", escapeCRLF: true, 658, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); list2.Remove(val2); list.Remove(customRoles3); } if (list2.Any()) { Logger.Warn("Role assignment error: There are players who have not been assigned a role", "RoleAssign", escapeCRLF: true, 666, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } if (list.Any()) { Logger.Warn("Team assignment error: There is an unassigned team", "RoleAssign", escapeCRLF: true, 668, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\Core\\AssignManager\\RoleAssign.cs"); } RoleAssignInfo GetAssignInfo(CustomRoles role) { return Roles.Values.FirstOrDefault((List x) => x.Any((RoleAssignInfo y) => y.Role == role))?.FirstOrDefault((RoleAssignInfo x) => x.Role == role); } } public static void CalculateVanillaRoleCount() { AddEngineerNum = 0; AddScientistNum = 0; AddShapeshifterNum = 0; AddNoisemakerNum = 0; AddPhantomNum = 0; AddTrackerNum = 0; CustomRoles[] allRoles = AllRoles; for (int i = 0; i < allRoles.Length; i++) { switch (allRoles[i].GetVNRole()) { case CustomRoles.Scientist: AddScientistNum++; break; case CustomRoles.Engineer: AddEngineerNum++; break; case CustomRoles.Shapeshifter: AddShapeshifterNum++; break; case CustomRoles.Noisemaker: AddNoisemakerNum++; break; case CustomRoles.Phantom: AddPhantomNum++; break; case CustomRoles.Tracker: AddTrackerNum++; break; } } } } } namespace TOHE.Roles.AddOns.Impostor { public static class Circumvent { private const int Id = 22600; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(22600, CustomRoles.Circumvent, CustomGameMode.Standard, canSetNum: true); } public static bool CantUseVent(PlayerControl player) { return player.Is(CustomRoles.Circumvent); } } public static class Clumsy { private const int Id = 22700; private static OptionItem ChanceToMiss; private static Dictionary HasMissed; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(22700, CustomRoles.Clumsy, CustomGameMode.Standard, canSetNum: true); ChanceToMiss = IntegerOptionItem.Create(22703, "ChanceToMiss", new IntegerValueRule(0, 100, 5), 50, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Clumsy]).SetValueFormat(OptionFormat.Percent); } public static void Init() { HasMissed = new Dictionary(); } public static void Add(byte PlayerId) { HasMissed.Add(PlayerId, value: false); } public static void Remove(byte player) { HasMissed.Remove(player); } private static void MissChance(PlayerControl killer) { if (IRandom.Instance.Next(0, 101) < ChanceToMiss.GetInt()) { killer.RpcGuardAndKill(killer); killer.SetKillCooldown(); HasMissed[killer.PlayerId] = true; } } public static bool OnCheckMurder(PlayerControl killer) { MissChance(killer); if (HasMissed[killer.PlayerId]) { HasMissed[killer.PlayerId] = false; return false; } return true; } } public static class LastImpostor { private const int Id = 22800; public static byte currentId = byte.MaxValue; private static OptionItem CooldownReduction; public static void SetupCustomOption() { Options.SetupSingleRoleOptions(22800, TabGroup.Addons, CustomRoles.LastImpostor); CooldownReduction = FloatOptionItem.Create(22815, "OverclockedReduction", new FloatValueRule(5f, 95f, 5f), 50f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.LastImpostor]).SetValueFormat(OptionFormat.Percent); } public static void Init() { currentId = byte.MaxValue; } public static void Add(byte id) { currentId = id; } public static void SetKillCooldown() { if (currentId != byte.MaxValue && Main.AllPlayerKillCooldown.TryGetValue(currentId, out var value)) { float num = value * (CooldownReduction.GetFloat() / 100f); Main.AllPlayerKillCooldown[currentId] -= num; } } private static bool CanBeLastImpostor(PlayerControl pc) { if (pc.IsAlive() && !pc.Is(CustomRoles.LastImpostor) && !pc.Is(CustomRoles.Overclocked)) { return pc.Is(Custom_Team.Impostor); } return false; } public static void SetSubRole() { if (currentId != byte.MaxValue || !((InnerNetClient)AmongUsClient.Instance).AmHost || Options.CurrentGameMode == CustomGameMode.FFA || !CustomRoles.LastImpostor.IsEnable() || Main.AliveImpostorCount != 1) { return; } PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (CanBeLastImpostor(val)) { val.RpcSetCustomRole(CustomRoles.LastImpostor); Add(val.PlayerId); SetKillCooldown(); val.SyncSettings(); Utils.NotifyRoles(val, null, isForMeeting: false, NoCache: false, ForceLoop: false); break; } } } } public static class Madmate { private static readonly int Id1 = 60003; private static readonly int Id2 = 22900; public static OptionItem MadmateSpawnMode; public static OptionItem MadmateCountMode; public static OptionItem SheriffCanBeMadmate; public static OptionItem MayorCanBeMadmate; public static OptionItem NGuesserCanBeMadmate; public static OptionItem MarshallCanBeMadmate; public static OptionItem OverseerCanBeMadmate; public static OptionItem SnitchCanBeMadmate; public static OptionItem MadSnitchTasks; public static OptionItem RetributionistCanBeMadmate; public static OptionItem JudgeCanBeMadmate; public static OptionItem ImpKnowWhosMadmate; public static OptionItem ImpCanKillMadmate; public static OptionItem MadmateKnowWhosMadmate; public static OptionItem MadmateKnowWhosImp; public static OptionItem MadmateCanKillImp; private static OptionItem MadmateHasImpostorVision; private static readonly string[] madmateSpawnMode = new string[3] { "MadmateSpawnMode.Assign", "MadmateSpawnMode.FirstKill", "MadmateSpawnMode.SelfVote" }; private static readonly string[] madmateCountMode = new string[3] { "MadmateCountMode.None", "MadmateCountMode.Imp", "MadmateCountMode.Original" }; public static void SetupMenuOptions() { ImpKnowWhosMadmate = BooleanOptionItem.Create(Id1, "ImpKnowWhosMadmate", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetHeader(value: true).SetGameMode(CustomGameMode.Standard); ImpCanKillMadmate = BooleanOptionItem.Create(Id1 + 1, "ImpCanKillMadmate", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard); MadmateKnowWhosMadmate = BooleanOptionItem.Create(Id1 + 2, "MadmateKnowWhosMadmate", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetHeader(value: true).SetGameMode(CustomGameMode.Standard); MadmateKnowWhosImp = BooleanOptionItem.Create(Id1 + 3, "MadmateKnowWhosImp", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard); MadmateCanKillImp = BooleanOptionItem.Create(Id1 + 4, "MadmateCanKillImp", defaultValue: true, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard); MadmateHasImpostorVision = BooleanOptionItem.Create(Id1 + 7, "MadmateHasImpostorVision", defaultValue: false, TabGroup.ImpostorRoles, isSingleValue: false).SetGameMode(CustomGameMode.Standard); } public static void SetupCustomMenuOptions() { Options.SetupAdtRoleOptions(Id2, CustomRoles.Madmate, CustomGameMode.Standard, canSetNum: true, TabGroup.Addons, canSetChance: false); MadmateSpawnMode = StringOptionItem.Create(Id2 + 3, "MadmateSpawnMode", madmateSpawnMode, 0, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); MadmateCountMode = StringOptionItem.Create(Id2 + 4, "MadmateCountMode", madmateCountMode, 1, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); SheriffCanBeMadmate = BooleanOptionItem.Create(Id2 + 5, "SheriffCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); MayorCanBeMadmate = BooleanOptionItem.Create(Id2 + 6, "MayorCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); NGuesserCanBeMadmate = BooleanOptionItem.Create(Id2 + 7, "NGuesserCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); MarshallCanBeMadmate = BooleanOptionItem.Create(Id2 + 8, "MarshallCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); RetributionistCanBeMadmate = BooleanOptionItem.Create(Id2 + 10, "RetributionistCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); OverseerCanBeMadmate = BooleanOptionItem.Create(Id2 + 9, "OverseerCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); SnitchCanBeMadmate = BooleanOptionItem.Create(Id2 + 11, "SnitchCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); MadSnitchTasks = IntegerOptionItem.Create(Id2 + 12, "MadSnitchTasks", new IntegerValueRule(1, 30, 1), 3, TabGroup.Addons, isSingleValue: false).SetParent(SnitchCanBeMadmate).SetValueFormat(OptionFormat.Pieces); JudgeCanBeMadmate = BooleanOptionItem.Create(Id2 + 13, "JudgeCanBeMadmate", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Madmate]); } public static void ApplyGameOptions(IGameOptions opt) { opt.SetVision(MadmateHasImpostorVision.GetBool()); } public static bool CanBeMadmate(this PlayerControl pc, bool forAdmirer = false, bool forGangster = false) { if ((Object)(object)pc != (Object)null && !pc.Is(CustomRoles.Madmate) && (pc.GetCustomRole().IsCrewmate() || (forAdmirer && pc.GetCustomRole().IsNeutral()))) { if (!pc.CheckCanBeMadmate(forGangster) && !pc.Is(CustomRoles.LazyGuy) && !pc.Is(CustomRoles.Lazy) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.SuperStar) && !pc.Is(CustomRoles.Celebrity) && !pc.Is(CustomRoles.TaskManager) && !pc.Is(CustomRoles.Egoist) && !pc.Is(CustomRoles.Paranoia) && !pc.Is(CustomRoles.Vigilante) && (!pc.Is(CustomRoles.NiceMini) || Mini.Age < 18)) { if (pc.Is(CustomRoles.Hurried)) { return Hurried.CanBeOnMadMate.GetBool(); } return true; } return false; } return false; } public static bool CheckCanBeMadmate(this PlayerControl pc, bool forGangster = false) { if ((!pc.Is(CustomRoles.Sheriff) || !((!forGangster) ? (!SheriffCanBeMadmate.GetBool()) : (!Gangster.SheriffCanBeMadmate.GetBool()))) && (!pc.Is(CustomRoles.Mayor) || !((!forGangster) ? (!MayorCanBeMadmate.GetBool()) : (!Gangster.MayorCanBeMadmate.GetBool()))) && (!pc.Is(CustomRoles.NiceGuesser) || !((!forGangster) ? (!NGuesserCanBeMadmate.GetBool()) : (!Gangster.NGuesserCanBeMadmate.GetBool()))) && (!pc.Is(CustomRoles.Snitch) || SnitchCanBeMadmate.GetBool()) && (!pc.Is(CustomRoles.Judge) || !((!forGangster) ? (!JudgeCanBeMadmate.GetBool()) : (!Gangster.JudgeCanBeMadmate.GetBool()))) && (!pc.Is(CustomRoles.Marshall) || !((!forGangster) ? (!MarshallCanBeMadmate.GetBool()) : (!Gangster.MarshallCanBeMadmate.GetBool()))) && (!pc.Is(CustomRoles.Retributionist) || !((!forGangster) ? (!RetributionistCanBeMadmate.GetBool()) : (!Gangster.RetributionistCanBeMadmate.GetBool())))) { if (pc.Is(CustomRoles.Overseer)) { if (forGangster) { return !Gangster.OverseerCanBeMadmate.GetBool(); } return !OverseerCanBeMadmate.GetBool(); } return false; } return true; } } public static class Mare { private const int Id = 23000; public static List playerIdList = new List(); public static OptionItem KillCooldownInLightsOut; private static OptionItem SpeedInLightsOut; private static bool idAccelerated = false; public static bool IsEnable => playerIdList.Any(); public static float GetKillCooldown { get { if (!Utils.IsActive((SystemTypes)7)) { return Options.DefaultKillCooldown; } return KillCooldownInLightsOut.GetFloat(); } } public static bool IsLightsOut => !Utils.IsActive((SystemTypes)7); public static void SetupCustomOption() { Options.SetupAdtRoleOptions(23000, CustomRoles.Mare, CustomGameMode.Standard, canSetNum: true); SpeedInLightsOut = FloatOptionItem.Create(23010, "MareAddSpeedInLightsOut", new FloatValueRule(0.1f, 0.5f, 0.1f), 0.3f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mare]).SetValueFormat(OptionFormat.Multiplier); KillCooldownInLightsOut = FloatOptionItem.Create(23011, "MareKillCooldownInLightsOut", new FloatValueRule(0f, 180f, 2.5f), 7.5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mare]).SetValueFormat(OptionFormat.Seconds); } public static void Init() { playerIdList = new List(); } public static void Add(byte mare) { playerIdList.Add(mare); } public static void ApplyGameOptions(byte playerId) { if (Utils.IsActive((SystemTypes)7) && !idAccelerated) { idAccelerated = true; Main.AllPlayerSpeed[playerId] += SpeedInLightsOut.GetFloat(); } else if (!Utils.IsActive((SystemTypes)7) && idAccelerated) { idAccelerated = false; Main.AllPlayerSpeed[playerId] -= SpeedInLightsOut.GetFloat(); } } public static bool KnowTargetRoleColor(PlayerControl target, bool isMeeting) { if (!isMeeting && playerIdList.Contains(target.PlayerId)) { return Utils.IsActive((SystemTypes)7); } return false; } } public static class Mimic { private const int Id = 23100; private static OptionItem CanSeeDeadRolesOpt; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(23100, CustomRoles.Mimic, CustomGameMode.Standard, canSetNum: true); CanSeeDeadRolesOpt = BooleanOptionItem.Create(23110, "MimicCanSeeDeadRoles", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mimic]); } public static bool CanSeeDeadRoles(PlayerControl seer, PlayerControl target) { if (seer.Is(CustomRoles.Mimic) && CanSeeDeadRolesOpt.GetBool() && Main.VisibleTasksCount) { return !target.IsAlive(); } return false; } } public static class Stealer { private const int Id = 23200; private static OptionItem TicketsPerKill; private static OptionItem HideAdditionalVotes; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(23200, CustomRoles.TicketsStealer, CustomGameMode.Standard, canSetNum: true); TicketsPerKill = FloatOptionItem.Create(23203, "TicketsPerKill", new FloatValueRule(0.1f, 10f, 0.1f), 0.5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TicketsStealer]); HideAdditionalVotes = BooleanOptionItem.Create(23204, "HideAdditionalVotes", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.TicketsStealer]); } public static int AddRealVotesNum(PlayerVoteArea ps) { return (int)((float)Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == ps.TargetPlayerId; }) * TicketsPerKill.GetFloat()); } public static void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!HideAdditionalVotes.GetBool()) { int num = (int)((float)Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == votedPlayer.TargetPlayerId; }) * TicketsPerKill.GetFloat()); for (int i = 0; i < num; i++) { statesList.Add(new VoterState { VoterId = votedPlayer.TargetPlayerId, VotedForId = votedPlayer.VotedFor }); } } } public static void OnMurderPlayer(PlayerControl killer) { killer.Notify(string.Format(Translator.GetString("TicketsStealerGetTicket"), ((float)(Main.AllPlayerControls.Count(delegate(PlayerControl x) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == killer.PlayerId; }) + 1) * TicketsPerKill.GetFloat()).ToString("0.0#####"))); } } public static class Swift { private const int Id = 23300; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(23300, CustomRoles.Swift, CustomGameMode.Standard, canSetNum: true); } public static bool OnCheckMurder(PlayerControl killer, PlayerControl target) { if (!Options.DisableShieldAnimations.GetBool()) { killer.RpcGuardAndKill(killer); } if (target.Is(CustomRoles.Trapper)) { killer.TrapperKilled(target); } killer.SetKillCooldown(); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); return false; } } public static class Tricky { private const int Id = 19900; private static OptionItem EnabledDeathReasons; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(19900, CustomRoles.Tricky, CustomGameMode.Standard, canSetNum: true); EnabledDeathReasons = BooleanOptionItem.Create(19911, "OnlyEnabledDeathReasons", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tricky]); } private static PlayerState.DeathReason ChangeRandomDeath() { PlayerState.DeathReason[] array = (from reason in EnumHelper.GetAllValues() where reason.IsReasonEnabled() select reason).ToArray(); if (array.Length == 0 || !array.Contains(PlayerState.DeathReason.Kill)) { CollectionExtensions.AddItem((IEnumerable)array, PlayerState.DeathReason.Kill); } int num = IRandom.Instance.Next(array.Length); return array[num]; } private static bool IsReasonEnabled(this PlayerState.DeathReason reason) { if (reason == PlayerState.DeathReason.etc) { return false; } if (!EnabledDeathReasons.GetBool()) { return true; } return reason.DeathReasonIsEnable(); } public static void AfterPlayerDeathTasks(PlayerControl target) { if ((Object)(object)target == (Object)null) { return; } new LateTask(delegate { PlayerControl realKiller = target.GetRealKiller(); if (!((Object)(object)realKiller == (Object)null) && realKiller.Is(CustomRoles.Tricky)) { PlayerState.DeathReason deathReason = ChangeRandomDeath(); Main.PlayerStates[target.PlayerId].deathReason = deathReason; Main.PlayerStates[target.PlayerId].SetDead(); Utils.NotifyRoles(target); Logger.Info($"Set death reason: {deathReason}", "Tricky", escapeCRLF: true, 46, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Impostor\\Tricky.cs"); } }, 0.3f, "Tricky random death reason"); } } } namespace TOHE.Roles.AddOns.Crewmate { public static class Bloodthirst { private const int Id = 21700; public static OptionItem ImpCanBeAutopsy; public static OptionItem CrewCanBeAutopsy; public static OptionItem NeutralCanBeAutopsy; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21700, CustomRoles.Bloodthirst, CustomGameMode.Standard, canSetNum: true); } public static void Add() { Alchemist.AddBloodlus(); } public static void OnTaskComplete(PlayerControl player) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!Alchemist.BloodthirstList.ContainsKey(player.PlayerId)) { Alchemist.BloodthirstList[player.PlayerId] = player.PlayerId; player.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Bloodthirst)), Translator.GetString("BloodthirstAdded"))); } } } public class Ghoul { private const int Id = 21900; public static HashSet KillGhoul = new HashSet(); public static bool IsEnable; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21900, CustomRoles.Ghoul, CustomGameMode.Standard, canSetNum: true); } public static void Init() { KillGhoul = new HashSet(); IsEnable = false; } public static void Add() { IsEnable = true; } public static void ApplyGameOptions(PlayerControl player) { if (Main.AllPlayerControls.Any(delegate(PlayerControl x) { if (x.Is(CustomRoles.Ghoul) && !x.IsAlive()) { PlayerControl realKiller = x.GetRealKiller(); return ((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == player.PlayerId; } return false; }) && !player.Is(CustomRoles.Pestilence)) { KillGhoul.Add(player.PlayerId); } } public static void OnTaskComplete(PlayerControl player) { if (player.IsAlive()) { new LateTask(delegate { player.SetDeathReason(PlayerState.DeathReason.Suicide); player.RpcMurderPlayer(player); }, 0.2f, "Ghoul Suicide"); return; } foreach (PlayerControl item in Main.AllAlivePlayerControls.Where((PlayerControl x) => KillGhoul.Contains(x.PlayerId))) { item.SetDeathReason(PlayerState.DeathReason.Kill); player.RpcMurderPlayer(item); } } } public static class Hurried { private const int Id = 21300; public static OptionItem CanBeOnMadMate; public static OptionItem CanBeOnTaskBasedCrew; public static OptionItem CanBeConverted; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(21300, CustomRoles.Hurried, CustomGameMode.Standard, canSetNum: true); CanBeOnMadMate = BooleanOptionItem.Create(21311, "MadmateCanBeHurried", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hurried]); CanBeOnTaskBasedCrew = BooleanOptionItem.Create(21312, "TaskBasedCrewCanBeHurried", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hurried]); CanBeConverted = BooleanOptionItem.Create(21313, "HurriedCanBeConverted", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hurried]); } public static bool CheckWinState(PlayerControl pc) { if ((Object)(object)pc == (Object)null) { return false; } if (!pc.Is(CustomRoles.Hurried)) { return true; } if (!pc.GetCustomRole().IsCrewmate() && !pc.Is(CustomRoles.Madmate)) { return true; } if (pc.GetCustomRole().IsTasklessCrewmate()) { return true; } if (pc.Is(CustomRoles.Madmate) && !CanBeOnMadMate.GetBool()) { return true; } if (pc.GetCustomRole().IsTaskBasedCrewmate() && !CanBeOnTaskBasedCrew.GetBool()) { return true; } TaskState playerTaskState = pc.GetPlayerTaskState(); if (!playerTaskState.hasTasks || playerTaskState.IsTaskFinished) { return true; } foreach (CustomRoles customSubRole in pc.GetCustomSubRoles()) { if (customSubRole.IsConverted() && !CanBeConverted.GetBool()) { return true; } } return false; } } public class Lazy { private const int Id = 19300; private static OptionItem TasklessCrewCanBeLazy; private static OptionItem TaskBasedCrewCanBeLazy; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19300, CustomRoles.Lazy, CustomGameMode.Standard, canSetNum: true); TasklessCrewCanBeLazy = BooleanOptionItem.Create(19310, "TasklessCrewCanBeLazy", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lazy]); TaskBasedCrewCanBeLazy = BooleanOptionItem.Create(19311, "TaskBasedCrewCanBeLazy", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lazy]); } public static bool CheckConflicts(PlayerControl player) { if (player.Is(CustomRoles.Ghoul) || player.Is(CustomRoles.LazyGuy)) { return false; } if (player.GetCustomRole().IsNeutral() || player.GetCustomRole().IsImpostor() || (player.GetCustomRole().IsTasklessCrewmate() && !TasklessCrewCanBeLazy.GetBool()) || (player.GetCustomRole().IsTaskBasedCrewmate() && !TaskBasedCrewCanBeLazy.GetBool())) { return false; } return true; } } public class Nimble { private const int Id = 19700; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19700, CustomRoles.Nimble, CustomGameMode.Standard, canSetNum: true); } } public class Rascal { private const int Id = 20800; private static OptionItem RascalAppearAsMadmate; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20800, CustomRoles.Rascal, CustomGameMode.Standard, canSetNum: true); RascalAppearAsMadmate = BooleanOptionItem.Create(20810, "RascalAppearAsMadmate", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rascal]); } public static bool AppearAsMadmate(PlayerControl player) { if (RascalAppearAsMadmate.GetBool()) { return player.Is(CustomRoles.Rascal); } return false; } } public class Torch { private const int Id = 20300; private static OptionItem TorchVision; private static OptionItem TorchAffectedByLights; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20300, CustomRoles.Torch, CustomGameMode.Standard, canSetNum: true); TorchVision = FloatOptionItem.Create(20310, "TorchVision", new FloatValueRule(0.5f, 5f, 0.25f), 1.25f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Torch]).SetValueFormat(OptionFormat.Multiplier); TorchAffectedByLights = BooleanOptionItem.Create(20311, "TorchAffectedByLights", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Torch]); } public static void ApplyGameOptions(IGameOptions opt) { if (!Utils.IsActive((SystemTypes)7)) { opt.SetVision(HasImpVision: true); } opt.SetFloat((FloatOptionNames)4, TorchVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, TorchVision.GetFloat()); if (Utils.IsActive((SystemTypes)7) && !TorchAffectedByLights.GetBool()) { opt.SetVision(HasImpVision: true); } opt.SetFloat((FloatOptionNames)4, TorchVision.GetFloat() * 5f); opt.SetFloat((FloatOptionNames)3, TorchVision.GetFloat() * 5f); } } public static class Workhorse { private const int Id = 23730; private static readonly HashSet playerIdList = new HashSet(); public static bool IsEnable = false; public static Color RoleColor = Utils.GetRoleColor(CustomRoles.Workhorse); private static OptionItem OptionAssignOnlyToCrewmate; private static OptionItem OptionNumLongTasks; private static OptionItem OptionNumShortTasks; private static OptionItem OptionSnitchCanBeWorkhorse; private static bool AssignOnlyToCrewmate; private static int NumLongTasks; private static int NumShortTasks; public static (bool, int, int) TaskData => (false, NumLongTasks, NumShortTasks); public static void SetupCustomOption() { Options.SetupRoleOptions(23730, TabGroup.Addons, CustomRoles.Workhorse, CustomGameMode.Standard, zeroOne: true); OptionAssignOnlyToCrewmate = BooleanOptionItem.Create(23740, "AssignOnlyToCrewmate", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workhorse]); OptionNumLongTasks = IntegerOptionItem.Create(23741, "WorkhorseNumLongTasks", new IntegerValueRule(0, 5, 1), 1, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workhorse]).SetValueFormat(OptionFormat.Pieces); OptionNumShortTasks = IntegerOptionItem.Create(23742, "WorkhorseNumShortTasks", new IntegerValueRule(0, 5, 1), 1, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workhorse]).SetValueFormat(OptionFormat.Pieces); OptionSnitchCanBeWorkhorse = BooleanOptionItem.Create(23744, "SnitchCanBeWorkhorse", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Workhorse]); } public static void Init() { playerIdList.Clear(); IsEnable = false; AssignOnlyToCrewmate = OptionAssignOnlyToCrewmate.GetBool(); NumLongTasks = OptionNumLongTasks.GetInt(); NumShortTasks = OptionNumShortTasks.GetInt(); } public static void Add(byte playerId) { playerIdList.Add(playerId); IsEnable = true; } public static bool IsThisRole(byte playerId) { return playerIdList.Contains(playerId); } private static bool IsAssignTarget(PlayerControl pc) { if (!pc.IsAlive() || IsThisRole(pc.PlayerId)) { return false; } if (pc.Is(CustomRoles.Snitch) && !OptionSnitchCanBeWorkhorse.GetBool()) { return false; } if (pc.Is(CustomRoles.LazyGuy) || pc.Is(CustomRoles.Lazy)) { return false; } TaskState playerTaskState = pc.GetPlayerTaskState(); if (playerTaskState.CompletedTasksCount < playerTaskState.AllTasksCount) { return false; } if (AssignOnlyToCrewmate) { return pc.Is(Custom_Team.Crewmate); } if (Utils.HasTasks(pc.Data)) { return !Options.OverrideTasksData.AllData.ContainsKey(pc.GetCustomRole()); } return false; } public static bool OnAddTask(PlayerControl pc) { if (!CustomRoles.Workhorse.IsEnable() || playerIdList.Count >= CustomRoles.Workhorse.GetCount()) { return true; } if (!IsAssignTarget(pc)) { return true; } pc.RpcSetCustomRole(CustomRoles.Workhorse); pc.GetPlayerTaskState().AllTasksCount += NumLongTasks + NumShortTasks; if (((InnerNetClient)AmongUsClient.Instance).AmHost) { Add(pc.PlayerId); pc.Data.RpcSetTasks(new Il2CppStructArray(0L)); pc.SyncSettings(); Utils.NotifyRoles(pc); } return false; } } } namespace TOHE.Roles.AddOns.Common { public static class Antidote { private const int Id = 21400; public static bool IsEnable = false; public static OptionItem ImpCanBeAntidote; public static OptionItem CrewCanBeAntidote; public static OptionItem NeutralCanBeAntidote; private static OptionItem AntidoteCDOpt; private static OptionItem AntidoteCDReset; private static Dictionary KilledAntidote = new Dictionary(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21400, CustomRoles.Antidote, CustomGameMode.Standard, canSetNum: true); ImpCanBeAntidote = BooleanOptionItem.Create(21410, "ImpCanBeAntidote", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Antidote]); CrewCanBeAntidote = BooleanOptionItem.Create(21411, "CrewCanBeAntidote", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Antidote]); NeutralCanBeAntidote = BooleanOptionItem.Create(21412, "NeutralCanBeAntidote", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Antidote]); AntidoteCDOpt = FloatOptionItem.Create(21413, "AntidoteCDOpt", new FloatValueRule(0f, 180f, 1f), 5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Antidote]).SetValueFormat(OptionFormat.Seconds); AntidoteCDReset = BooleanOptionItem.Create(21414, "AntidoteCDReset", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Antidote]); } public static void Init() { KilledAntidote = new Dictionary(); IsEnable = false; } public static void Add() { IsEnable = true; } public static void ReduceKCD(PlayerControl player) { if (KilledAntidote.ContainsKey(player.PlayerId)) { float num = Main.AllPlayerKillCooldown[player.PlayerId] - (float)KilledAntidote[player.PlayerId] * AntidoteCDOpt.GetFloat(); if (num < 0f) { num = 0f; } Main.AllPlayerKillCooldown[player.PlayerId] = num; Logger.Info($"kill cd of player set to {Main.AllPlayerKillCooldown[player.PlayerId]}", "Antidote", escapeCRLF: true, 46, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Antidote.cs"); } } public static void AfterMeetingTasks() { if (!AntidoteCDReset.GetBool()) { return; } byte[] array = KilledAntidote.Keys.ToArray(); foreach (byte b in array) { KilledAntidote[b] = 0; PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { playerById.ResetKillCooldown(); } } KilledAntidote = new Dictionary(); } public static void CheckMurder(PlayerControl killer) { if (KilledAntidote.ContainsKey(killer.PlayerId)) { KilledAntidote[killer.PlayerId]++; } else { KilledAntidote.Add(killer.PlayerId, 1); } } } public static class Autopsy { private const int Id = 18600; public static OptionItem ImpCanBeAutopsy; public static OptionItem CrewCanBeAutopsy; public static OptionItem NeutralCanBeAutopsy; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(18600, CustomRoles.Autopsy, CustomGameMode.Standard, canSetNum: true); ImpCanBeAutopsy = BooleanOptionItem.Create(18610, "ImpCanBeAutopsy", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Autopsy]); CrewCanBeAutopsy = BooleanOptionItem.Create(18611, "CrewCanBeAutopsy", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Autopsy]); NeutralCanBeAutopsy = BooleanOptionItem.Create(18612, "NeutralCanBeAutopsy", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Autopsy]); } } public static class Avanger { private const int Id = 21500; public static OptionItem ImpCanBeAvanger; public static OptionItem CrewCanBeAvanger; public static OptionItem NeutralCanBeAvanger; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21500, CustomRoles.Avanger, CustomGameMode.Standard, canSetNum: true); ImpCanBeAvanger = BooleanOptionItem.Create(21510, "ImpCanBeAvanger", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Avanger]); CrewCanBeAvanger = BooleanOptionItem.Create(21512, "CrewCanBeAvanger", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Avanger]); NeutralCanBeAvanger = BooleanOptionItem.Create(21513, "NeutralCanBeAvanger", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Avanger]); } public static void OnMurderPlayer(PlayerControl target) { List list = Main.AllAlivePlayerControls.Where((PlayerControl pc) => pc.PlayerId != target.PlayerId && !Pelican.IsEaten(pc.PlayerId) && !Medic.ProtectList.Contains(pc.PlayerId) && !pc.Is(CustomRoles.Pestilence) && !pc.Is(CustomRoles.Necromancer) && !pc.Is(CustomRoles.PunchingBag) && !pc.Is(CustomRoles.Solsticer) && ((!pc.Is(CustomRoles.NiceMini) && !pc.Is(CustomRoles.EvilMini)) || Mini.Age >= 18)).ToList(); if (list.Any()) { PlayerControl obj = list.RandomElement(); obj.SetDeathReason(PlayerState.DeathReason.Revenge); obj.RpcMurderPlayer(obj); obj.SetRealKiller(target); } } } public static class Aware { private const int Id = 21600; public static bool IsEnable = false; public static OptionItem ImpCanBeAware; public static OptionItem CrewCanBeAware; public static OptionItem NeutralCanBeAware; private static OptionItem AwareknowRole; public static Dictionary> AwareInteracted = new Dictionary>(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21600, CustomRoles.Aware, CustomGameMode.Standard, canSetNum: true); ImpCanBeAware = BooleanOptionItem.Create(21610, "ImpCanBeAware", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Aware]); CrewCanBeAware = BooleanOptionItem.Create(21611, "CrewCanBeAware", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Aware]); NeutralCanBeAware = BooleanOptionItem.Create(21612, "NeutralCanBeAware", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Aware]); AwareknowRole = BooleanOptionItem.Create(21613, "AwareKnowRole", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Aware]); } public static void Init() { AwareInteracted = new Dictionary>(); IsEnable = false; } public static void Add(byte playerId) { AwareInteracted[playerId] = new List(); IsEnable = true; } public static void OnCheckMurder(CustomRoles killerRole, PlayerControl target) { if (killerRole == CustomRoles.Consigliere || killerRole == CustomRoles.Overseer) { if (!AwareInteracted.ContainsKey(target.PlayerId)) { AwareInteracted.Add(target.PlayerId, new List()); } if (!AwareInteracted[target.PlayerId].Contains(Utils.GetRoleName(killerRole))) { AwareInteracted[target.PlayerId].Add(Utils.GetRoleName(killerRole)); } } } public static void OnReportDeadBody() { byte[] array = AwareInteracted.Keys.ToArray(); foreach (byte pid in array) { PlayerControl playerById = Utils.GetPlayerById(pid); if (!AwareInteracted[pid].Any() || !playerById.IsAlive()) { continue; } string rolelist = "Someone"; new LateTask(delegate { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (AwareknowRole.GetBool()) { rolelist = string.Join(", ", AwareInteracted[pid]); } Utils.SendMessage(string.Format(Translator.GetString("AwareInteracted"), rolelist), pid, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Aware)), Translator.GetString("AwareTitle"))); AwareInteracted[pid] = new List(); }, 0.5f, "Aware Check Msg"); } } public static void OnVoted(PlayerControl pc, PlayerVoteArea pva) { CustomRoles customRole = pc.GetCustomRole(); if (customRole == CustomRoles.FortuneTeller || customRole == CustomRoles.Oracle) { if (!AwareInteracted.ContainsKey(pva.VotedFor)) { AwareInteracted[pva.VotedFor] = new List(); } if (!AwareInteracted[pva.VotedFor].Contains(Utils.GetRoleName(pc.GetCustomRole()))) { AwareInteracted[pva.VotedFor].Add(Utils.GetRoleName(pc.GetCustomRole())); } } } } public static class Bait { private const int Id = 18700; public static OptionItem ImpCanBeBait; public static OptionItem CrewCanBeBait; public static OptionItem NeutralCanBeBait; public static OptionItem BaitDelayMin; public static OptionItem BaitDelayMax; public static OptionItem BaitDelayNotify; public static OptionItem BaitNotification; public static OptionItem BaitCanBeReportedUnderAllConditions; public static List BaitAlive = new List(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(18700, CustomRoles.Bait, CustomGameMode.Standard, canSetNum: true); ImpCanBeBait = BooleanOptionItem.Create(18710, "ImpCanBeBait", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); CrewCanBeBait = BooleanOptionItem.Create(18711, "CrewCanBeBait", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); NeutralCanBeBait = BooleanOptionItem.Create(18712, "NeutralCanBeBait", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); BaitDelayMin = FloatOptionItem.Create(18713, "BaitDelayMin", new FloatValueRule(0f, 5f, 1f), 0f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]).SetValueFormat(OptionFormat.Seconds); BaitDelayMax = FloatOptionItem.Create(18714, "BaitDelayMax", new FloatValueRule(0f, 10f, 1f), 0f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]).SetValueFormat(OptionFormat.Seconds); BaitDelayNotify = BooleanOptionItem.Create(18715, "BaitDelayNotify", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); BaitNotification = BooleanOptionItem.Create(18716, "BaitNotification", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); BaitCanBeReportedUnderAllConditions = BooleanOptionItem.Create(18717, "BaitCanBeReportedUnderAllConditions", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bait]); } public static void Init() { BaitAlive = new List(); } public static void BaitAfterDeathTasks(PlayerControl killer, PlayerControl target) { //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if (killer.PlayerId == target.PlayerId && (Object)(object)target.GetRealKiller() != (Object)null) { if (!target.GetRealKiller().IsAlive()) { return; } killer = target.GetRealKiller(); } if (killer.PlayerId == target.PlayerId || killer.Is(CustomRoles.KillingMachine) || killer.Is(CustomRoles.Swooper) || killer.Is(CustomRoles.Wraith) || (killer.Is(CustomRoles.Oblivious) && Oblivious.ObliviousBaitImmune.GetBool())) { return; } killer.RPCPlayCustomSound("Congrats"); target.RPCPlayCustomSound("Congrats"); float val = ((!(BaitDelayMax.GetFloat() < BaitDelayMin.GetFloat())) ? ((float)IRandom.Instance.Next((int)BaitDelayMin.GetFloat(), (int)BaitDelayMax.GetFloat() + 1)) : 0f); val = Math.Max(val, 0.15f); if (val > 0.15f && BaitDelayNotify.GetBool()) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Bait)), string.Format(Translator.GetString("KillBaitNotify"), (int)val)), val); } Logger.Info(killer.GetNameWithRole() + " 击杀诱饵 => " + target.GetNameWithRole(), "MurderPlayer", escapeCRLF: true, 69, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Bait.cs"); new LateTask(delegate { if (GameStates.IsInTask && GameStates.IsInGame) { PlayerControl obj = killer; if (obj != null) { obj.CmdReportDeadBody(target.Data); } } }, val, "Bait Self Report"); } } public static class Trapper { private const int Id = 18800; public static OptionItem ImpCanBeTrapper; public static OptionItem CrewCanBeTrapper; public static OptionItem NeutralCanBeTrapper; private static OptionItem TrapperBlockMoveTime; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(18800, CustomRoles.Trapper, CustomGameMode.Standard, canSetNum: true); ImpCanBeTrapper = BooleanOptionItem.Create(18810, "ImpCanBeTrapper", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapper]); CrewCanBeTrapper = BooleanOptionItem.Create(18811, "CrewCanBeTrapper", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapper]); NeutralCanBeTrapper = BooleanOptionItem.Create(18812, "NeutralCanBeTrapper", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapper]); TrapperBlockMoveTime = FloatOptionItem.Create(18813, "TrapperBlockMoveTime", new FloatValueRule(1f, 180f, 1f), 5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Trapper]).SetValueFormat(OptionFormat.Seconds); } public static void TrapperKilled(this PlayerControl killer, PlayerControl target) { object obj; if (target == null) { obj = null; } else { NetworkedPlayerInfo data = target.Data; obj = ((data != null) ? data.PlayerName : null); } Logger.Info((string?)obj + " was Trapper", "Trapper", escapeCRLF: true, 25, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Beartrap.cs"); float tmpSpeed = Main.AllPlayerSpeed[killer.PlayerId]; Main.AllPlayerSpeed[killer.PlayerId] = 0.0001f; ReportDeadBodyPatch.CanReport[killer.PlayerId] = false; killer.MarkDirtySettings(); new LateTask(delegate { Main.AllPlayerSpeed[killer.PlayerId] = Main.AllPlayerSpeed[killer.PlayerId] - 0.0001f + tmpSpeed; ReportDeadBodyPatch.CanReport[killer.PlayerId] = true; killer.MarkDirtySettings(); RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); }, TrapperBlockMoveTime.GetFloat(), "Trapper BlockMove"); } } public static class Bewilder { private const int Id = 18900; private static OptionItem BewilderVision; public static OptionItem ImpCanBeBewilder; public static OptionItem CrewCanBeBewilder; public static OptionItem NeutralCanBeBewilder; private static OptionItem KillerGetBewilderVision; public static bool IsEnable; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(18900, CustomRoles.Bewilder, CustomGameMode.Standard, canSetNum: true); BewilderVision = FloatOptionItem.Create(18910, "BewilderVision", new FloatValueRule(0f, 5f, 0.05f), 0.6f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bewilder]).SetValueFormat(OptionFormat.Multiplier); ImpCanBeBewilder = BooleanOptionItem.Create(18911, "ImpCanBeBewilder", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bewilder]); CrewCanBeBewilder = BooleanOptionItem.Create(18912, "CrewCanBeBewilder", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bewilder]); NeutralCanBeBewilder = BooleanOptionItem.Create(18913, "NeutralCanBeBewilder", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bewilder]); KillerGetBewilderVision = BooleanOptionItem.Create(18914, "KillerGetBewilderVision", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bewilder]); } public static void Init() { IsEnable = false; } public static void Add() { IsEnable = true; } public static void ApplyVisionOptions(IGameOptions opt) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)3, BewilderVision.GetFloat()); opt.SetFloat((FloatOptionNames)4, BewilderVision.GetFloat()); } public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) { if (Main.AllPlayerControls.Any(delegate(PlayerControl x) { if (x.Is(CustomRoles.Bewilder) && !x.IsAlive()) { PlayerControl realKiller = x.GetRealKiller(); if (((realKiller != null) ? new byte?(realKiller.PlayerId) : null) == player.PlayerId && KillerGetBewilderVision.GetBool()) { return !x.Is(CustomRoles.Hangman); } } return false; })) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, BewilderVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, BewilderVision.GetFloat()); } } } public static class Burst { private const int Id = 19000; public static bool IsEnable = false; public static OptionItem ImpCanBeBurst; public static OptionItem CrewCanBeBurst; public static OptionItem NeutralCanBeBurst; private static OptionItem BurstKillDelay; private static readonly List BurstBodies = new List(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19000, CustomRoles.Burst, CustomGameMode.Standard, canSetNum: true); ImpCanBeBurst = BooleanOptionItem.Create(19010, "ImpCanBeBurst", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Burst]); CrewCanBeBurst = BooleanOptionItem.Create(19011, "CrewCanBeBurst", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Burst]); NeutralCanBeBurst = BooleanOptionItem.Create(19012, "NeutralCanBeBurst", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Burst]); BurstKillDelay = FloatOptionItem.Create(19013, "BurstKillDelay", new FloatValueRule(1f, 180f, 1f), 5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Burst]).SetValueFormat(OptionFormat.Seconds); } public static void Init() { BurstBodies.Clear(); IsEnable = false; } public static void Add() { IsEnable = true; } public static void AfterMeetingTasks() { BurstBodies.Clear(); } public static void AfterBurstDeadTasks(PlayerControl killer, PlayerControl target) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) target.SetRealKiller(killer); BurstBodies.Add(target.PlayerId); if (killer.PlayerId == target.PlayerId || killer.Is(CustomRoles.Pestilence)) { return; } killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Burst)), Translator.GetString("BurstNotify"))); new LateTask(delegate { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) if (!killer.inVent && killer.IsAlive() && !GameStates.IsMeeting && GameStates.IsInGame) { killer.SetDeathReason(PlayerState.DeathReason.Bombed); target.RpcMurderPlayer(killer); killer.SetRealKiller(target); } else if (GameStates.IsInGame) { RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); killer.SetKillCooldown(Main.AllPlayerKillCooldown[killer.PlayerId] - BurstKillDelay.GetFloat(), null, forceAnime: true); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Burst)), Translator.GetString("BurstFailed"))); } BurstBodies.Remove(target.PlayerId); }, BurstKillDelay.GetFloat(), "Burst Suicide"); } } public class Cyber { private const int Id = 19100; public static List CyberDead = new List(); public static OptionItem ImpCanBeCyber; public static OptionItem CrewCanBeCyber; public static OptionItem NeutralCanBeCyber; public static OptionItem ImpKnowCyberDead; public static OptionItem CrewKnowCyberDead; public static OptionItem NeutralKnowCyberDead; public static OptionItem CyberKnown; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19100, CustomRoles.Cyber, CustomGameMode.Standard, canSetNum: true); ImpCanBeCyber = BooleanOptionItem.Create(19110, "ImpCanBeCyber", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); CrewCanBeCyber = BooleanOptionItem.Create(19111, "CrewCanBeCyber", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); NeutralCanBeCyber = BooleanOptionItem.Create(19112, "NeutralCanBeCyber", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); ImpKnowCyberDead = BooleanOptionItem.Create(19113, "ImpKnowCyberDead", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); CrewKnowCyberDead = BooleanOptionItem.Create(19114, "CrewKnowCyberDead", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); NeutralKnowCyberDead = BooleanOptionItem.Create(19115, "NeutralKnowCyberDead", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); CyberKnown = BooleanOptionItem.Create(19116, "CyberKnown", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cyber]); } public static void Init() { CyberDead = new List(); } public static void Clear() { CyberDead.Clear(); } public static void AfterCyberDeadTask(PlayerControl target, bool inMeeting) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (target.IsDisconnected()) { return; } PlayerControl[] allPlayerControls = Main.AllPlayerControls; foreach (PlayerControl val in allPlayerControls) { if ((ImpKnowCyberDead.GetBool() || !val.GetCustomRole().IsImpostor()) && (NeutralKnowCyberDead.GetBool() || !val.GetCustomRole().IsNeutral()) && (CrewKnowCyberDead.GetBool() || !val.GetCustomRole().IsCrewmate())) { if (inMeeting) { Utils.SendMessage(string.Format(Translator.GetString("CyberDead"), target.GetRealName()), val.PlayerId, Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cyber)), Translator.GetString("CyberNewsTitle"))); continue; } val.KillFlash(); val.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Cyber)), Translator.GetString("OnCyberDead"))); } } if (!inMeeting && !CyberDead.Contains(target.PlayerId)) { CyberDead.Add(target.PlayerId); } } } public static class Diseased { private const int Id = 21800; public static bool IsEnable; public static OptionItem ImpCanBeDiseased; public static OptionItem CrewCanBeDiseased; public static OptionItem NeutralCanBeDiseased; private static OptionItem DiseasedCDOpt; private static OptionItem DiseasedCDReset; private static Dictionary KilledDiseased; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21800, CustomRoles.Diseased, CustomGameMode.Standard, canSetNum: true); ImpCanBeDiseased = BooleanOptionItem.Create(21810, "ImpCanBeDiseased", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Diseased]); CrewCanBeDiseased = BooleanOptionItem.Create(21811, "CrewCanBeDiseased", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Diseased]); NeutralCanBeDiseased = BooleanOptionItem.Create(21812, "NeutralCanBeDiseased", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Diseased]); DiseasedCDOpt = FloatOptionItem.Create(21813, "DiseasedCDOpt", new FloatValueRule(0f, 180f, 1f), 25f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Diseased]).SetValueFormat(OptionFormat.Seconds); DiseasedCDReset = BooleanOptionItem.Create(21814, "DiseasedCDReset", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Diseased]); } public static void Init() { KilledDiseased = new Dictionary(); IsEnable = false; } public static void Add() { IsEnable = true; } public static void IncreaseKCD(PlayerControl player) { if (KilledDiseased.ContainsKey(player.PlayerId)) { Main.AllPlayerKillCooldown[player.PlayerId] = Main.AllPlayerKillCooldown[player.PlayerId] + (float)KilledDiseased[player.PlayerId] * DiseasedCDOpt.GetFloat(); Logger.Info($"kill cd of player set to {Main.AllPlayerKillCooldown[player.PlayerId]}", "Diseased", escapeCRLF: true, 44, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Diseased.cs"); } } public static void AfterMeetingTasks() { if (!DiseasedCDReset.GetBool()) { return; } foreach (byte key in KilledDiseased.Keys) { KilledDiseased[key] = 0; PlayerControl playerById = Utils.GetPlayerById(key); if (!((Object)(object)playerById == (Object)null)) { playerById.ResetKillCooldown(); } } KilledDiseased = new Dictionary(); } public static void CheckMurder(PlayerControl killer) { if (KilledDiseased.ContainsKey(killer.PlayerId)) { KilledDiseased[killer.PlayerId]++; } else { KilledDiseased.Add(killer.PlayerId, 1); } } } public static class DoubleShot { public static HashSet IsActive = new HashSet(); public static OptionItem ImpCanBeDoubleShot; public static OptionItem CrewCanBeDoubleShot; public static OptionItem NeutralCanBeDoubleShot; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(19200, CustomRoles.DoubleShot, CustomGameMode.Standard, canSetNum: true, TabGroup.ModifierSettings); ImpCanBeDoubleShot = BooleanOptionItem.Create(19203, "ImpCanBeDoubleShot", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DoubleShot]); CrewCanBeDoubleShot = BooleanOptionItem.Create(19204, "CrewCanBeDoubleShot", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DoubleShot]); NeutralCanBeDoubleShot = BooleanOptionItem.Create(19205, "NeutralCanBeDoubleShot", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.DoubleShot]); } public static void Init() { IsActive = new HashSet(); } } public static class Egoist { private const int Id = 23500; public static OptionItem CrewCanBeEgoist; public static OptionItem ImpCanBeEgoist; public static OptionItem ImpEgoistVisibalToAllies; public static OptionItem EgoistCountAsConverted; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(23500, CustomRoles.Egoist, CustomGameMode.Standard, canSetNum: true); CrewCanBeEgoist = BooleanOptionItem.Create(23510, "CrewCanBeEgoist", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Egoist]); ImpCanBeEgoist = BooleanOptionItem.Create(23511, "ImpCanBeEgoist", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Egoist]); ImpEgoistVisibalToAllies = BooleanOptionItem.Create(23512, "ImpEgoistVisibalToAllies", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Egoist]); EgoistCountAsConverted = BooleanOptionItem.Create(23513, "EgoistCountAsConverted", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Egoist]); } } public static class Flash { private const int Id = 26100; private static OptionItem OptionSpeed; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(26100, CustomRoles.Flash, CustomGameMode.Standard, canSetNum: true); OptionSpeed = FloatOptionItem.Create(26110, "FlashSpeed", new FloatValueRule(0.25f, 5f, 0.25f), 2.5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Flash]).SetValueFormat(OptionFormat.Multiplier); } public static void SetSpeed(byte playerId, bool clearAddOn) { if (!clearAddOn) { Main.AllPlayerSpeed[playerId] = OptionSpeed.GetFloat(); } else { Main.AllPlayerSpeed[playerId] = Main.RealOptionsData.GetFloat((FloatOptionNames)2); } } } public static class Fool { private const int Id = 25600; public static bool IsEnable; public static OptionItem ImpCanBeFool; public static OptionItem CrewCanBeFool; public static OptionItem NeutralCanBeFool; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(25600, CustomRoles.Fool, CustomGameMode.Standard, canSetNum: true); ImpCanBeFool = BooleanOptionItem.Create(25610, "ImpCanBeFool", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fool]); CrewCanBeFool = BooleanOptionItem.Create(25611, "CrewCanBeFool", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fool]); NeutralCanBeFool = BooleanOptionItem.Create(25612, "NeutralCanBeFool", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fool]); } public static void Init() { IsEnable = false; } public static void Add() { IsEnable = true; } public static bool BlockFixSabotage(PlayerControl player, SystemTypes systemType) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 if (!player.Is(CustomRoles.Fool)) { return false; } bool flag = !Main.MeetingIsStarted && (int)systemType != 17; bool flag2; if (flag) { if ((int)systemType <= 8) { if ((int)systemType == 3 || systemType - 7 <= 1) { goto IL_0044; } } else if ((int)systemType == 14 || (int)systemType == 21 || (int)systemType == 58) { goto IL_0044; } flag2 = false; goto IL_004a; } goto IL_004c; IL_0044: flag2 = true; goto IL_004a; IL_004a: flag = flag2; goto IL_004c; IL_004c: if (flag) { return true; } return false; } } public static class Fragile { private const int Id = 20600; public static OptionItem ImpCanBeFragile; public static OptionItem CrewCanBeFragile; public static OptionItem NeutralCanBeFragile; public static OptionItem ImpCanKillFragile; private static OptionItem CrewCanKillFragile; private static OptionItem NeutralCanKillFragile; private static OptionItem FragileKillerLunge; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20600, CustomRoles.Fragile, CustomGameMode.Standard, canSetNum: true); ImpCanBeFragile = BooleanOptionItem.Create(20610, "ImpCanBeFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); CrewCanBeFragile = BooleanOptionItem.Create(20611, "CrewCanBeFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); NeutralCanBeFragile = BooleanOptionItem.Create(20612, "NeutralCanBeFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); ImpCanKillFragile = BooleanOptionItem.Create(20613, "ImpCanKillFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); CrewCanKillFragile = BooleanOptionItem.Create(20614, "CrewCanKillFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); NeutralCanKillFragile = BooleanOptionItem.Create(20615, "NeutralCanKillFragile", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); FragileKillerLunge = BooleanOptionItem.Create(20616, "FragileKillerLunge", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fragile]); } public static bool KillFragile(PlayerControl killer, PlayerControl target) { if ((Object)(object)target == (Object)null || !target.IsAlive()) { return false; } CustomRoles customRole = killer.GetCustomRole(); if ((customRole.IsImpostorTeamV3() && ImpCanKillFragile.GetBool()) || (customRole.IsNeutral() && NeutralCanKillFragile.GetBool()) || (customRole.IsCrewmate() && CrewCanKillFragile.GetBool())) { target.SetDeathReason(PlayerState.DeathReason.Shattered); if (FragileKillerLunge.GetBool()) { killer.RpcMurderPlayer(target); } else { target.RpcMurderPlayer(target); } target.SetRealKiller(killer); killer.ResetKillCooldown(); return true; } return false; } } public static class Glow { private const int Id = 22000; public static bool IsEnable = false; public static OptionItem ImpCanBeGlow; public static OptionItem CrewCanBeGlow; public static OptionItem NeutralCanBeGlow; private static OptionItem GlowRadius; private static OptionItem GlowVisionOthers; private static OptionItem GlowVisionSelf; private static readonly Dictionary> InRadius = new Dictionary>(); private static readonly Dictionary MarkedOnce = new Dictionary(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(22000, CustomRoles.Glow, CustomGameMode.Standard, canSetNum: true); ImpCanBeGlow = BooleanOptionItem.Create(22010, "ImpCanBeGlow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]); CrewCanBeGlow = BooleanOptionItem.Create(22011, "CrewCanBeGlow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]); NeutralCanBeGlow = BooleanOptionItem.Create(22012, "NeutralCanBeGlow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]); GlowRadius = FloatOptionItem.Create(22013, "GlowRadius", new FloatValueRule(0.1f, 5f, 0.05f), 0.5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]).SetValueFormat(OptionFormat.Multiplier); GlowVisionOthers = FloatOptionItem.Create(22014, "GlowVisionOthers", new FloatValueRule(0.1f, 5f, 0.05f), 0.15f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]).SetValueFormat(OptionFormat.Multiplier); GlowVisionSelf = FloatOptionItem.Create(22015, "GlowVisionSelf", new FloatValueRule(0.1f, 5f, 0.05f), 0.15f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Glow]).SetValueFormat(OptionFormat.Multiplier); } public static void Init() { InRadius.Clear(); IsEnable = false; MarkedOnce.Clear(); } public static void Add(byte playerId) { MarkedOnce[playerId] = false; InRadius[playerId] = new HashSet(); IsEnable = true; } public static void Remove(byte playerId) { MarkedOnce.Remove(playerId); InRadius.Remove(playerId); } public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) { if (!InRadius.Any() || (Object)(object)player == (Object)null || !Utils.IsActive((SystemTypes)7)) { return; } if (!player.Is(CustomRoles.Glow)) { HashSet hashSet = new HashSet(); foreach (HashSet value in InRadius.Values) { hashSet.UnionWith(value); } if (!hashSet.Contains(player.PlayerId)) { return; } } opt.SetVision(HasImpVision: false); float @float = opt.GetFloat((FloatOptionNames)4); float float2 = opt.GetFloat((FloatOptionNames)3); @float += (player.Is(CustomRoles.Glow) ? GlowVisionSelf.GetFloat() : GlowVisionOthers.GetFloat()); float2 += (player.Is(CustomRoles.Glow) ? GlowVisionSelf.GetFloat() : GlowVisionOthers.GetFloat()); opt.SetFloat((FloatOptionNames)3, float2); opt.SetFloat((FloatOptionNames)4, @float); } public static void OnFixedUpdate(PlayerControl player) { if ((Object)(object)player == (Object)null || !player.Is(CustomRoles.Glow)) { return; } if (!Utils.IsActive((SystemTypes)7)) { InRadius[player.PlayerId].Clear(); MarkedOnce[player.PlayerId] = false; return; } if (!InRadius.ContainsKey(player.PlayerId)) { InRadius[player.PlayerId] = new HashSet(); } HashSet hashSet = InRadius[player.PlayerId]; if (!MarkedOnce.ContainsKey(player.PlayerId)) { MarkedOnce[player.PlayerId] = false; } InRadius[player.PlayerId] = (from target in Main.AllAlivePlayerControls where (Object)(object)target != (Object)null && !target.Is(CustomRoles.Glow) && Vector2.Distance(player.GetCustomPosition(), target.GetCustomPosition()) <= GlowRadius.GetFloat() select target.PlayerId).ToHashSet(); if (!MarkedOnce[player.PlayerId] || !hashSet.SetEquals(InRadius[player.PlayerId])) { MarkedOnce[player.PlayerId] = true; Utils.MarkEveryoneDirtySettings(); } } } public static class Gravestone { private const int Id = 22100; public static OptionItem ImpCanBeGravestone; public static OptionItem CrewCanBeGravestone; public static OptionItem NeutralCanBeGravestone; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(22100, CustomRoles.Gravestone, CustomGameMode.Standard, canSetNum: true); ImpCanBeGravestone = BooleanOptionItem.Create(22110, "ImpCanBeGravestone", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gravestone]); CrewCanBeGravestone = BooleanOptionItem.Create(22111, "CrewCanBeGravestone", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gravestone]); NeutralCanBeGravestone = BooleanOptionItem.Create(22112, "NeutralCanBeGravestone", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Gravestone]); } public static bool EveryoneKnowRole(PlayerControl player) { if (player.Is(CustomRoles.Gravestone)) { return !player.IsAlive(); } return false; } } public static class Guesser { private const int Id = 22200; public static OptionItem ImpCanBeGuesser; public static OptionItem CrewCanBeGuesser; public static OptionItem NeutralCanBeGuesser; public static OptionItem GCanGuessAdt; public static OptionItem GCanGuessTaskDoneSnitch; public static OptionItem GTryHideMsg; public static void SetupCustomOptions() { //IL_0116: Unknown result type (might be due to invalid IL or missing references) Options.SetupAdtRoleOptions(22200, CustomRoles.Guesser, CustomGameMode.Standard, canSetNum: true); ImpCanBeGuesser = BooleanOptionItem.Create(22210, "ImpCanBeGuesser", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]); CrewCanBeGuesser = BooleanOptionItem.Create(22211, "CrewCanBeGuesser", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]); NeutralCanBeGuesser = BooleanOptionItem.Create(22212, "NeutralCanBeGuesser", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]); GCanGuessAdt = BooleanOptionItem.Create(22213, "GCanGuessAdt", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]); GCanGuessTaskDoneSnitch = BooleanOptionItem.Create(22214, "GCanGuessTaskDoneSnitch", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]); GTryHideMsg = BooleanOptionItem.Create(22215, "GuesserTryHideMsg", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Guesser]).SetColor(Color.green); } } public static class Influenced { private const int Id = 21200; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(21200, CustomRoles.Influenced, CustomGameMode.Standard, canSetNum: true); CanBeOnImp = BooleanOptionItem.Create(21210, "ImpCanBeInfluenced", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Influenced]); CanBeOnCrew = BooleanOptionItem.Create(21211, "CrewCanBeInfluenced", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Influenced]); CanBeOnNeutral = BooleanOptionItem.Create(21212, "NeutralCanBeInfluenced", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Influenced]); } public static void ChangeVotingData(Dictionary VotingData) { HashSet playerIdList = new HashSet(); CollectionExtensions.Do(Main.AllAlivePlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Influenced)), (Action)delegate(PlayerControl x) { playerIdList.Add(x.PlayerId); }); if (playerIdList.Count == 0 || playerIdList.Count >= Main.AllAlivePlayerControls.Length) { return; } int num = 0; bool flag = false; byte b = byte.MaxValue; foreach (KeyValuePair VotingDatum in VotingData) { if (VotingDatum.Value > num) { b = VotingDatum.Key; num = VotingDatum.Value; flag = false; } else if (VotingDatum.Value == num) { b = byte.MaxValue; flag = true; } } if (flag) { return; } foreach (byte item in playerIdList) { PlayerVoteArea playerVoteArea = CheckForEndVotingPatch.GetPlayerVoteArea(item); if ((Object)(object)playerVoteArea != (Object)null && playerVoteArea.VotedFor != b) { playerVoteArea.VotedFor = b; CheckForEndVotingPatch.ReturnChangedPva(playerVoteArea); Logger.Info($"changed influenced {item} {playerVoteArea.TargetPlayerId} vote target to {b}", "InfluencedChangeVote", escapeCRLF: true, 59, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Influenced.cs"); } } } } public static class Loyal { private const int Id = 19400; public static OptionItem ImpCanBeLoyal; public static OptionItem CrewCanBeLoyal; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19400, CustomRoles.Loyal, CustomGameMode.Standard, canSetNum: true); ImpCanBeLoyal = BooleanOptionItem.Create(19410, "ImpCanBeLoyal", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Loyal]); CrewCanBeLoyal = BooleanOptionItem.Create(19411, "CrewCanBeLoyal", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Loyal]); } } public static class Lucky { private const int Id = 19500; private static OptionItem LuckyProbability; public static OptionItem ImpCanBeLucky; public static OptionItem CrewCanBeLucky; public static OptionItem NeutralCanBeLucky; private static Dictionary LuckyAvoid; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19500, CustomRoles.Lucky, CustomGameMode.Standard, canSetNum: true); LuckyProbability = IntegerOptionItem.Create(19510, "LuckyProbability", new IntegerValueRule(0, 100, 5), 50, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lucky]).SetValueFormat(OptionFormat.Percent); ImpCanBeLucky = BooleanOptionItem.Create(19511, "ImpCanBeLucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lucky]); CrewCanBeLucky = BooleanOptionItem.Create(19512, "CrewCanBeLucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lucky]); NeutralCanBeLucky = BooleanOptionItem.Create(19513, "NeutralCanBeLucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lucky]); } public static void Init() { LuckyAvoid = new Dictionary(); } public static void Add(byte PlayerId) { LuckyAvoid.Add(PlayerId, value: false); } public static void Remove(byte player) { LuckyAvoid.Remove(player); } private static void AvoidDeathChance(PlayerControl killer, PlayerControl target) { if (IRandom.Instance.Next(0, 101) < LuckyProbability.GetInt()) { killer.RpcGuardAndKill(target); LuckyAvoid[target.PlayerId] = true; } } public static bool OnCheckMurder(PlayerControl killer, PlayerControl target) { AvoidDeathChance(killer, target); if (LuckyAvoid[target.PlayerId]) { LuckyAvoid[target.PlayerId] = false; return false; } return true; } } public static class Mundane { private const int Id = 26700; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnNeutral; public static void SetupCustomOption() { Options.SetupAdtRoleOptions(26700, CustomRoles.Mundane, CustomGameMode.Standard, canSetNum: true); CanBeOnCrew = BooleanOptionItem.Create(26711, "CrewCanBeMundane", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mundane]); CanBeOnNeutral = BooleanOptionItem.Create(26712, "NeutralCanBeMundane", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mundane]); } public static bool OnGuess(PlayerControl pc) { if ((Object)(object)pc == (Object)null || !pc.Is(CustomRoles.Mundane)) { return true; } return pc.GetPlayerTaskState().IsTaskFinished; } } public static class Necroview { private const int Id = 19600; public static OptionItem ImpCanBeNecroview; public static OptionItem CrewCanBeNecroview; public static OptionItem NeutralCanBeNecroview; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19600, CustomRoles.Necroview, CustomGameMode.Standard, canSetNum: true); ImpCanBeNecroview = BooleanOptionItem.Create(19610, "ImpCanBeNecroview", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necroview]); CrewCanBeNecroview = BooleanOptionItem.Create(19611, "CrewCanBeNecroview", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necroview]); NeutralCanBeNecroview = BooleanOptionItem.Create(19612, "NeutralCanBeNecroview", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Necroview]); } public static string NameColorOptions(PlayerControl target) { CustomRoles customRole = target.GetCustomRole(); using (List.Enumerator enumerator = target.GetCustomSubRoles().GetEnumerator()) { while (enumerator.MoveNext()) { bool flag; switch (enumerator.Current) { case CustomRoles.Charmed: case CustomRoles.Contagious: case CustomRoles.Egoist: case CustomRoles.Infected: case CustomRoles.Recruit: case CustomRoles.Soulless: flag = true; break; default: flag = false; break; } if (flag) { return Main.roleColors[CustomRoles.Knight]; } } } if (customRole.IsImpostorTeamV2() || customRole.IsMadmate()) { return Main.roleColors[CustomRoles.Impostor]; } if (customRole.IsCrewmate()) { return Main.roleColors[CustomRoles.Bait]; } return Main.roleColors[CustomRoles.Knight]; } } public static class Oblivious { private const int Id = 20700; public static OptionItem ImpCanBeOblivious; public static OptionItem CrewCanBeOblivious; public static OptionItem NeutralCanBeOblivious; public static OptionItem ObliviousBaitImmune; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20700, CustomRoles.Oblivious, CustomGameMode.Standard, canSetNum: true); ImpCanBeOblivious = BooleanOptionItem.Create(20710, "ImpCanBeOblivious", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oblivious]); CrewCanBeOblivious = BooleanOptionItem.Create(20711, "CrewCanBeOblivious", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oblivious]); NeutralCanBeOblivious = BooleanOptionItem.Create(20712, "NeutralCanBeOblivious", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oblivious]); ObliviousBaitImmune = BooleanOptionItem.Create(20713, "ObliviousBaitImmune", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oblivious]); } } public static class Oiiai { private enum ChangeRolesSelectList { Role_NoChange, Role_Amnesiac, Role_Imitator } private const int Id = 25700; private static readonly List playerIdList = new List(); public static bool IsEnable = false; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; private static OptionItem CanPassOn; private static OptionItem ChangeNeutralRole; public static readonly CustomRoles[] NRoleChangeRoles = new CustomRoles[2] { CustomRoles.Amnesiac, CustomRoles.Imitator }; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(25700, CustomRoles.Oiiai, CustomGameMode.Standard, canSetNum: true); CanBeOnImp = BooleanOptionItem.Create(25711, "ImpCanBeOiiai", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oiiai]); CanBeOnCrew = BooleanOptionItem.Create(25712, "CrewCanBeOiiai", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oiiai]); CanBeOnNeutral = BooleanOptionItem.Create(25713, "NeutralCanBeOiiai", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oiiai]); CanPassOn = BooleanOptionItem.Create(25714, "OiiaiCanPassOn", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oiiai]); ChangeNeutralRole = StringOptionItem.Create(25715, "NeutralChangeRolesForOiiai", EnumHelper.GetAllNames(), 1, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Oiiai]); } public static void Init() { playerIdList.Clear(); Eraser.ErasedRoleStorage.Clear(); IsEnable = false; } public static void Add(byte playerId) { playerIdList.Add(playerId); IsEnable = true; } public static void OnMurderPlayer(PlayerControl killer, PlayerControl target) { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)killer == (Object)null || (Object)(object)target == (Object)null || killer.PlayerId == target.PlayerId || killer.Is(CustomRoles.KillingMachine) || !target.Is(CustomRoles.Oiiai) || !CanGetOiiaied(killer)) { return; } if (CanPassOn.GetBool() && !playerIdList.Contains(killer.PlayerId)) { Add(killer.PlayerId); killer.RpcSetCustomRole(CustomRoles.Oiiai); Logger.Info(killer.GetNameWithRole() + " gets Oiiai addon by " + target.GetNameWithRole(), "Oiiai", escapeCRLF: true, 67, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } if (!Eraser.ErasedRoleStorage.ContainsKey(killer.PlayerId)) { Eraser.ErasedRoleStorage.Add(killer.PlayerId, killer.GetCustomRole()); Logger.Info("Added " + killer.GetNameWithRole() + " to ErasedRoleStorage", "Oiiai", escapeCRLF: true, 73, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); CustomRoles customRole = killer.GetCustomRole(); if (customRole.IsTasklessCrewmate() || customRole.IsGhostRole() || Main.TasklessCrewmate.Contains(killer.PlayerId) || CopyCat.playerIdList.Contains(killer.PlayerId) || killer.Is(CustomRoles.Stubborn)) { Logger.Info("Oiiai " + killer.GetNameWithRole().RemoveHtmlTags() + " cannot eraser crew imp-based role", "Oiiai", escapeCRLF: true, 84, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); return; } if (!killer.GetCustomRole().IsNeutral()) { killer.RpcSetCustomRole(Eraser.GetErasedRole(killer.GetCustomRole().GetRoleTypes(), killer.GetCustomRole())); Logger.Info("Oiiai " + killer.GetNameWithRole().RemoveHtmlTags() + " with eraser assign.", "Oiiai", escapeCRLF: true, 91, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } else if (killer.HasImpKillButton()) { int value = ChangeNeutralRole.GetValue(); if (value != 0) { killer.RpcSetCustomRole(NRoleChangeRoles[value - 1]); killer.GetRoleClass().OnAdd(killer.PlayerId); Logger.Info("Oiiai " + killer.GetNameWithRole().RemoveHtmlTags() + " with Neutrals with kill button assign.", "Oiiai", escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } } else { killer.RpcSetCustomRole(CustomRoles.Opportunist); Logger.Info("Oiiai " + killer.GetNameWithRole().RemoveHtmlTags() + " with Neutrals without kill button assign.", "Oiiai", escapeCRLF: true, 110, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } killer.ResetKillCooldown(); killer.SetKillCooldown(); killer.Notify(Translator.GetString("LostRoleByOiiai")); killer.RPCPlayCustomSound("Oiiai"); Logger.Info(killer.GetRealName() + " was OIIAIed", "Oiiai", escapeCRLF: true, 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } else { Logger.Info("Canceled " + killer.GetNameWithRole() + " Oiiai bcz already erased.", "Oiiai", escapeCRLF: true, 77, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Oiiai.cs"); } } private static bool CanGetOiiaied(PlayerControl player) { if (player.GetCustomRole().IsNeutral() && ChangeNeutralRole.GetValue() == 0) { return false; } if (player.Is(CustomRoles.Loyal)) { return false; } return true; } } public static class Onbound { private const int Id = 25800; public static OptionItem ImpCanBeOnbound; public static OptionItem CrewCanBeOnbound; public static OptionItem NeutralCanBeOnbound; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(25800, CustomRoles.Onbound, CustomGameMode.Standard, canSetNum: true, TabGroup.ModifierSettings); ImpCanBeOnbound = BooleanOptionItem.Create(25810, "ImpCanBeOnbound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Onbound]); CrewCanBeOnbound = BooleanOptionItem.Create(25811, "CrewCanBeOnbound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Onbound]); NeutralCanBeOnbound = BooleanOptionItem.Create(25812, "NeutralCanBeOnbound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Onbound]); } } public static class Overclocked { private const int Id = 19800; public static OptionItem OverclockedReduction; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(19800, CustomRoles.Overclocked, CustomGameMode.Standard, canSetNum: true); OverclockedReduction = FloatOptionItem.Create(19810, "OverclockedReduction", new FloatValueRule(0f, 90f, 5f), 40f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Overclocked]).SetValueFormat(OptionFormat.Percent); } } public static class Paranoia { private const int Id = 22400; public static OptionItem CanBeImp; public static OptionItem CanBeCrew; public static OptionItem DualVotes; private static OptionItem HideAdditionalVotes; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(22400, CustomRoles.Paranoia, CustomGameMode.Standard, canSetNum: true); CanBeImp = BooleanOptionItem.Create(22410, "ImpCanBeParanoia", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Paranoia]); CanBeCrew = BooleanOptionItem.Create(22411, "CrewCanBeParanoia", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Paranoia]); DualVotes = BooleanOptionItem.Create(22412, "DualVotes", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Paranoia]); HideAdditionalVotes = BooleanOptionItem.Create(22413, "HideAdditionalVotes", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(DualVotes); } public static bool IsExistInGame(PlayerControl player) { return player.Is(CustomRoles.Paranoia); } public static void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!HideAdditionalVotes.GetBool()) { statesList.Add(new VoterState { VoterId = votedPlayer.TargetPlayerId, VotedForId = votedPlayer.VotedFor }); } } } public static class Radar { private const int Id = 28200; public static bool IsEnable = false; public static OptionItem ImpCanBeRadar; public static OptionItem CrewCanBeRadar; public static OptionItem NeutralCanBeRadar; private static Dictionary ClosestPlayer = new Dictionary(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(28200, CustomRoles.Radar, CustomGameMode.Standard, canSetNum: true); ImpCanBeRadar = BooleanOptionItem.Create(28210, "ImpCanBeRadar", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Radar]); CrewCanBeRadar = BooleanOptionItem.Create(28211, "CrewCanBeRadar", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Radar]); NeutralCanBeRadar = BooleanOptionItem.Create(28212, "NeutralCanBeRadar", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Radar]); } public static void Init() { ClosestPlayer.Clear(); IsEnable = false; } public static void Add(byte playerId) { ClosestPlayer[playerId] = byte.MaxValue; IsEnable = true; } public static void Remove(byte playerId) { ClosestPlayer.Remove(playerId); } private static void SendRPC(byte playerId, byte previousClosest) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)186, (SendOption)1, -1); val.Write(playerId); val.Write(previousClosest); val.Write(ClosestPlayer[playerId]); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } public static void ReceiveRPC(MessageReader reader) { byte b = reader.ReadByte(); byte target = reader.ReadByte(); TargetArrow.Remove(b, target); byte b2 = reader.ReadByte(); TargetArrow.Add(b, b2); ClosestPlayer[b] = b2; } public static void OnFixedUpdate(PlayerControl radarPC) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)radarPC == (Object)null || !radarPC.Is(CustomRoles.Radar) || !GameStates.IsInTask || Main.AllAlivePlayerControls.Length <= 1) { return; } if (!ClosestPlayer.ContainsKey(radarPC.PlayerId)) { ClosestPlayer[radarPC.PlayerId] = byte.MaxValue; } byte b = ClosestPlayer[radarPC.PlayerId]; byte b2 = byte.MaxValue; float num = float.PositiveInfinity; PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (!((Object)(object)val == (Object)(object)radarPC)) { float num2 = Vector2.Distance(radarPC.GetCustomPosition(), val.GetCustomPosition()); if (num2 < num) { num = num2; b2 = val.PlayerId; } } } if (b2 != b) { TargetArrow.Remove(radarPC.PlayerId, b); if (b2 != byte.MaxValue) { ClosestPlayer[radarPC.PlayerId] = b2; TargetArrow.Add(radarPC.PlayerId, b2); SendRPC(radarPC.PlayerId, b); Logger.Info($"Radar: {radarPC.PlayerId} Target: {b2}", "Radar Target", escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Radar.cs"); } } } public static string GetPlayerArrow(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (isForMeeting || (Object)(object)seer == (Object)null) { return string.Empty; } if (!seer.Is(CustomRoles.Radar) || !ClosestPlayer.ContainsKey(seer.PlayerId)) { return string.Empty; } if ((Object)(object)target != (Object)null && seer.PlayerId != target.PlayerId) { return string.Empty; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Radar)), TargetArrow.GetArrows(seer, ClosestPlayer[seer.PlayerId])); } } public static class Rainbow { private const int Id = 27700; public static OptionItem CrewCanBeRainbow; public static OptionItem ImpCanBeRainbow; public static OptionItem NeutralCanBeRainbow; private static OptionItem RainbowColorChangeCoolDown; private static OptionItem ChangeInCamouflage; public static bool isEnabled; public static long LastColorChange; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(27700, CustomRoles.Rainbow, CustomGameMode.Standard, canSetNum: true); CrewCanBeRainbow = BooleanOptionItem.Create(27710, "CrewCanBeRainbow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rainbow]); ImpCanBeRainbow = BooleanOptionItem.Create(27711, "ImpCanBeRainbow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rainbow]); NeutralCanBeRainbow = BooleanOptionItem.Create(27712, "NeutralCanBeRainbow", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rainbow]); RainbowColorChangeCoolDown = IntegerOptionItem.Create(27713, "RainbowColorChangeCoolDown", new IntegerValueRule(1, 100, 1), 3, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rainbow]); ChangeInCamouflage = BooleanOptionItem.Create(27714, "RainbowInCamouflage", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rainbow]); } public static void Init() { LastColorChange = Utils.GetTimeStamp(); isEnabled = false; } public static void Add() { isEnabled = true; } public static void OnFixedUpdate() { if ((!Camouflage.IsCamouflage || ChangeInCamouflage.GetBool()) && LastColorChange + RainbowColorChangeCoolDown.GetInt() <= Utils.GetTimeStamp()) { LastColorChange = Utils.GetTimeStamp(); ChangeAllColor(); } } private static void ChangeAllColor() { CustomRpcSender customRpcSender = CustomRpcSender.Create("Rainbow Sender", (SendOption)0); foreach (PlayerControl item in Main.AllPlayerControls.Where((PlayerControl x) => x.Is(CustomRoles.Rainbow) && x.IsAlive() && !x.inMovingPlat && !x.inVent && !x.walkingToVent && !x.onLadder)) { int num = PickRandomColor(); item.SetColor(num); customRpcSender.AutoStartRpc(((InnerNetObject)item).NetId, 8).Write(((InnerNetObject)item.Data).NetId).Write((byte)num) .EndRpc(); } customRpcSender.SendMessage(); } private static int PickRandomColor() { return IRandom.Instance.Next(0, 18); } } public class Reach { private const int Id = 23700; public static CustomRoles IsReach = CustomRoles.Reach; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(23700, CustomRoles.Reach, CustomGameMode.Standard, canSetNum: true); } public static void ApplyGameOptions(IGameOptions opt) { opt.SetInt((Int32OptionNames)2, 2); } } public static class Rebound { private const int Id = 22300; public static OptionItem ImpCanBeRebound; public static OptionItem CrewCanBeRebound; public static OptionItem NeutralCanBeRebound; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(22300, CustomRoles.Rebound, CustomGameMode.Standard, canSetNum: true, TabGroup.ModifierSettings); ImpCanBeRebound = BooleanOptionItem.Create(22310, "ImpCanBeRebound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rebound]); CrewCanBeRebound = BooleanOptionItem.Create(22311, "CrewCanBeRebound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rebound]); NeutralCanBeRebound = BooleanOptionItem.Create(22312, "NeutralCanBeRebound", defaultValue: true, TabGroup.ModifierSettings, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Rebound]); } } public static class Seer { private const int Id = 20000; public static OptionItem ImpCanBeSeer; public static OptionItem CrewCanBeSeer; public static OptionItem NeutralCanBeSeer; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20000, CustomRoles.Seer, CustomGameMode.Standard, canSetNum: true); ImpCanBeSeer = BooleanOptionItem.Create(20010, "ImpCanBeSeer", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Seer]); CrewCanBeSeer = BooleanOptionItem.Create(20011, "CrewCanBeSeer", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Seer]); NeutralCanBeSeer = BooleanOptionItem.Create(20012, "NeutralCanBeSeer", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Seer]); } } public static class Silent { private const int Id = 26600; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(26600, CustomRoles.Silent, CustomGameMode.Standard, canSetNum: true); CanBeOnImp = BooleanOptionItem.Create(26611, "ImpCanBeSilent", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Silent]); CanBeOnCrew = BooleanOptionItem.Create(26612, "CrewCanBeSilent", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Silent]); CanBeOnNeutral = BooleanOptionItem.Create(26613, "NeutralCanBeSilent", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Silent]); } } public static class Sleuth { private const int Id = 20100; public static OptionItem ImpCanBeSleuth; public static OptionItem CrewCanBeSleuth; public static OptionItem NeutralCanBeSleuth; public static OptionItem SleuthCanKnowKillerRole; public static Dictionary SleuthNotify = new Dictionary(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20100, CustomRoles.Sleuth, CustomGameMode.Standard, canSetNum: true); ImpCanBeSleuth = BooleanOptionItem.Create(20110, "ImpCanBeSleuth", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sleuth]); CrewCanBeSleuth = BooleanOptionItem.Create(20111, "CrewCanBeSleuth", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sleuth]); NeutralCanBeSleuth = BooleanOptionItem.Create(20112, "NeutralCanBeSleuth", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sleuth]); SleuthCanKnowKillerRole = BooleanOptionItem.Create(20113, "SleuthCanKnowKillerRole", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Sleuth]); } public static void Init() { SleuthNotify = new Dictionary(); } public static void Clear() { SleuthNotify.Clear(); } public static void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo deadBody) { if (reporter.Is(CustomRoles.Sleuth) && (Object)(object)deadBody != (Object)null && (Object)(object)deadBody.Object != (Object)null && !deadBody.Object.IsAlive() && reporter.PlayerId != deadBody.PlayerId) { string text = string.Format(Translator.GetString("SleuthNoticeVictim"), deadBody.Object.GetRealName(), deadBody.Object.GetDisplayRoleAndSubName(deadBody.Object)); if (SleuthCanKnowKillerRole.GetBool()) { PlayerControl realKiller = deadBody.Object.GetRealKiller(); text = ((!((Object)(object)realKiller == (Object)null)) ? (text + ";" + string.Format(Translator.GetString("SleuthNoticeKiller"), realKiller.GetDisplayRoleAndSubName(realKiller))) : (text + ";" + Translator.GetString("SleuthNoticeKillerNotFound"))); } SleuthNotify.Add(reporter.PlayerId, text); } } } public static class Statue { private const int Id = 13800; public static bool IsEnable; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; private static OptionItem SlowDown; private static OptionItem PeopleAmount; private static bool Active; private static HashSet CountNearplr; private static Dictionary tempSpeed; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(13800, CustomRoles.Statue, CustomGameMode.Standard, canSetNum: true); SlowDown = FloatOptionItem.Create(13810, "StatueSlow", new FloatValueRule(0f, 1.25f, 0.25f), 0f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Statue]).SetValueFormat(OptionFormat.Multiplier); PeopleAmount = IntegerOptionItem.Create(13811, "StatuePeopleToSlow", new IntegerValueRule(1, 5, 1), 3, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Statue]).SetValueFormat(OptionFormat.Times); CanBeOnImp = BooleanOptionItem.Create(13812, "ImpCanBeStatue", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Statue]); CanBeOnCrew = BooleanOptionItem.Create(13813, "CrewCanBeStatue", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Statue]); CanBeOnNeutral = BooleanOptionItem.Create(13814, "NeutralCanBeStatue", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Statue]); } public static void Init() { CountNearplr = new HashSet(); tempSpeed = new Dictionary(); Active = true; IsEnable = false; } public static void Add(byte player) { tempSpeed.Add(player, Main.AllPlayerSpeed[player]); IsEnable = true; } public static void Remove(byte player) { tempSpeed.Remove(player); } public static void AfterMeetingTasks() { foreach (byte key in tempSpeed.Keys) { PlayerControl playerById = Utils.GetPlayerById(key); if (!((Object)(object)playerById == (Object)null)) { float num = tempSpeed[key]; Main.AllPlayerSpeed[key] = Main.AllPlayerSpeed[key] - Main.AllPlayerSpeed[key] + num; playerById.MarkDirtySettings(); } } Active = false; CountNearplr = new HashSet(); new LateTask(delegate { Active = true; }, 6f); } public static void OnFixedUpdate(PlayerControl victim) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) PlayerControl[] allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val in allAlivePlayerControls) { if (CountNearplr.Contains(val.PlayerId) && Vector2.Distance(Vector2.op_Implicit(((Component)val).transform.position), Vector2.op_Implicit(((Component)victim).transform.position)) > 2f) { CountNearplr.Remove(val.PlayerId); } } if (!Active) { return; } allAlivePlayerControls = Main.AllAlivePlayerControls; foreach (PlayerControl val2 in allAlivePlayerControls) { if (Vector2.Distance(Vector2.op_Implicit(((Component)val2).transform.position), Vector2.op_Implicit(((Component)victim).transform.position)) < 2f && (Object)(object)val2 != (Object)(object)victim && !CountNearplr.Contains(val2.PlayerId)) { CountNearplr.Add(val2.PlayerId); } } if (CountNearplr.Count >= PeopleAmount.GetInt()) { if (Main.AllPlayerSpeed[victim.PlayerId] != SlowDown.GetFloat()) { Main.AllPlayerSpeed[victim.PlayerId] = SlowDown.GetFloat(); victim.MarkDirtySettings(); } } else if (Main.AllPlayerSpeed[victim.PlayerId] == SlowDown.GetFloat()) { float num = tempSpeed[victim.PlayerId]; Main.AllPlayerSpeed[victim.PlayerId] = Main.AllPlayerSpeed[victim.PlayerId] - SlowDown.GetFloat() + num; victim.MarkDirtySettings(); } } } public static class Stubborn { private const int Id = 22500; public static OptionItem ImpCanBeStubborn; public static OptionItem CrewCanBeStubborn; public static OptionItem NeutralCanBeStubborn; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(22500, CustomRoles.Stubborn, CustomGameMode.Standard, canSetNum: true); ImpCanBeStubborn = BooleanOptionItem.Create(22510, "ImpCanBeStubborn", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stubborn]); CrewCanBeStubborn = BooleanOptionItem.Create(22511, "CrewCanBeStubborn", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stubborn]); NeutralCanBeStubborn = BooleanOptionItem.Create(22512, "NeutralCanBeStubborn", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Stubborn]); } } public class Susceptible { private const int Id = 27100; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; private static OptionItem EnabledDeathReasons; public static PlayerState.DeathReason randomReason; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(27100, CustomRoles.Susceptible, CustomGameMode.Standard, canSetNum: true); EnabledDeathReasons = BooleanOptionItem.Create(27111, "OnlyEnabledDeathReasons", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Susceptible]); CanBeOnImp = BooleanOptionItem.Create(27112, "ImpCanBeSusceptible", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Susceptible]); CanBeOnCrew = BooleanOptionItem.Create(27113, "CrewCanBeSusceptible", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Susceptible]); CanBeOnNeutral = BooleanOptionItem.Create(27114, "NeutralCanBeSusceptible", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Susceptible]); } private static void ChangeRandomDeath() { PlayerState.DeathReason[] allValues = EnumHelper.GetAllValues(); int num = new Random().Next(allValues.Length); randomReason = allValues[num]; } public static void CallEnabledAndChange(PlayerControl victim) { ChangeRandomDeath(); if (EnabledDeathReasons.GetBool()) { Logger.Info($"{victim.GetNameWithRole().RemoveHtmlTags()} had the death reason {randomReason}", "Susceptible", escapeCRLF: true, 37, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\AddOns\\Common\\Susceptible.cs"); Main.PlayerStates[victim.PlayerId].deathReason = (randomReason.DeathReasonIsEnable() ? randomReason : Main.PlayerStates[victim.PlayerId].deathReason); } else { Main.PlayerStates[victim.PlayerId].deathReason = (randomReason.DeathReasonIsEnable(checkbanned: true) ? randomReason : Main.PlayerStates[victim.PlayerId].deathReason); } } } public static class Tiebreaker { private const int Id = 20200; public static OptionItem ImpCanBeTiebreaker; public static OptionItem CrewCanBeTiebreaker; public static OptionItem NeutralCanBeTiebreaker; public static List VoteFor = new List(); public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20200, CustomRoles.Tiebreaker, CustomGameMode.Standard, canSetNum: true); ImpCanBeTiebreaker = BooleanOptionItem.Create(20210, "ImpCanBeTiebreaker", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tiebreaker]); CrewCanBeTiebreaker = BooleanOptionItem.Create(20211, "CrewCanBeTiebreaker", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tiebreaker]); NeutralCanBeTiebreaker = BooleanOptionItem.Create(20212, "NeutralCanBeTiebreaker", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tiebreaker]); } public static void Clear() { VoteFor = new List(); } public static void CheckVote(PlayerControl target, PlayerVoteArea ps) { if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Tiebreaker) && !VoteFor.Contains(target.PlayerId)) { VoteFor.Add(target.PlayerId); } } } public class Tired { private const int Id = 27300; private static Dictionary playerIdList; public static OptionItem CanBeOnCrew; public static OptionItem CanBeOnImp; public static OptionItem CanBeOnNeutral; private static OptionItem SetVision; private static OptionItem SetSpeed; private static OptionItem TiredDuration; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(27300, CustomRoles.Tired, CustomGameMode.Standard, canSetNum: true); SetVision = FloatOptionItem.Create(27310, "TiredVision", new FloatValueRule(0f, 2f, 0.25f), 0.25f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]).SetValueFormat(OptionFormat.Multiplier); SetSpeed = FloatOptionItem.Create(27311, "TiredSpeed", new FloatValueRule(0.25f, 3f, 0.25f), 0.75f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]).SetValueFormat(OptionFormat.Multiplier); TiredDuration = FloatOptionItem.Create(27312, "TiredDur", new FloatValueRule(2f, 15f, 0.5f), 5f, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]).SetValueFormat(OptionFormat.Seconds); CanBeOnImp = BooleanOptionItem.Create(27313, "ImpCanBeTired", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]); CanBeOnCrew = BooleanOptionItem.Create(27314, "CrewCanBeTired", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]); CanBeOnNeutral = BooleanOptionItem.Create(27315, "NeutralCanBeTired", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Tired]); } public static void Init() { playerIdList = new Dictionary(); } public static void Add(byte playerId) { playerIdList.Add(playerId, value: false); } public static void Remove(byte player) { playerIdList.Remove(player); } public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) { if (playerIdList.ContainsKey(player.PlayerId)) { if (playerIdList[player.PlayerId]) { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, SetVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, SetVision.GetFloat()); } else { opt.SetVision(HasImpVision: false); opt.SetFloat((FloatOptionNames)4, Main.DefaultCrewmateVision); opt.SetFloat((FloatOptionNames)3, Main.DefaultImpostorVision); } } } public static void AfterActionTasks(PlayerControl player) { player.Notify(Translator.GetString("TiredNotify")); player.MarkDirtySettings(); float tmpSpeed = Main.AllPlayerSpeed[player.PlayerId]; Main.AllPlayerSpeed[player.PlayerId] = SetSpeed.GetFloat(); playerIdList[player.PlayerId] = true; new LateTask(delegate { Main.AllPlayerSpeed[player.PlayerId] = Main.AllPlayerSpeed[player.PlayerId] - SetSpeed.GetFloat() + tmpSpeed; player.MarkDirtySettings(); playerIdList[player.PlayerId] = false; }, TiredDuration.GetFloat()); } } public static class Unlucky { public enum StateSuicide { TryKill, CompleteTask, EnterVent, ReportDeadBody, OpenDoor } private const int Id = 21000; private static OptionItem UnluckyTaskSuicideChance; private static OptionItem UnluckyKillSuicideChance; private static OptionItem UnluckyVentSuicideChance; private static OptionItem UnluckyReportSuicideChance; private static OptionItem UnluckyOpenDoorSuicideChance; public static OptionItem ImpCanBeUnlucky; public static OptionItem CrewCanBeUnlucky; public static OptionItem NeutralCanBeUnlucky; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21000, CustomRoles.Unlucky, CustomGameMode.Standard, canSetNum: true); UnluckyKillSuicideChance = IntegerOptionItem.Create(21010, "UnluckyKillSuicideChance", new IntegerValueRule(0, 100, 1), 2, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]).SetValueFormat(OptionFormat.Percent); UnluckyTaskSuicideChance = IntegerOptionItem.Create(21011, "UnluckyTaskSuicideChance", new IntegerValueRule(0, 100, 1), 5, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]).SetValueFormat(OptionFormat.Percent); UnluckyVentSuicideChance = IntegerOptionItem.Create(21012, "UnluckyVentSuicideChance", new IntegerValueRule(0, 100, 1), 3, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]).SetValueFormat(OptionFormat.Percent); UnluckyReportSuicideChance = IntegerOptionItem.Create(21013, "UnluckyReportSuicideChance", new IntegerValueRule(0, 100, 1), 1, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]).SetValueFormat(OptionFormat.Percent); UnluckyOpenDoorSuicideChance = IntegerOptionItem.Create(21014, "UnluckyOpenDoorSuicideChance", new IntegerValueRule(0, 100, 1), 4, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]).SetValueFormat(OptionFormat.Percent); ImpCanBeUnlucky = BooleanOptionItem.Create(21015, "ImpCanBeUnlucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]); CrewCanBeUnlucky = BooleanOptionItem.Create(21016, "CrewCanBeUnlucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]); NeutralCanBeUnlucky = BooleanOptionItem.Create(21017, "NeutralCanBeUnlucky", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unlucky]); } public static bool SuicideRand(PlayerControl victim, StateSuicide state) { int num = IRandom.Instance.Next(1, 100); if (num <= state switch { StateSuicide.TryKill => UnluckyKillSuicideChance.GetInt(), StateSuicide.CompleteTask => UnluckyTaskSuicideChance.GetInt(), StateSuicide.EnterVent => UnluckyVentSuicideChance.GetInt(), StateSuicide.ReportDeadBody => UnluckyReportSuicideChance.GetInt(), StateSuicide.OpenDoor => UnluckyOpenDoorSuicideChance.GetInt(), _ => -1, }) { victim.SetDeathReason(PlayerState.DeathReason.Suicide); victim.RpcMurderPlayer(victim); return true; } return false; } } public static class Unreportable { private const int Id = 20500; public static OptionItem ImpCanBeUnreportable; public static OptionItem CrewCanBeUnreportable; public static OptionItem NeutralCanBeUnreportable; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20500, CustomRoles.Unreportable, CustomGameMode.Standard, canSetNum: true); ImpCanBeUnreportable = BooleanOptionItem.Create(20510, "ImpCanBeUnreportable", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unreportable]); CrewCanBeUnreportable = BooleanOptionItem.Create(20511, "CrewCanBeUnreportable", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unreportable]); NeutralCanBeUnreportable = BooleanOptionItem.Create(20512, "NeutralCanBeUnreportable", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Unreportable]); } } public static class VoidBallot { private const int Id = 21100; public static OptionItem ImpCanBeVoidBallot; public static OptionItem CrewCanBeVoidBallot; public static OptionItem NeutralCanBeVoidBallot; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(21100, CustomRoles.VoidBallot, CustomGameMode.Standard, canSetNum: true); ImpCanBeVoidBallot = BooleanOptionItem.Create(21110, "ImpCanBeVoidBallot", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.VoidBallot]); CrewCanBeVoidBallot = BooleanOptionItem.Create(21111, "CrewCanBeVoidBallot", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.VoidBallot]); NeutralCanBeVoidBallot = BooleanOptionItem.Create(21112, "NeutralCanBeVoidBallot", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.VoidBallot]); } } public static class Watcher { private const int Id = 20400; public static OptionItem ImpCanBeWatcher; public static OptionItem CrewCanBeWatcher; public static OptionItem NeutralCanBeWatcher; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(20400, CustomRoles.Watcher, CustomGameMode.Standard, canSetNum: true); ImpCanBeWatcher = BooleanOptionItem.Create(20410, "ImpCanBeWatcher", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Watcher]); CrewCanBeWatcher = BooleanOptionItem.Create(20411, "CrewCanBeWatcher", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Watcher]); NeutralCanBeWatcher = BooleanOptionItem.Create(20412, "NeutralCanBeWatcher", defaultValue: true, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Watcher]); } public static void RevealVotes(IGameOptions opt) { opt.SetBool((BoolOptionNames)4, false); } } public static class Youtuber { private const int Id = 25500; public static OptionItem KillerWinsWithYouTuber; public static void SetupCustomOptions() { Options.SetupAdtRoleOptions(25500, CustomRoles.Youtuber, CustomGameMode.Standard, canSetNum: true); KillerWinsWithYouTuber = BooleanOptionItem.Create(25510, "Youtuber_KillerWinsWithYouTuber", defaultValue: false, TabGroup.Addons, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Youtuber]); } public static void OnMurderPlayer(PlayerControl killer, PlayerControl target) { target.SetDeathReason(PlayerState.DeathReason.Kill); target.SetRealKiller(killer, NotOverRide: true); Main.PlayerStates[target.PlayerId].SetDead(); CustomSoundsManager.RPCPlayCustomSoundAll("Congrats"); CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Youtuber); CustomWinnerHolder.WinnerIds.Add(target.PlayerId); } } } namespace TOHE.Roles._Ghosts_.Impostor { internal class Bloodmoon : RoleBase { private const int Id = 28100; public static OptionItem KillCooldown; public static OptionItem CanKillNum; private static OptionItem TimeTilDeath; public static readonly Dictionary PlayerDie = new Dictionary(); public static readonly Dictionary LastTime = new Dictionary(); public static bool HasEnabled => CustomRoles.Bloodmoon.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorGhosts; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(28100, TabGroup.ImpostorRoles, CustomRoles.Bloodmoon); KillCooldown = FloatOptionItem.Create(28110, GeneralOption.KillCooldown, new FloatValueRule(2.5f, 120f, 2.5f), 25f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bloodmoon]).SetValueFormat(OptionFormat.Seconds); CanKillNum = IntegerOptionItem.Create(28111, "BloodMoonCanKillNum", new IntegerValueRule(1, 15, 1), 3, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bloodmoon]).SetValueFormat(OptionFormat.Players); TimeTilDeath = IntegerOptionItem.Create(28112, "BloodMoonTimeTilDie", new IntegerValueRule(1, 120, 1), 60, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bloodmoon]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { PlayerDie.Clear(); LastTime.Clear(); } public override void Add(byte PlayerId) { base.AbilityLimit = CanKillNum.GetInt(); CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOther); } public override bool CanUseSabotage(PlayerControl pc) { return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = KillCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = 0f; } public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("CantBlood"))); return true; } if (base.AbilityLimit > 0f && !target.Is(CustomRoles.Jinx) && !target.Is(CustomRoles.CursedWolf) && !target.Is(CustomRoles.Pestilence) && killer.RpcCheckAndMurder(target, check: true) && !PlayerDie.ContainsKey(target.PlayerId)) { PlayerDie.Add(target.PlayerId, TimeTilDeath.GetInt()); LastTime.Add(target.PlayerId, Utils.GetTimeStamp()); killer.RpcResetAbilityCooldown(); base.AbilityLimit--; SendSkillRPC(); } return false; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Bloodmoon).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } private void OnFixedUpdateOther(PlayerControl player) { bool isMeeting = GameStates.IsMeeting; byte playerId = player.PlayerId; if (LastTime.TryGetValue(playerId, out var value) && value + 1 <= Utils.GetTimeStamp() && !isMeeting) { LastTime[playerId] = Utils.GetTimeStamp(); PlayerDie[playerId]--; if (PlayerDie[playerId] <= 0) { PlayerDie.Remove(playerId); LastTime.Remove(playerId); player.SetDeathReason(PlayerState.DeathReason.BloodLet); player.RpcMurderPlayer(player); player.SetRealKiller(base._Player); } } } public override void OnOtherTargetsReducedToAtoms(PlayerControl DeadPlayer) { if (LastTime.ContainsKey(DeadPlayer.PlayerId)) { LastTime.Remove(DeadPlayer.PlayerId); } if (PlayerDie.ContainsKey(DeadPlayer.PlayerId)) { PlayerDie.Remove(DeadPlayer.PlayerId); } } public override string GetLowerTextOthers(PlayerControl seer, PlayerControl player = null, bool isForMeeting = false, bool isForHud = false) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsMeeting || isForMeeting) { return string.Empty; } byte playerId = player.PlayerId; if (!PlayerDie.TryGetValue(playerId, out var value)) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Bloodmoon)), Translator.GetString("DeathTimer").Replace("{DeathTimer}", value.ToString())); } } internal class Minion : RoleBase { private const int Id = 27900; private static readonly HashSet Playerids = new HashSet(); public static OptionItem AbilityCooldown; public static OptionItem AbilityTime; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorGhosts; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(27900, TabGroup.ImpostorRoles, CustomRoles.Minion); AbilityCooldown = FloatOptionItem.Create(27910, GeneralOption.AbilityCooldown, new FloatValueRule(2.5f, 120f, 2.5f), 40f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Minion]).SetValueFormat(OptionFormat.Seconds); AbilityTime = FloatOptionItem.Create(27911, "MinionAbilityTime", new FloatValueRule(1f, 10f, 1f), 5f, TabGroup.ImpostorRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Minion]).SetValueFormat(OptionFormat.Seconds); } public override void Init() { Playerids.Clear(); } public override void Add(byte playerId) { Playerids.Add(playerId); } public override bool CanUseSabotage(PlayerControl pc) { return false; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = AbilityCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = 0f; } public override string GetLowerTextOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false, bool isForHud = false) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (seer.GetCustomRole().IsImpostorTeam() && Main.PlayerStates[target.PlayerId].IsBlackOut && !isForMeeting) { string @string = Translator.GetString("Minion_Blind"); return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Minion)), "『" + @string + "』"); } return string.Empty; } public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { if (!target.GetCustomRole().IsImpostor() || killer.IsAnySubRole((CustomRoles x) => x.IsConverted() && !killer.Is(CustomRoles.Madmate))) { Main.PlayerStates[target.PlayerId].IsBlackOut = true; target.MarkDirtySettings(); new LateTask(delegate { Main.PlayerStates[target.PlayerId].IsBlackOut = false; target.MarkDirtySettings(); }, AbilityTime.GetFloat(), "Minion: return vision"); killer.RpcResetAbilityCooldown(); } return false; } } } namespace TOHE.Roles._Ghosts_.Crewmate { internal class Ghastly : RoleBase { private const int Id = 22060; private static OptionItem PossessCooldown; private static OptionItem MaxPossesions; private static OptionItem PossessDur; private static OptionItem GhastlySpeed; private static OptionItem GhastlyKillAllies; private (byte, byte) killertarget = (byte.MaxValue, byte.MaxValue); private readonly Dictionary LastTime = new Dictionary(); private bool KillerIsChosen; public static bool HasEnabled => CustomRoles.Ghastly.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateGhosts; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(22060, TabGroup.CrewmateRoles, CustomRoles.Ghastly); PossessCooldown = FloatOptionItem.Create(22070, "GhastlyPossessCD", new FloatValueRule(2.5f, 120f, 2.5f), 35f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ghastly]).SetValueFormat(OptionFormat.Seconds); MaxPossesions = IntegerOptionItem.Create(22071, "GhastlyMaxPossessions", new IntegerValueRule(1, 99, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ghastly]).SetValueFormat(OptionFormat.Players); PossessDur = IntegerOptionItem.Create(22072, "GhastlyPossessionDuration", new IntegerValueRule(5, 120, 5), 40, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ghastly]).SetValueFormat(OptionFormat.Seconds); GhastlySpeed = FloatOptionItem.Create(22073, "GhastlySpeed", new FloatValueRule(1.5f, 5f, 0.5f), 2f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ghastly]).SetValueFormat(OptionFormat.Multiplier); GhastlyKillAllies = BooleanOptionItem.Create(22074, "GhastlyKillAllies", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ghastly]); } public override void Add(byte playerId) { base.AbilityLimit = MaxPossesions.GetInt(); CustomRoleManager.OnFixedUpdateOthers.Add(OnFixUpdateOthers); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = PossessCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = 0f; } public override bool OnCheckProtect(PlayerControl angel, PlayerControl target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { angel.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Gangster)), Translator.GetString("CantPosses"))); return true; } if (base.AbilityLimit <= 0f) { angel.Notify(Translator.GetString("GhastlyNoMorePossess")); return false; } byte b = killertarget.Item1; byte b2 = killertarget.Item2; if (!KillerIsChosen && !CheckConflicts(target)) { angel.Notify(Translator.GetString("GhastlyCannotPossessTarget")); return false; } if (!KillerIsChosen && target.PlayerId != b) { TargetArrow.Remove(b, b2); LastTime.Remove(b); b = target.PlayerId; b2 = byte.MaxValue; KillerIsChosen = true; angel.Notify("\n" + Translator.GetString("GhastlyChooseTarget") + "\n"); } else if (KillerIsChosen && b2 == byte.MaxValue && target.PlayerId != b) { b2 = target.PlayerId; base.AbilityLimit--; SendSkillRPC(); LastTime.Add(b, Utils.GetTimeStamp()); KillerIsChosen = false; Utils.GetPlayerById(b)?.Notify(Translator.GetString("GhastlyYouvePosses")); angel.Notify("\n〘" + string.Format(Translator.GetString("GhastlyPossessedUser"), "" + Utils.GetPlayerById(b).GetRealName()) + " 〙\n"); TargetArrow.Add(b, b2); angel.RpcGuardAndKill(target); angel.RpcResetAbilityCooldown(); Logger.Info(" chosen " + target.GetRealName() + " for : " + Utils.GetPlayerById(b).GetRealName(), "GhastlyTarget", escapeCRLF: true, 103, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\(Ghosts)\\Crewmate\\Ghastly.cs"); } else if (target.PlayerId == b) { angel.Notify(Translator.GetString("GhastlyCannotPossessTarget")); } killertarget = (b, b2); return false; } private bool CheckConflicts(PlayerControl target) { if ((Object)(object)target != (Object)null) { if (GhastlyKillAllies.GetBool()) { return target.GetCountTypes() != base._Player.GetCountTypes(); } return true; } return false; } public override void OnFixedUpdate(PlayerControl pc) { if (Main.AllPlayerSpeed[pc.PlayerId] != GhastlySpeed.GetFloat()) { Main.AllPlayerSpeed[pc.PlayerId] = GhastlySpeed.GetFloat(); pc.MarkDirtySettings(); } } public void OnFixUpdateOthers(PlayerControl player) { if (killertarget.Item1 == player.PlayerId && LastTime.TryGetValue(player.PlayerId, out var value) && value + PossessDur.GetInt() <= Utils.GetTimeStamp()) { base._Player?.Notify(string.Format("\n" + Translator.GetString("GhastlyExpired") + "\n", player.GetRealName())); TargetArrow.Remove(killertarget.Item1, killertarget.Item2); LastTime.Remove(player.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); } } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { (byte, byte) tuple = killertarget; if (tuple.Item1 == killer.PlayerId && tuple.Item2 != byte.MaxValue) { if (tuple.Item2 != target.PlayerId) { killer.Notify(Translator.GetString("GhastlyNotUrTarget")); return true; } base._Player?.Notify(string.Format("\n" + Translator.GetString("GhastlyExpired") + "\n", killer.GetRealName())); TargetArrow.Remove(killertarget.Item1, killertarget.Item2); LastTime.Remove(killer.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); } return false; } public override string GetLowerTextOthers(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsMeeting || isForMeeting || ((Object)(object)seer != (Object)(object)seen && seer.IsAlive())) { return ""; } byte item = killertarget.Item1; byte item2 = killertarget.Item2; if (item == seen.PlayerId && item2 != byte.MaxValue) { string arrows = TargetArrow.GetArrows(Utils.GetPlayerById(item), item2); string realName = Utils.GetPlayerById(item2).GetRealName(); if (realName == null) { return ""; } return Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Ghastly)), "" + realName + arrows); } return ""; } public override void OnOtherTargetsReducedToAtoms(PlayerControl DeadPlayer) { (byte, byte) tuple = killertarget; if (DeadPlayer.PlayerId == tuple.Item1 || DeadPlayer.PlayerId == tuple.Item2) { base._Player?.Notify(string.Format("\n" + Translator.GetString("GhastlyExpired") + "\n", Utils.GetPlayerById(killertarget.Item1))); TargetArrow.Remove(killertarget.Item1, killertarget.Item2); LastTime.Remove(DeadPlayer.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); } } public override string GetProgressText(byte playerId, bool cooms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Ghastly).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class GuardianAngelTOHE : RoleBase { private const int Id = 20900; private static readonly HashSet PlayerIds = new HashSet(); private static OptionItem AbilityCooldown; private static OptionItem ProtectDur; private static OptionItem ImpVis; public static readonly Dictionary PlayerShield = new Dictionary(); public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanillaGhosts; public override void SetupCustomOption() { Options.SetupRoleOptions(20900, TabGroup.CrewmateRoles, CustomRoles.GuardianAngelTOHE); AbilityCooldown = FloatOptionItem.Create(20910, GeneralOption.GuardianAngelBase_ProtectCooldown, new FloatValueRule(2.5f, 120f, 2.5f), 35f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.GuardianAngelTOHE]).SetValueFormat(OptionFormat.Seconds); ProtectDur = IntegerOptionItem.Create(20911, GeneralOption.GuardianAngelBase_ProtectionDuration, new IntegerValueRule(1, 120, 1), 10, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.GuardianAngelTOHE]).SetValueFormat(OptionFormat.Seconds); ImpVis = BooleanOptionItem.Create(20912, GeneralOption.GuardianAngelBase_ImpostorsCanSeeProtect, defaultValue: true, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.GuardianAngelTOHE]); } public override void Init() { PlayerShield.Clear(); PlayerIds.Clear(); } public override void Add(byte playerId) { CustomRoleManager.OnFixedUpdateOthers.Add(OnOthersFixUpdate); PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = AbilityCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = ProtectDur.GetFloat(); AURoleOptions.ImpostorsCanSeeProtect = ImpVis.GetBool(); } public override bool OnCheckProtect(PlayerControl angel, PlayerControl target) { if (!PlayerShield.ContainsKey(target.PlayerId)) { PlayerShield.Add(target.PlayerId, Utils.GetTimeStamp()); } else { PlayerShield[target.PlayerId] = Utils.GetTimeStamp(); } return true; } public override void OnOtherTargetsReducedToAtoms(PlayerControl target) { if (PlayerShield.ContainsKey(target.PlayerId)) { PlayerShield.Remove(target.PlayerId); } } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { if (PlayerShield.ContainsKey(target.PlayerId)) { if (ImpVis.GetBool()) { killer.SetKillCooldown(); killer.RpcGuardAndKill(target); } return true; } return false; } private void OnOthersFixUpdate(PlayerControl player) { if (PlayerShield.ContainsKey(player.PlayerId) && PlayerShield[player.PlayerId] + ProtectDur.GetInt() <= Utils.GetTimeStamp()) { PlayerShield.Remove(player.PlayerId); } } } internal class Hawk : RoleBase { private const int Id = 28000; public static OptionItem KillCooldown; public static OptionItem HawkCanKillNum; public static OptionItem MinimumPlayersAliveToKill; public static OptionItem MissChance; public static OptionItem IncreaseByOneIfConvert; public readonly Dictionary KillerChanceMiss = new Dictionary(); public int KeepCount; public static bool HasEnabled => CustomRoles.Hawk.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateGhosts; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(28000, TabGroup.CrewmateRoles, CustomRoles.Hawk); KillCooldown = FloatOptionItem.Create(28010, GeneralOption.KillCooldown, new FloatValueRule(0f, 120f, 2.5f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hawk]).SetValueFormat(OptionFormat.Seconds); HawkCanKillNum = IntegerOptionItem.Create(28011, "HawkCanKillNum", new IntegerValueRule(1, 15, 1), 3, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hawk]).SetValueFormat(OptionFormat.Players); MissChance = FloatOptionItem.Create(28012, "MissChance", new FloatValueRule(0f, 97.5f, 2.5f), 85f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hawk]).SetValueFormat(OptionFormat.Percent); MinimumPlayersAliveToKill = IntegerOptionItem.Create(28013, "MinimumPlayersAliveToKill", new IntegerValueRule(0, 15, 1), 4, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hawk]).SetValueFormat(OptionFormat.Players); IncreaseByOneIfConvert = BooleanOptionItem.Create(28014, "IncreaseByOneIfConvert", defaultValue: false, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Hawk]); } public override void Add(byte PlayerId) { base.AbilityLimit = HawkCanKillNum.GetInt(); PlayerControl[] allPlayerControls = Main.AllPlayerControls; for (int i = 0; i < allPlayerControls.Length; i++) { if (allPlayerControls[i].IsAnySubRole((CustomRoles x) => x.IsConverted())) { KeepCount++; } } } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { int num = 0; PlayerControl[] allPlayerControls = Main.AllPlayerControls; for (int i = 0; i < allPlayerControls.Length; i++) { if (allPlayerControls[i].IsAnySubRole((CustomRoles x) => x.IsConverted())) { num++; } } if (num > KeepCount && IncreaseByOneIfConvert.GetBool()) { KeepCount++; base.AbilityLimit += num - KeepCount; } } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = KillCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = 0f; } public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (!KillerChanceMiss.ContainsKey(target.PlayerId)) { KillerChanceMiss.Add(target.PlayerId, MissChance.GetFloat()); } if (CheckRetriConflicts(target) && killer.RpcCheckAndMurder(target, check: true)) { target.SetDeathReason(PlayerState.DeathReason.Slice); killer.RpcMurderPlayer(target); killer.RpcResetAbilityCooldown(); base.AbilityLimit--; SendSkillRPC(); } else if (base.AbilityLimit <= 0f) { killer.Notify(Translator.GetString("HawkKillMax")); } else if (Main.AllAlivePlayerControls.Length < MinimumPlayersAliveToKill.GetInt()) { killer.Notify(Translator.GetString("HawkKillTooManyDead")); } else { killer.RpcResetAbilityCooldown(); base.AbilityLimit--; SendSkillRPC(); killer.Notify(Utils.ColorString(Color32.op_Implicit(Utils.GetRoleColor(CustomRoles.Hawk)), Translator.GetString("HawkMissed"))); } Logger.Info($" {target.GetRealName()}'s DieChance is :{100f - KillerChanceMiss[target.PlayerId]}%", "Hawk", escapeCRLF: true, 100, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Roles\\(Ghosts)\\Crewmate\\Hawk.cs"); KillerChanceMiss[target.PlayerId] -= Math.Clamp(35f, 0f, KillerChanceMiss[target.PlayerId] - 10f); return false; } private bool CheckRetriConflicts(PlayerControl target) { IRandom instance = IRandom.Instance; if ((Object)(object)target != (Object)null && Main.AllAlivePlayerControls.Length >= MinimumPlayersAliveToKill.GetInt() && base.AbilityLimit > 0f && (float)instance.Next(100) >= KillerChanceMiss[target.PlayerId] && !target.Is(CustomRoles.Pestilence) && !target.Is(CustomRoles.Jinx) && !target.Is(CustomRoles.CursedWolf)) { if (target.Is(CustomRoles.NiceMini)) { return Mini.Age > 18; } return true; } return false; } public override string GetProgressText(byte playerId, bool coms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Hawk).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } internal class Warden : RoleBase { private const int Id = 27800; private static OptionItem AbilityCooldown; private static OptionItem IncreaseSpeed; private static OptionItem WardenCanAlertNum; private readonly HashSet IsAffected = new HashSet(); public static bool HasEnabled => CustomRoles.Warden.HasEnabled(); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateGhosts; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(27800, TabGroup.CrewmateRoles, CustomRoles.Warden); AbilityCooldown = FloatOptionItem.Create(27810, GeneralOption.AbilityCooldown, new FloatValueRule(0f, 120f, 2.5f), 25f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warden]).SetValueFormat(OptionFormat.Seconds); IncreaseSpeed = FloatOptionItem.Create(27811, "WardenIncreaseSpeed", new FloatValueRule(1f, 3f, 0.5f), 1f, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warden]).SetValueFormat(OptionFormat.Times); WardenCanAlertNum = IntegerOptionItem.Create(27812, "WardenNotifyLimit", new IntegerValueRule(1, 20, 1), 2, TabGroup.CrewmateRoles, isSingleValue: false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Warden]).SetValueFormat(OptionFormat.Players); } public override void Add(byte PlayerId) { base.AbilityLimit = WardenCanAlertNum.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = AbilityCooldown.GetFloat(); AURoleOptions.ProtectionDurationSeconds = 0f; } public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) CustomRoles customRole = target.GetCustomRole(); if (base.AbilityLimit > 0f) { if (!customRole.IsSpeedRole() && !target.IsAnySubRole((CustomRoles x) => x.IsSpeedRole()) && !IsAffected.Contains(target.PlayerId)) { IsAffected.Add(target.PlayerId); target.MarkDirtySettings(); float tmpSpeed = Main.AllPlayerSpeed[target.PlayerId]; Main.AllPlayerSpeed[target.PlayerId] = Main.AllPlayerSpeed[target.PlayerId] + IncreaseSpeed.GetFloat(); new LateTask(delegate { Main.AllPlayerSpeed[target.PlayerId] = Main.AllPlayerSpeed[target.PlayerId] - Main.AllPlayerSpeed[target.PlayerId] + tmpSpeed; target.MarkDirtySettings(); if (IsAffected.Contains(target.PlayerId)) { IsAffected.Remove(target.PlayerId); } }, 2f, "Warden: Set Speed to default"); } target.Notify(Utils.ColorString(new Color32((byte)179, (byte)0, (byte)0, byte.MaxValue), Translator.GetString("WardenWarn"))); killer.RpcResetAbilityCooldown(); base.AbilityLimit--; SendSkillRPC(); } return false; } public override string GetProgressText(byte playerId, bool cooms) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) return Utils.ColorString(Color32.op_Implicit((base.AbilityLimit > 0f) ? Utils.GetRoleColor(CustomRoles.Warden).ShadeColor(0.25f) : Color.gray), $"({base.AbilityLimit})"); } } } namespace TOHE.Patches { [HarmonyPatch(typeof(AprilFoolsMode), "ShouldShowAprilFoolsToggle")] public static class ShouldShowTogglePatch { public static void Postfix(ref bool __result) { __result = true; } } [HarmonyPatch(typeof(NormalGameManager), "GetBodyType")] public static class GetNormalBodyType_Patch { public static void Postfix(ref PlayerBodyTypes __result) { if (Main.HorseMode.Value) { __result = (PlayerBodyTypes)1; } else if (AprilFoolsMode.ShouldLongAround()) { __result = (PlayerBodyTypes)3; } else { __result = (PlayerBodyTypes)0; } } } [HarmonyPatch(typeof(HideAndSeekManager), "GetBodyType")] public static class GetHnsBodyType_Patch { public static void Postfix(ref PlayerBodyTypes __result, [HarmonyArgument(0)] PlayerControl player) { if ((Object)(object)player == (Object)null || (Object)(object)player.Data == (Object)null || (Object)(object)player.Data.Role == (Object)null) { if (Main.HorseMode.Value) { __result = (PlayerBodyTypes)1; } else if (AprilFoolsMode.ShouldLongAround()) { __result = (PlayerBodyTypes)3; } else { __result = (PlayerBodyTypes)0; } } else if (Main.HorseMode.Value) { if (player.Data.Role.IsImpostor) { __result = (PlayerBodyTypes)0; } else { __result = (PlayerBodyTypes)1; } } else if (AprilFoolsMode.ShouldLongAround()) { if (player.Data.Role.IsImpostor) { __result = (PlayerBodyTypes)4; } else { __result = (PlayerBodyTypes)3; } } else if (player.Data.Role.IsImpostor) { __result = (PlayerBodyTypes)2; } else { __result = (PlayerBodyTypes)0; } } } [HarmonyPatch(typeof(LongBoiPlayerBody))] public static class LongBoiPatches { [HarmonyPatch("Awake")] [HarmonyPrefix] public static bool LongBoyAwake_Prefix(LongBoiPlayerBody __instance) { CosmeticsLayer cosmeticLayer = __instance.cosmeticLayer; cosmeticLayer.OnSetBodyAsGhost += Action.op_Implicit((Action)__instance.SetPoolableGhost); CosmeticsLayer cosmeticLayer2 = __instance.cosmeticLayer; cosmeticLayer2.OnColorChange += Action.op_Implicit((Action)__instance.SetHeightFromColor); CosmeticsLayer cosmeticLayer3 = __instance.cosmeticLayer; cosmeticLayer3.OnCosmeticSet += Action.op_Implicit((Action)__instance.OnCosmeticSet); ((Component)__instance).gameObject.layer = 8; return false; } [HarmonyPatch("Start")] [HarmonyPrefix] public static bool LongBoyStart_Prefix(LongBoiPlayerBody __instance) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 __instance.ShouldLongAround = true; if (__instance.hideCosmeticsQC) { __instance.cosmeticLayer.SetHatVisorVisible(false); } __instance.SetupNeckGrowth(false, true); if (__instance.isExiledPlayer) { ShipStatus instance = ShipStatus.Instance; if ((Object)(object)instance == (Object)null || (int)instance.Type != 3) { __instance.cosmeticLayer.AdjustCosmeticRotations(-17.75f); } } if (!__instance.isPoolablePlayer) { __instance.cosmeticLayer.ValidateCosmetics(); } return false; } [HarmonyPatch("SetHeighFromDistanceHnS")] [HarmonyPrefix] public static bool LongBoyNeckSize_Prefix(LongBoiPlayerBody __instance, ref float distance) { __instance.targetHeight = distance / 10f + 0.5f; __instance.SetupNeckGrowth(true, true); return false; } [HarmonyPatch(typeof(HatManager), "CheckLongModeValidCosmetic")] [HarmonyPrefix] public static bool CheckLongMode_Prefix(out bool __result, ref string cosmeticID) { if (Main.HorseMode.Value) { __result = false; return false; } if (AprilFoolsMode.ShouldLongAround() && string.Equals("skin_rhm", cosmeticID)) { __result = false; return false; } __result = true; return false; } } [HarmonyPatch(typeof(ChatBubble), "SetRight")] internal class ChatBubbleSetRightPatch { public static void Postfix(ChatBubble __instance) { if (Main.isChatCommand) { __instance.SetLeft(); } } } [HarmonyPatch(typeof(ChatBubble), "SetName")] internal class ChatBubbleSetNamePatch { public static void Postfix(ChatBubble __instance, [HarmonyArgument(1)] bool isDead, [HarmonyArgument(2)] bool voted) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsInGame && !voted && __instance.playerInfo.PlayerId == PlayerControl.LocalPlayer.PlayerId) { ((Graphic)__instance.NameText).color = PlayerControl.LocalPlayer.GetRoleColor(); } if (Main.DarkTheme.Value) { if (isDead) { __instance.Background.color = new Color(0f, 0f, 0f, 0.6f); } else { __instance.Background.color = Color.black; } ((Graphic)__instance.TextArea).color = Color.white; } } } [HarmonyPatch(typeof(DeconSystem), "UpdateSystem")] public static class DeconSystemUpdateSystemPatch { public static void Prefix(DeconSystem __instance) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if (Options.ChangeDecontaminationTime.GetBool()) { MapNames activeMapName = Utils.GetActiveMapName(); float num = (((int)activeMapName == 1) ? Options.DecontaminationTimeOnMiraHQ.GetFloat() : (((int)activeMapName != 2) ? 3f : Options.DecontaminationTimeOnPolus.GetFloat())); float deconTime = (__instance.DoorOpenTime = num); __instance.DeconTime = deconTime; } else { __instance.DoorOpenTime = 3f; __instance.DeconTime = 3f; } } } } [HarmonyPatch(typeof(DialogueBox))] internal class DialogueBoxPatch { [HarmonyPatch("Show")] [HarmonyPostfix] public static void Show_Postfix(DialogueBox __instance, [HarmonyArgument(0)] string dialouge) { if (!PlayerControl.LocalPlayer.inVent && dialouge.Contains("tohe") && GameStates.IsInTask) { PlayerControl.LocalPlayer.ForceKillTimerContinue = true; } } [HarmonyPatch("Hide")] [HarmonyPostfix] public static void Hide_Postfix(DialogueBox __instance) { if (((TMP_Text)__instance.target).text.Contains("tohe")) { PlayerControl.LocalPlayer.ForceKillTimerContinue = false; } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static class DisconnectPenaltyPatch { public static bool Prefix(StatsManager __instance, ref int __result) { if (!DebugModeManager.AmDebugger) { return true; } if (__instance.BanPoints != 0f) { __instance.BanPoints = 0f; __result = 0; Logger.Info("Debug Removed Disconnect ban", "PenaltyPatch", escapeCRLF: true, 15, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\DisconnectPenaltyPatch.cs"); return false; } return true; } } [HarmonyPatch(typeof(ActivityManager), "UpdateActivity")] public class DiscordRPC { private static string lobbycode = ""; private static string region = ""; public static void Prefix([HarmonyArgument(0)] Activity activity) { if (activity == null) { return; } string details = (activity.Details = "TOHE v2.0.3"); try { if (!(activity.State != "In Menus")) { return; } if (!DataManager.Settings.Gameplay.StreamerMode) { _ = GameOptionsManager.Instance.CurrentGameOptions.MaxPlayers; if (GameStates.IsLobby) { lobbycode = ((TMP_Text)DestroyableSingleton.Instance.GameRoomNameCode).text; region = Utils.GetRegionName(); } if (lobbycode != "" && region != "") { if (GameStates.IsNormalGame) { details = $"TOHE - {lobbycode} ({region})"; } else if (GameStates.IsHideNSeek) { details = $"TOHE Hide & Seek - {lobbycode} ({region})"; } } activity.Details = details; } else { details = (GameStates.IsNormalGame ? "TOHE v2.0.3" : ((!GameStates.IsHideNSeek) ? "TOHE v2.0.3" : "TOHE v2.0.3 - Hide & Seek")); activity.Details = details; } } catch (ArgumentException ex) { Logger.Error("Error in updating discord rpc", "DiscordPatch", escapeCRLF: true, 61, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\DiscordPatch.cs"); Logger.Exception(ex, "DiscordPatch", 62, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\DiscordPatch.cs"); details = "TOHE v2.0.3"; activity.Details = details; } } } [HarmonyPatch(typeof(_CoStartGameHost_d__32), "MoveNext")] public static class DleksPatch { private static bool Prefix(_CoStartGameHost_d__32 __instance, ref bool __result) { if (__instance.__1__state != 0) { return true; } __instance.__1__state = -1; if (Object.op_Implicit((Object)(object)LobbyBehaviour.Instance)) { ((InnerNetObject)LobbyBehaviour.Instance).Despawn(); } if (Object.op_Implicit((Object)(object)ShipStatus.Instance)) { __instance.__2__current = null; __instance.__1__state = 2; __result = true; return false; } int num = Mathf.Clamp((int)GameOptionsManager.Instance.CurrentGameOptions.MapId, 0, ((Il2CppArrayBase)(object)Constants.MapNames).Length - 1); AsyncOperationHandle _2__current = (__instance.__4__this.ShipLoadingAsyncHandle = __instance.__4__this.ShipPrefabs[num].InstantiateAsync((Transform)null, false)); __instance.__2__current = (Object)(object)_2__current; __instance.__1__state = 1; __result = true; return false; } } [HarmonyPatch(typeof(GameStartManager))] internal class AllMapIconsPatch { [HarmonyPatch("Start")] [HarmonyPostfix] public static void Postfix_AllMapIcons(GameStartManager __instance) { if ((Object)(object)__instance == (Object)null) { return; } if (GameStates.IsNormalGame && Main.NormalOptions.MapId == 3) { Main.NormalOptions.MapId = 0; __instance.UpdateMapImage((MapNames)0); if (!Options.RandomMapsMode.GetBool()) { CreateOptionsPickerPatch.SetDleks = true; } } else if (GameStates.IsHideNSeek && Main.HideNSeekOptions.MapId == 3) { Main.HideNSeekOptions.MapId = 0; __instance.UpdateMapImage((MapNames)0); if (!Options.RandomMapsMode.GetBool()) { CreateOptionsPickerPatch.SetDleks = true; } } MapIconByName val = Object.Instantiate(__instance, ((Component)__instance).gameObject.transform).AllMapIcons[0]; val.Name = (MapNames)3; val.MapImage = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner.png", 100f); val.NameImage = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner-Wordart.png", 100f); __instance.AllMapIcons.Add(val); } } [HarmonyPatch(typeof(StringOption), "Start")] internal class AutoSelectDleksPatch { private static void Postfix(StringOption __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((int)((OptionBehaviour)__instance).Title == 132) { __instance.Value = GameOptionsManager.Instance.CurrentGameOptions.MapId; } } } [HarmonyPatch(typeof(Vent), "SetButtons")] public static class VentSetButtonsPatch { public static bool ShowButtons; private static bool Prefix(Vent __instance, [HarmonyArgument(0)] ref bool enabled) { if (GameStates.DleksIsActive && Main.introDestroyed) { enabled = false; if (GameStates.IsMeeting) { ShowButtons = false; } } return true; } public static void Postfix(Vent __instance, [HarmonyArgument(0)] bool enabled) { if (GameStates.DleksIsActive && !enabled && Main.introDestroyed) { bool active = ShowButtons || (!PlayerControl.LocalPlayer.inVent && !GameStates.IsMeeting); switch (__instance.Id) { case 0: case 1: case 2: case 3: case 5: case 6: ((Component)((Il2CppArrayBase)(object)__instance.Buttons)[0]).gameObject.SetActive(active); ((Component)((Il2CppArrayBase)(object)__instance.Buttons)[1]).gameObject.SetActive(active); break; case 7: case 12: case 13: ((Component)((Il2CppArrayBase)(object)__instance.Buttons)[0]).gameObject.SetActive(active); break; case 4: case 8: case 9: case 10: case 11: ((Component)((Il2CppArrayBase)(object)__instance.Buttons)[1]).gameObject.SetActive(active); break; } } } } [HarmonyPatch(typeof(Vent), "TryMoveToVent")] internal class VentTryMoveToVentPatch { private static void Postfix(Vent __instance, [HarmonyArgument(0)] Vent otherVent) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)otherVent == (Object)null) && GameStates.DleksIsActive) { VentSetButtonsPatch.ShowButtons = true; VentSetButtonsPatch.Postfix(otherVent, enabled: false); VentSetButtonsPatch.ShowButtons = false; } } } [HarmonyPatch(typeof(Vent), "UpdateArrows")] internal class VentUpdateArrowsPatch { private static bool Prefix() { return !GameStates.DleksIsActive; } } [HarmonyPatch(typeof(EndGameManager), "ShowButtons")] public class EndGameManagerPatch { public static GameObject CountdownText; public static TextMeshPro CountdownTextText; public static bool IsRestarting; public static void Postfix(EndGameManager __instance) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && Options.AutoPlayAgain.GetBool()) { IsRestarting = false; new LateTask(delegate { Logger.Msg("Beginning Auto Play Again Countdown!", "AutoPlayAgain", escapeCRLF: true, 21, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\EndGameManagerPatch.cs"); IsRestarting = true; BeginAutoPlayAgainCountdown(__instance, Options.AutoPlayAgainCountdown.GetInt()); }, 0.5f, "Auto Play Again"); } } private static void BeginAutoPlayAgainCountdown(EndGameManager endGameManager, int seconds) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if (!IsRestarting) { try { if ((Object)(object)CountdownTextText != (Object)null && ((Behaviour)CountdownTextText).isActiveAndEnabled) { ((TMP_Text)CountdownTextText).text = string.Format(Translator.GetString("CancelStartCountDown"), seconds); } return; } catch { return; } } if ((Object)(object)endGameManager == (Object)null) { return; } EndGameNavigation navigation = endGameManager.Navigation; if ((Object)(object)navigation == (Object)null) { return; } if (seconds == Options.AutoPlayAgainCountdown.GetInt()) { CountdownText = new GameObject("CountdownText"); CountdownText.transform.position = new Vector3(0f, -2.5f, 30f); CountdownTextText = CountdownText.AddComponent(); ((TMP_Text)CountdownTextText).text = string.Format(Translator.GetString("CountdownText"), seconds); ((TMP_Text)CountdownTextText).alignment = (TextAlignmentOptions)514; ((TMP_Text)CountdownTextText).fontSize = 3f; } else { ((TMP_Text)CountdownTextText).text = string.Format(Translator.GetString("CountdownText"), seconds); } if (seconds == 0) { navigation.NextGame(); GameObjectExtensions.DestroyChildren(CountdownText.transform); } else { new LateTask(delegate { BeginAutoPlayAgainCountdown(endGameManager, seconds - 1); }, 1f, "Begin Auto Play Again Countdown"); } } } [HarmonyPatch(typeof(HauntMenuMinigame), "SetFilterText")] public static class HauntMenuMinigameSetFilterTextPatch { public static bool Prefix(HauntMenuMinigame __instance) { if ((Object)(object)__instance.HauntTarget != (Object)null && Options.GhostCanSeeOtherRoles.GetBool()) { ((TMP_Text)__instance.FilterText).text = Utils.GetDisplayRoleAndSubName(PlayerControl.LocalPlayer.PlayerId, __instance.HauntTarget.PlayerId); return false; } return true; } } public enum GameDataTag : byte { DataFlag = 1, RpcFlag = 2, SpawnFlag = 4, DespawnFlag = 5, SceneChangeFlag = 6, ReadyFlag = 7, ChangeSettingsFlag = 8, ConsoleDeclareClientPlatformFlag = 205, PS4RoomRequest = 206, XboxDeclareXuid = 207 } [HarmonyPatch(typeof(InnerNetClient), "HandleGameDataInner")] internal class GameDataHandlerPatch { public static bool Prefix(InnerNetClient __instance, MessageReader reader, int msgNum) { MessageReader.Get(reader); switch ((GameDataTag)reader.Tag) { case GameDataTag.DataFlag: { uint num3 = reader.ReadPackedUInt32(); InnerNetObject val = default(InnerNetObject); if (!__instance.allObjectsFast.TryGetValue(num3, ref val)) { break; } if (val.AmOwner) { Logger.Warn($"Received DataFlag for object {num3.ToString()} {((Object)val).name} that we own.", "GameDataHandlerPatch", escapeCRLF: true, 37, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if ((Object)(object)val == (Object)(object)MeetingHud.Instance) { Logger.Warn($"Received DataFlag for MeetingHud {num3.ToString()} that we own.", "GameDataHandlerPatch", escapeCRLF: true, 47, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } if ((Object)(object)val == (Object)(object)VoteBanSystem.Instance) { Logger.Warn($"Received DataFlag for VoteBanSystem {num3.ToString()} that we own.", "GameDataHandlerPatch", escapeCRLF: true, 54, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } if (val is NetworkedPlayerInfo) { Logger.Warn($"Received DataFlag for NetworkedPlayerInfo {num3.ToString()} that we own.", "GameDataHandlerPatch", escapeCRLF: true, 61, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } } break; } case GameDataTag.SceneChangeFlag: { int num2 = reader.ReadPackedInt32(); string text = reader.ReadString(); ClientData clientById = Utils.GetClientById(num2); if (clientById == null) { Logger.Warn($"Received SceneChangeFlag for unknown client {num2}.", "GameDataHandlerPatch", escapeCRLF: true, 91, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); return false; } if (text == string.Empty || text == null) { Logger.Warn($"Client {clientById.PlayerName} ({clientById.Id}) tried to send SceneChangeFlag with null scene.", "GameDataHandlerPatch", escapeCRLF: true, 97, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } if (text.ToLower() == "tutorial") { Logger.Warn($"Client {clientById.PlayerName} ({clientById.Id}) tried to send SceneChangeFlag to Tutorial.", "GameDataHandlerPatch", escapeCRLF: true, 104, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(100); if (GameStates.IsOnlineGame && ((InnerNetClient)AmongUsClient.Instance).AmHost) { Utils.ErrorEnd("SceneChange Tutorial Hack"); } return false; } if (GameStates.IsInGame) { Logger.Warn($"Client {clientById.PlayerName} ({clientById.Id}) tried to send SceneChangeFlag during mid of game.", "GameDataHandlerPatch", escapeCRLF: true, 116, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); return false; } break; } case GameDataTag.ReadyFlag: { int num = reader.ReadPackedInt32(); if (Utils.GetClientById(num) == null) { Logger.Warn($"Received ReadyFlag for unknown client {num}.", "GameDataHandlerPatch", escapeCRLF: true, 130, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } if (((InnerNetClient)AmongUsClient.Instance).AmHost && !StartGameHostPatch.isStartingAsHost) { Logger.Warn($"Received ReadyFlag while game is started from {num}.", "GameDataHandlerPatch", escapeCRLF: true, 139, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\InnerNetClientPatch.cs"); EAC.WarnHost(); return false; } break; } } return true; } } [HarmonyPatch(typeof(AmongUsClient), "CoStartGameHost")] internal class StartGameHostPatch { public static bool isStartingAsHost; public static void Prefix(AmongUsClient __instance) { if ((Object)(object)LobbyBehaviour.Instance != (Object)null) { isStartingAsHost = true; } } public static void Postfix(AmongUsClient __instance) { if ((Object)(object)ShipStatus.Instance != (Object)null) { isStartingAsHost = false; } } } [HarmonyPatch] internal class AuthTimeoutPatch { [HarmonyPatch(typeof(_CoConnect_d__4), "MoveNext")] [HarmonyPatch(typeof(_CoWaitForNonce_d__6), "MoveNext")] [HarmonyPrefix] public static bool CoWaitforNoncePrefix(ref bool __result) { if (GameStates.IsVanillaServer) { return true; } __result = false; return false; } [HarmonyPatch(typeof(_CoJoinOnlinePublicGame_d__1), "MoveNext")] [HarmonyPrefix] public static void EnableUdpMatchmakingPrefix(_CoJoinOnlinePublicGame_d__1 __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (__instance.__1__state == 0 && !DestroyableSingleton.Instance.IsHttp) { __instance.__1__state = 1; __instance.__8__1 = new __c__DisplayClass1_0 { matchmakerToken = string.Empty }; } } } [HarmonyPatch(typeof(LobbyBehaviour), "Start")] public class LobbyStartPatch { private static GameObject LobbyPaintObject; private static GameObject DropshipDecorationsObject; private static Sprite LobbyPaintSprite; private static Sprite DropshipDecorationsSprite; private static bool FirstDecorationsLoad = true; public static void Prefix() { LobbyPaintSprite = Utils.LoadSprite("TOHE.Resources.Images.LobbyPaint.png", 290f); DropshipDecorationsSprite = Utils.LoadSprite("TOHE.Resources.Images.Dropship-Decorations.png", 60f); } public static void Postfix(LobbyBehaviour __instance) { float num = 0f; new LateTask(time: (!FirstDecorationsLoad) ? 0.05f : 0.25f, action: delegate { ((MonoBehaviour)__instance).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(CoLoadDecorations())); }, name: "Co Load Dropship Decorations", shoudLog: false); static IEnumerator CoLoadDecorations() { GameObject val = GameObject.Find("Leftbox"); if ((Object)(object)val != (Object)null) { LobbyPaintObject = Object.Instantiate(val, ((Component)val.transform.parent).transform); ((Object)LobbyPaintObject).name = "Lobby Paint"; LobbyPaintObject.transform.localPosition = new Vector3(0.042f, -2.59f, -10.5f); LobbyPaintObject.GetComponent().sprite = LobbyPaintSprite; } yield return null; if (Main.EnableCustomDecorations.Value) { GameObject val2 = GameObject.Find("SmallBox"); if ((Object)(object)val2 != (Object)null) { DropshipDecorationsObject = Object.Instantiate(val2, ((Component)Object.FindAnyObjectByType()).transform); ((Object)DropshipDecorationsObject).name = "Lobby_Decorations"; GameObjectExtensions.DestroyChildren(DropshipDecorationsObject.transform); Object.Destroy((Object)(object)DropshipDecorationsObject.GetComponent()); DropshipDecorationsObject.GetComponent().sprite = DropshipDecorationsSprite; DropshipDecorationsObject.transform.SetSiblingIndex(1); DropshipDecorationsObject.transform.localPosition = new Vector3(0.05f, 0.8334f); } } yield return null; FirstDecorationsLoad = false; } } } [HarmonyPatch(typeof(LobbyBehaviour))] public class LobbyBehaviourPatch { [HarmonyPatch("Update")] [HarmonyPostfix] public static void Update_Postfix(LobbyBehaviour __instance) { Func func = (ISoundPlayer x) => x.Name.Equals("MapTheme"); ISoundPlayer val = SoundManager.Instance.soundPlayers.Find(Predicate.op_Implicit(func)); if (Main.DisableLobbyMusic.Value) { if (val != null) { SoundManager.Instance.StopNamedSound("MapTheme"); } } else if (val == null) { SoundManager.Instance.CrossFadeSound("MapTheme", __instance.MapTheme, 0.5f, 1.5f); } } } [HarmonyPatch(typeof(HostInfoPanel), "SetUp")] public static class HostInfoPanelUpdatePatch { private static TextMeshPro HostText; public static void Postfix(HostInfoPanel __instance) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (((InnerNetClient)AmongUsClient.Instance).AmHost) { if ((Object)(object)HostText == (Object)null) { HostText = ((Component)__instance.content.transform.FindChild("Name")).GetComponent(); } string value = ColorUtility.ToHtmlStringRGB(Color32.op_Implicit(((Il2CppArrayBase)(object)Palette.PlayerColors)[__instance.player.ColorId])); string hostRealName = Main.HostRealName; string @string = DestroyableSingleton.Instance.GetString((StringNames)3375, (Il2CppReferenceArray)null); ((TMP_Text)HostText).text = $"{hostRealName} ({@string})"; } } } internal class CreateOptionsPickerPatch { [HarmonyPatch(typeof(GameOptionsMapPicker))] public static class GameOptionsMapPickerPatch { [HarmonyPatch("Initialize")] [HarmonyPostfix] public static void Postfix_Initialize(GameOptionsMapPicker __instance) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) int num = 3; MapSelectButton[] array = Il2CppArrayBase.op_Implicit(((Component)((Component)__instance).transform).GetComponentsInChildren()); if (array == null) { return; } GameObject val = Object.Instantiate(((Component)array[0]).gameObject, ((Component)__instance).transform); val.transform.position = ((Component)array[num]).transform.position; val.transform.SetSiblingIndex(num + 2); MapSelectButton dlekS_ehT_MapButton = val.GetComponent(); DleksButton = dlekS_ehT_MapButton; ((Component)dlekS_ehT_MapButton.MapIcon).transform.localScale = new Vector3(-1f, 1f, 1f); ((UnityEventBase)dlekS_ehT_MapButton.Button.OnClick).RemoveAllListeners(); ((UnityEvent)dlekS_ehT_MapButton.Button.OnClick).AddListener(UnityAction.op_Implicit((Action)delegate { __instance.SelectMap(__instance.AllMapIcons[0]); if (Object.op_Implicit((Object)(object)__instance.selectedButton)) { __instance.selectedButton.Button.SelectButton(false); } __instance.selectedButton = dlekS_ehT_MapButton; __instance.selectedButton.Button.SelectButton(true); __instance.selectedMapId = 3; if (GameStates.IsNormalGame) { Main.NormalOptions.MapId = 0; } else if (GameStates.IsHideNSeek) { Main.HideNSeekOptions.MapId = 0; } __instance.MapImage.sprite = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner.png", 100f); __instance.MapName.sprite = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner-Wordart.png", 100f); })); for (int i = num; i < array.Length; i++) { Transform transform = ((Component)array[i]).transform; transform.localPosition += new Vector3(0.625f, 0f, 0f); } if (!((Object)(object)DleksButton != (Object)null)) { return; } if (SetDleks) { if (Object.op_Implicit((Object)(object)__instance.selectedButton)) { __instance.selectedButton.Button.SelectButton(false); } DleksButton.Button.SelectButton(true); __instance.selectedButton = DleksButton; __instance.selectedMapId = 3; __instance.MapImage.sprite = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner.png", 100f); __instance.MapName.sprite = Utils.LoadSprite("TOHE.Resources.Images.DleksBanner-Wordart.png", 100f); } else { DleksButton.Button.SelectButton(false); } } [HarmonyPatch("FixedUpdate")] [HarmonyPrefix] public static bool Prefix_FixedUpdate(GameOptionsMapPicker __instance) { if ((Object)(object)__instance == (Object)null) { return true; } if ((Object)(object)DleksButton != (Object)null) { if (__instance.selectedMapId == 3) { SetDleks = true; } else { SetDleks = false; } } if (__instance.selectedMapId == 3) { return false; } return true; } } [HarmonyPatch(typeof(CreateOptionsPicker), "Awake")] private class MenuMapPickerPatch { public static void Postfix(CreateOptionsPicker __instance) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)__instance).transform.Find("MapPicker"); MapPickerMenu component = ((Component)val.Find("Map Picker Menu")).GetComponent(); MapFilterButton val2 = ((Il2CppArrayBase)(object)__instance.MapMenu.MapButtons)[3]; MapFilterButton one = ((Il2CppArrayBase)(object)__instance.MapMenu.MapButtons)[4]; MapFilterButton val3 = ((Il2CppArrayBase)(object)__instance.MapMenu.MapButtons)[0]; MapFilterButton val4 = Object.Instantiate(val2, ((Component)val2).transform.parent); Transform val5 = ((Component)component).transform.Find("Skeld"); Transform val6 = ((Component)component).transform.Find("Polus"); Transform val7 = ((Component)component).transform.Find("Airship"); Transform val8 = ((Component)component).transform.Find("Fungle"); Transform val9 = Object.Instantiate(val7, val7.parent); PassiveButton component2 = ((Component)val9).GetComponent(); ((UnityEventBase)component2.OnClick).m_PersistentCalls.m_Calls._items[0].arguments.intArgument = 3; SpriteRenderer component3 = ((Component)val9.Find("Image")).GetComponent(); component3.sprite = ((Component)val5.Find("Image")).GetComponent().sprite; ((Object)val4).name = "Dleks"; ((Component)val4).transform.localPosition = new Vector3(0.8f, ((Component)val2).transform.localPosition.y, ((Component)val2).transform.localPosition.z); val4.MapId = (MapNames)3; val4.Button = component2; val4.ButtonCheck = ((Component)val9.Find("selectedCheck")).GetComponent(); val4.ButtonImage = component3; val4.ButtonOutline = ((Component)((Component)component3).transform.parent).GetComponent(); val4.Icon.sprite = val3.Icon.sprite; ((Object)val9).name = "Dleks"; val9.position = new Vector3(val9.position.x, 2f * val9.position.y - ((Component)val6).transform.position.y, val9.position.z); val8.position = new Vector3(val8.position.x, ((Component)val9).transform.position.y - 0.6f, val8.position.z); __instance.MapMenu.MapButtons = Il2CppReferenceArray.op_Implicit(CollectionExtensions.AddItem((IEnumerable)__instance.MapMenu.MapButtons, val4).ToArray()); float num = -1f; for (int i = 0; i < 6; i++) { GameObjectExtensions.SetLocalX(((Component)((Il2CppArrayBase)(object)__instance.MapMenu.MapButtons)[i]).transform, num); num += 0.34f; } if ((int)__instance.mode == 0) { ((Component)component).transform.localPosition = new Vector3(((Component)component).transform.localPosition.x, 0.85f, ((Component)component).transform.localPosition.z); val.localScale = new Vector3(0.86f, 0.85f, 1f); ((Component)val).transform.localPosition = new Vector3(((Component)val).transform.localPosition.x + 0.05f, ((Component)val).transform.localPosition.y + 0.03f, ((Component)val).transform.localPosition.z); } SwapIconOrButtomsPositions((Component)(object)val2, (Component)(object)val4); SwapIconOrButtomsPositions((Component)(object)one, (Component)(object)val2); SwapIconOrButtomsPositions((Component)(object)val7, (Component)(object)val9); ((Il2CppArrayBase)(object)__instance.MapMenu.MapButtons)[5].SetFlipped(true); Transform obj = ((Component)component).transform.Find("Backdrop"); obj.localScale *= 5f; } private static void SwapIconOrButtomsPositions(Component one, Component two) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) Transform transform = one.transform; Transform transform2 = two.transform; Vector3 position = two.transform.position; Vector3 position2 = one.transform.position; transform.position = position; Vector3 position3 = position2; transform2.position = position3; } } public static bool SetDleks; private static MapSelectButton DleksButton; } [HarmonyPatch(typeof(RegionMenu))] public static class RegionMenuPatch { public static Scroller Scroller; [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Awake_Postfix(RegionMenu __instance) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Scroller != (Object)null)) { Transform val = ((Component)__instance.ButtonPool).transform.FindChild("Backdrop"); Transform transform = ((Component)val).transform; transform.localScale *= 10f; Scroller = ((Component)((Component)__instance.ButtonPool).transform.parent).gameObject.AddComponent(); Scroller.Inner = ((Component)__instance.ButtonPool).transform; Scroller.MouseMustBeOverToScroll = true; ((PassiveUiElement)Scroller).ClickMask = (Collider2D)(object)((Component)val).GetComponent(); Scroller.ScrollWheelSpeed = 0.7f; Scroller.SetYBoundsMin(0f); Scroller.SetYBoundsMax(4f); Scroller.allowY = true; } } } [HarmonyPatch(typeof(SabotageButton), "DoClick")] public static class SabotageButtonDoClickPatch { public static bool Prefix() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (!PlayerControl.LocalPlayer.inVent && GameManager.Instance.SabotagesEnabled()) { DestroyableSingleton.Instance.ToggleMapVisible(new MapOptions { Mode = (Modes)3 }); } return false; } } [HarmonyPatch(typeof(Constants), "GetBroadcastVersion")] internal class ServerUpdatePatch { private static void Postfix(ref int __result) { if (GameStates.IsLocalGame) { Logger.Info($"IsLocalGame: {__result}", "VersionServer", escapeCRLF: true, 10, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ServerVersionPatch.cs"); } if (GameStates.IsOnlineGame) { __result += 25; Logger.Info($"IsOnlineGame: {__result}", "VersionServer", escapeCRLF: true, 18, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\ServerVersionPatch.cs"); } } } [HarmonyPatch(typeof(Constants), "IsVersionModded")] public static class IsVersionModdedPatch { public static bool Prefix(ref bool __result) { __result = true; return false; } } [HarmonyPatch] public class ShowHostMeetingPatch { private static PlayerControl HostControl = null; private static string hostName = string.Empty; private static int hostColor = int.MaxValue; [HarmonyPatch(typeof(PlayerControl), "OnDestroy")] [HarmonyPostfix] public static void OnDestroy_Postfix() { try { if (GameStates.IsInGame && (Object)(object)HostControl == (Object)null) { HostControl = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character; hostName = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character.CurrentOutfit.PlayerName; hostColor = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character.CurrentOutfit.ColorId; if (Doppelganger.HasEnabled && Doppelganger.CheckDoppelVictim(((InnerNetClient)AmongUsClient.Instance).GetHost().Character.PlayerId)) { hostName = Main.PlayerStates[((InnerNetClient)AmongUsClient.Instance).GetHost().Character.Data.PlayerId].NormalOutfit.PlayerName; hostColor = Main.PlayerStates[((InnerNetClient)AmongUsClient.Instance).GetHost().Character.Data.PlayerId].NormalOutfit.ColorId; } } } catch { } } [HarmonyPatch(typeof(IntroCutscene), "ShowRole")] [HarmonyPostfix] public static void ShowRole_Postfix() { HostControl = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character; hostName = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character.CurrentOutfit.PlayerName; hostColor = ((InnerNetClient)AmongUsClient.Instance).GetHost().Character.CurrentOutfit.ColorId; } [HarmonyPatch(typeof(MeetingHud), "Update")] [HarmonyPostfix] public static void Update_Postfix(MeetingHud __instance) { if (GameStates.IsOnlineGame) { PlayerMaterial.SetColors(hostColor, (Renderer)(object)__instance.HostIcon); ((TMP_Text)((Component)__instance.ProceedButton).gameObject.GetComponentInChildren()).text = string.Format(Translator.GetString("HostIconInMeeting"), hostName); } } [HarmonyPatch(typeof(MeetingHud), "Start")] [HarmonyPostfix] public static void Setup_Postfix(MeetingHud __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (GameStates.IsOnlineGame) { ((Component)__instance.ProceedButton).gameObject.transform.localPosition = new Vector3(-2.5f, 2.2f, 0f); ((Renderer)((Component)__instance.ProceedButton).gameObject.GetComponent()).enabled = false; ((Behaviour)((Component)__instance.ProceedButton).GetComponent()).enabled = false; ((Renderer)__instance.HostIcon).enabled = true; ((Component)__instance.HostIcon).gameObject.SetActive(true); ((Component)__instance.ProceedButton).gameObject.SetActive(true); } } } [HarmonyPatch(typeof(VoteBanSystem), "AddVote")] internal class VoteBanSystemPatch { public static bool Prefix([HarmonyArgument(0)] int srcClient, [HarmonyArgument(1)] int clientId) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } return false; } } } namespace TOHE.Patches.HideNSeek { [HarmonyPatch(typeof(LogicGameFlowHnS), "CheckEndCriteria")] internal class GameEndCheckerForHnS { public static bool Prefix() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (Options.NoGameEnd.GetBool()) { CustomWinner winnerTeam = CustomWinnerHolder.WinnerTeam; if (winnerTeam != CustomWinner.Draw && winnerTeam != CustomWinner.Error) { return false; } } return true; } } [HarmonyPatch(typeof(LogicGameFlowHnS), "OnGameEnd")] internal class OnGameEndForHnS { public static bool Prefix() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return true; } if (Options.NoGameEnd.GetBool()) { CustomWinner winnerTeam = CustomWinnerHolder.WinnerTeam; if (winnerTeam != CustomWinner.Draw && winnerTeam != CustomWinner.Error) { return false; } } return true; } } [HarmonyPatch(typeof(PlayerControl), "CheckMurder")] internal class CheckMurderInHidenSeekPatch { public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target) { if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return false; } if (GameStates.IsNormalGame) { return true; } Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + " => " + target.GetNameWithRole().RemoveHtmlTags(), "CheckMurder H&S", escapeCRLF: true, 18, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); if (!__instance.IsAlive()) { Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + " was cancelled because it is dead", "CheckMurder H&S", escapeCRLF: true, 23, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); return false; } if ((Object)(object)target.Data == (Object)null || target.inVent || target.inMovingPlat || target.MyPhysics.Animations.IsPlayingEnterVentAnimation() || target.MyPhysics.Animations.IsPlayingAnyLadderAnimation()) { Logger.Info("The target is in an unkillable state and the kill is canceled", "CheckMurder H&S", escapeCRLF: true, 36, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); return false; } if (!target.IsAlive()) { Logger.Info("The target is in a dead state and the kill is canceled", "CheckMurder H&S", escapeCRLF: true, 42, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); return false; } if ((Object)(object)MeetingHud.Instance != (Object)null) { Logger.Info("In the meeting, the kill was canceled", "CheckMurder H&S", escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); return false; } return true; } } [HarmonyPatch(typeof(PlayerControl), "MurderPlayer")] internal class MurderPlayerInHidenSeekPatch { public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] PlayerControl target) { if (((InnerNetClient)AmongUsClient.Instance).AmHost && !GameStates.IsNormalGame && target.Data.IsDead) { Logger.Info(__instance.GetNameWithRole().RemoveHtmlTags() + " => " + target.GetNameWithRole().RemoveHtmlTags(), "MurderPlayer H&S", escapeCRLF: true, 66, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); if ((Object)(object)__instance != (Object)(object)__instance) { Logger.Info("Real Killer => " + __instance.GetNameWithRole().RemoveHtmlTags(), "MurderPlayer H&S", escapeCRLF: true, 70, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); } if (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.etc) { target.SetDeathReason(PlayerState.DeathReason.Kill); } Main.PlayerStates[target.PlayerId].SetDead(); target.SetRealKiller(__instance, NotOverRide: true); if (Options.LowLoadMode.GetBool()) { __instance.MarkDirtySettings(); target.MarkDirtySettings(); } else { Utils.SyncAllSettings(); } Logger.Info($"Killer Is Alive: {__instance.IsAlive()}, Target Is Alive: {target.IsAlive()}", "Check Is Alive", escapeCRLF: true, 91, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); } } } [HarmonyPatch(typeof(PlayerControl), "FixedUpdate")] internal class FixedUpdateInHidenSeekPatch { private static int LevelKickBufferTime = 20; private static readonly Dictionary BufferTime = new Dictionary(); public static async void Postfix(PlayerControl __instance) { if (GameStates.IsNormalGame || !GameStates.IsModHost || (Object)(object)__instance == (Object)null) { return; } try { await DoPostfix(__instance); } catch (Exception value) { Logger.Error($"Error for {__instance.GetNameWithRole().RemoveHtmlTags()}: {value}", "FixedUpdateInHidenSeekPatch", escapeCRLF: true, 112, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); } } public static Task DoPostfix(PlayerControl __instance) { bool flag = false; if (Options.LowLoadMode.GetBool()) { if (!BufferTime.TryGetValue(__instance.PlayerId, out var value)) { BufferTime.TryAdd(__instance.PlayerId, 10); value = 10; } value--; if (value > 0) { flag = true; } else { value = 10; } BufferTime[__instance.PlayerId] = value; } if (!flag) { Zoom.OnFixedUpdate(); } if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return Task.CompletedTask; } if (GameStates.IsLobby) { if (((ModUpdater.hasUpdate && ModUpdater.forceUpdate) || ModUpdater.isBroken || !Main.AllowPublicRoom || !VersionChecker.IsSupported) && ((InnerNetClient)AmongUsClient.Instance).IsGamePublic) { ((InnerNetClient)AmongUsClient.Instance).ChangeGamePublic(false); } bool flag2 = false; if (Options.ApplyAllowList.GetBool()) { flag2 = BanManager.CheckAllowList(__instance.Data.FriendCode); } if (!flag2 && !flag && !((InnerNetObject)__instance).AmOwner && Options.KickLowLevelPlayer.GetInt() != 0 && __instance.Data.PlayerLevel != 0 && __instance.Data.PlayerLevel < Options.KickLowLevelPlayer.GetInt()) { LevelKickBufferTime--; if (LevelKickBufferTime <= 0) { LevelKickBufferTime = 20; if (!Options.TempBanLowLevelPlayer.GetBool()) { ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), false); string text = string.Format(Translator.GetString("KickBecauseLowLevel"), __instance.GetRealName().RemoveHtmlTags()); Logger.SendInGame(text); Logger.Info(text, "Low Level Kick", escapeCRLF: true, 180, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); } else { if (__instance.GetClient().ProductUserId != "" && !BanManager.TempBanWhiteList.Contains(__instance.GetClient().GetHashedPuid())) { BanManager.TempBanWhiteList.Add(__instance.GetClient().GetHashedPuid()); } string text2 = string.Format(Translator.GetString("TempBannedBecauseLowLevel"), __instance.GetRealName().RemoveHtmlTags()); Logger.SendInGame(text2); ((InnerNetClient)AmongUsClient.Instance).KickPlayer(__instance.GetClientId(), true); Logger.Info(text2, "Low Level Temp Ban", escapeCRLF: true, 192, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Patches\\HideNSeek\\PlayerControlPatchHnS.cs"); } } } if (KickPlayerPatch.AttemptedKickPlayerList.Any()) { foreach (KeyValuePair attemptedKickPlayer in KickPlayerPatch.AttemptedKickPlayerList) { KickPlayerPatch.AttemptedKickPlayerList[attemptedKickPlayer.Key]++; if (attemptedKickPlayer.Value > 11) { KickPlayerPatch.AttemptedKickPlayerList.Remove(attemptedKickPlayer.Key); } } } } else if (!flag && Options.LadderDeath.GetBool() && __instance.IsAlive()) { FallFromLadder.FixedUpdate(__instance); } if (!Main.DoBlockNameChange) { Utils.ApplySuffix(__instance); } return Task.CompletedTask; } } } namespace TOHE.Modules { public static class AdminProvider { public readonly record struct AdminEntry { public SystemTypes Room { get; init; } public int TotalPlayers { get; init; } public int NumDeadBodies { get; init; } public int NumImpostors { get; init; } [CompilerGenerated] private bool PrintMembers(StringBuilder builder) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) builder.Append("Room = "); SystemTypes room = Room; builder.Append(((object)(SystemTypes)(ref room)).ToString()); builder.Append(", TotalPlayers = "); builder.Append(TotalPlayers.ToString()); builder.Append(", NumDeadBodies = "); builder.Append(NumDeadBodies.ToString()); builder.Append(", NumImpostors = "); builder.Append(NumImpostors.ToString()); return true; } } public static SortedDictionary CalculateAdmin() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) SortedDictionary sortedDictionary = new SortedDictionary(); HashSet hashSet = new HashSet(15); Il2CppReferenceArray val = new Il2CppReferenceArray(45L); ContactFilter2D val2 = default(ContactFilter2D); val2.useLayerMask = true; val2.layerMask = LayerMask.op_Implicit(Constants.LivingPlayersOnlyMask); val2.useTriggers = true; ContactFilter2D val3 = val2; foreach (PlainShipRoom item in (Il2CppArrayBase)(object)ShipStatus.Instance.AllRooms) { SystemTypes roomId = item.RoomId; if ((int)roomId == 0 || (Object)(object)item.roomArea == (Object)null) { continue; } int num = item.roomArea.OverlapCollider(val3, val); int num2 = 0; int num3 = 0; int num4 = 0; for (int i = 0; i < num; i++) { Collider2D val4 = ((Il2CppArrayBase)(object)val)[i]; if (((Component)val4).CompareTag("DeadBody")) { DeadBody component = ((Component)val4).GetComponent(); if ((Object)(object)component != (Object)null && hashSet.Add(component.ParentId)) { num2++; num3++; PlayerControl playerById = Utils.GetPlayerById(component.ParentId); if (playerById != null && playerById.Is(Custom_Team.Impostor)) { num4++; } } } else { if (val4.isTrigger) { continue; } PlayerControl component2 = ((Component)val4).GetComponent(); if (component2.IsAlive() && hashSet.Add(component2.PlayerId)) { num2++; if (component2.Is(Custom_Team.Impostor)) { num4++; } } } } sortedDictionary[roomId] = new AdminEntry { Room = roomId, TotalPlayers = num2, NumDeadBodies = num3, NumImpostors = num4 }; } return sortedDictionary; } } public static class CustomSoundsManager { private static readonly string SOUNDS_PATH = Environment.CurrentDirectory.Replace("\\", "/") + "/BepInEx/resources/"; public static void RPCPlayCustomSound(this PlayerControl pc, string sound, bool force = false) { if (force || (((InnerNetClient)AmongUsClient.Instance).AmHost && pc.IsModClient())) { if ((Object)(object)pc == (Object)null || PlayerControl.LocalPlayer.PlayerId == pc.PlayerId) { Play(sound); return; } MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)108, (SendOption)1, pc.GetClientId()); val.Write(sound); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); } } public static void RPCPlayCustomSoundAll(string sound) { if (((InnerNetClient)AmongUsClient.Instance).AmHost) { MessageWriter val = ((InnerNetClient)AmongUsClient.Instance).StartRpcImmediately(((InnerNetObject)PlayerControl.LocalPlayer).NetId, (byte)108, (SendOption)1, -1); val.Write(sound); ((InnerNetClient)AmongUsClient.Instance).FinishRpcImmediately(val); Play(sound); } } public static void ReceiveRPC(MessageReader reader) { Play(reader.ReadString()); } public static void Play(string sound) { if (!Constants.ShouldPlaySfx() || !Main.EnableCustomSoundEffect.Value) { return; } string path = SOUNDS_PATH + sound + ".wav"; if (!Directory.Exists(SOUNDS_PATH)) { Directory.CreateDirectory(SOUNDS_PATH); } DirectoryInfo directoryInfo = new DirectoryInfo(SOUNDS_PATH); if ((directoryInfo.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden) { directoryInfo.Attributes = FileAttributes.Hidden; } if (!File.Exists(path)) { Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("TOHE.Resources.Sounds." + sound + ".wav"); if (manifestResourceStream == null) { Logger.Warn("Sound file missing:" + sound, "CustomSounds", escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomSounds.cs"); return; } FileStream fileStream = File.Create(path); manifestResourceStream.CopyTo(fileStream); fileStream.Close(); } StartPlay(path); Logger.Msg("play sound:" + sound, "CustomSounds", escapeCRLF: true, 56, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\CustomSounds.cs"); } [DllImport("winmm.dll")] private static extern bool PlaySound(string Filename, int Mod, int Flags); private static void StartPlay(string path) { PlaySound(path ?? "", 0, 1); } } public static class DoorsReset { public enum ResetModeList { AllOpen, AllClosed, RandomByDoor } private static bool isEnabled = false; private static ResetModeList mode; private static readonly LogHandler logger = Logger.Handler("DoorsReset"); private static DoorsSystemType DoorsSystem { get { ISystemType val = default(ISystemType); if (!ShipStatus.Instance.Systems.TryGetValue((SystemTypes)16, ref val)) { return null; } return ((Il2CppObjectBase)val).TryCast(); } } public static void Initialize() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (GameStates.IsHideNSeek) { isEnabled = false; return; } MapNames activeMapName = Utils.GetActiveMapName(); bool flag = (((int)activeMapName == 2 || activeMapName - 4 <= 1) ? true : false); if (!flag || Options.DisableCloseDoor.GetBool()) { isEnabled = false; return; } isEnabled = Options.ResetDoorsEveryTurns.GetBool(); mode = (ResetModeList)Options.DoorsResetMode.GetValue(); Logger.Info($"initialization: [ {isEnabled}, {mode} ]", "Reset Doors", escapeCRLF: true, 25, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DoorsReset.cs"); } public static void ResetDoors() { if (isEnabled && DoorsSystem != null) { Logger.Info("Reset", "Reset Doors", escapeCRLF: true, 35, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DoorsReset.cs"); switch (mode) { case ResetModeList.AllOpen: OpenAllDoors(); return; case ResetModeList.AllClosed: CloseAllDoors(); return; case ResetModeList.RandomByDoor: OpenOrCloseAllDoorsRandomly(); return; } Logger.Warn($"Invalid Reset Doors Mode: {mode}", "Reset Doors", escapeCRLF: true, 42, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DoorsReset.cs"); } } private static void OpenAllDoors() { foreach (OpenableDoor item in (Il2CppArrayBase)(object)ShipStatus.Instance.AllDoors) { SetDoorOpenState(item, isOpen: true); } DoorsSystem.IsDirty = true; } private static void CloseAllDoors() { foreach (OpenableDoor item in (Il2CppArrayBase)(object)ShipStatus.Instance.AllDoors) { SetDoorOpenState(item, isOpen: false); } DoorsSystem.IsDirty = true; } private static void OpenOrCloseAllDoorsRandomly() { foreach (OpenableDoor item in (Il2CppArrayBase)(object)ShipStatus.Instance.AllDoors) { bool isOpen = IRandom.Instance.Next(2) > 0; SetDoorOpenState(item, isOpen); } DoorsSystem.IsDirty = true; } private static void SetDoorOpenState(OpenableDoor door, bool isOpen) { if (IsValidDoor(door)) { ((SomeKindaDoor)door).SetDoorway(isOpen); } } private static bool IsValidDoor(OpenableDoor door) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 SystemTypes room = door.Room; bool flag = (((int)room == 18 || (int)room == 43) ? true : false); return !flag; } } public abstract class GameOptionsSender { public static readonly List AllSenders = new List(100) { new NormalGameOptionsSender() }; public abstract IGameOptions BasedGameOptions { get; } public abstract bool IsDirty { get; protected set; } public static void SendAllGameOptions() { AllSenders.RemoveAll((GameOptionsSender s) => !s.AmValid()); GameOptionsSender[] array = AllSenders.ToArray(); foreach (GameOptionsSender gameOptionsSender in array) { if (gameOptionsSender.IsDirty) { gameOptionsSender.SendGameOptions(); } gameOptionsSender.IsDirty = false; } } public virtual void SendGameOptions() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown IGameOptions val = BuildGameOptions(); GameModes val2 = (AprilFoolsMode.IsAprilFoolsModeToggledOn ? val.AprilFoolsOnMode : val.GameMode); MessageWriter val3 = MessageWriter.Get((SendOption)0); val3.Write(val.Version); val3.StartMessage((byte)0); val3.Write((byte)(int)val2); HideNSeekGameOptionsV08 casted2; if (((Il2CppObjectBase)(object)val).TryCast(out NormalGameOptionsV08 casted)) { NormalGameOptionsV08.Serialize(val3, casted); } else if (((Il2CppObjectBase)(object)val).TryCast(out casted2)) { HideNSeekGameOptionsV08.Serialize(val3, casted2); } else { val3.Recycle(); Logger.Error("Option Cast Failed", ToString(), escapeCRLF: true, 48, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameOptionsSender\\GameOptionsSender.cs"); } val3.EndMessage(); Il2CppStructArray val4 = new Il2CppStructArray((long)(val3.Length - 1)); Buffer.BlockCopy(((Il2CppObjectBase)val3.Buffer).Cast(), 1, ((Il2CppObjectBase)val4).Cast(), 0, val3.Length - 1); SendOptionsArray(val4); val3.Recycle(); } public virtual void SendOptionsArray(Il2CppStructArray optionArray) { try { byte b = 0; foreach (GameLogicComponent item in GameManager.Instance.LogicComponents.GetFastEnumerator()) { if (((Il2CppObjectBase)(object)item).TryCast(out LogicOptions _)) { SendOptionsArray(optionArray, b, -1); } b++; } } catch (Exception ex) { Logger.Fatal(ex.ToString(), "GameOptionsSender.SendOptionsArray", escapeCRLF: true, 76, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameOptionsSender\\GameOptionsSender.cs"); } } protected virtual void SendOptionsArray(Il2CppStructArray optionArray, byte LogicOptionsIndex, int targetClientId) { MessageWriter val = MessageWriter.Get((SendOption)1); val.StartMessage((targetClientId == -1) ? Tags.GameData : Tags.GameDataTo); val.Write(((InnerNetClient)AmongUsClient.Instance).GameId); if (targetClientId != -1) { val.WritePacked(targetClientId); } val.StartMessage((byte)1); val.WritePacked(((InnerNetObject)GameManager.Instance).NetId); val.StartMessage(LogicOptionsIndex); val.WriteBytesAndSize(optionArray); val.EndMessage(); val.EndMessage(); val.EndMessage(); ((InnerNetClient)AmongUsClient.Instance).SendOrDisconnect(val); val.Recycle(); } public abstract IGameOptions BuildGameOptions(); public virtual bool AmValid() { return true; } } public class NormalGameOptionsSender : GameOptionsSender { private LogicOptions _logicOptions; public override IGameOptions BasedGameOptions => GameOptionsManager.Instance.CurrentGameOptions; public override bool IsDirty { get { try { if (_logicOptions == null || !GameManager.Instance.LogicComponents.Contains((GameLogicComponent)(object)_logicOptions)) { GameManager instance = GameManager.Instance; foreach (GameLogicComponent item in (instance != null) ? instance.LogicComponents.GetFastEnumerator() : null) { if (((Il2CppObjectBase)(object)item).TryCast(out LogicOptions casted)) { _logicOptions = casted; } } } return _logicOptions != null && ((GameLogicComponent)_logicOptions).IsDirty; } catch (Exception value) { Logger.Warn($"_logicOptions == null {_logicOptions == null} --- GameManager.Instance.LogicComponents == null {GameManager.Instance.LogicComponents == null} - Error: {value}", "NormalGameOptionsSender.IsDirty.Get", escapeCRLF: true, 28, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameOptionsSender\\NormalGameOptionsSender.cs"); return _logicOptions != null && ((GameLogicComponent)_logicOptions).IsDirty; } } protected set { try { LogicOptions logicOptions = _logicOptions; if (logicOptions != null) { ((GameLogicComponent)logicOptions).ClearDirtyFlag(); } } catch (Exception ex) { Logger.Warn(ex.ToString(), "NormalGameOptionsSender.IsDirty.ProtectedSet", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\GameOptionsSender\\NormalGameOptionsSender.cs"); } } } public override IGameOptions BuildGameOptions() { return BasedGameOptions; } } public class PlayerGameOptionsSender : GameOptionsSender { public PlayerControl player; public override IGameOptions BasedGameOptions { get { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!GameStates.IsNormalGame) { return Main.RealOptionsData.Restore(((Il2CppObjectBase)new HideNSeekGameOptionsV08(((Il2CppObjectBase)new UnityLogger()).Cast())).Cast()); } return Main.RealOptionsData.Restore(((Il2CppObjectBase)new NormalGameOptionsV08(((Il2CppObjectBase)new UnityLogger()).Cast())).Cast()); } } public override bool IsDirty { get; protected set; } public PlayerGameOptionsSender(PlayerControl player) { this.player = player; base..ctor(); } public static void SetDirty(PlayerControl player) { SetDirty(player.PlayerId); } public static void SetDirty(byte playerId) { PlayerGameOptionsSender[] array = (from sender in GameOptionsSender.AllSenders.OfType() where sender.player.PlayerId == playerId select sender).ToArray(); int num = 0; if (num < array.Length) { array[num].SetDirty(); } } public static void SetDirtyToAll() { PlayerGameOptionsSender[] array = GameOptionsSender.AllSenders.OfType().ToArray(); for (int i = 0; i < array.Length; i++) { array[i].SetDirty(); } } public void SetDirty() { IsDirty = true; } public override void SendGameOptions() { if (((InnerNetObject)player).AmOwner) { IGameOptions val = BuildGameOptions(); foreach (GameLogicComponent item in GameManager.Instance.LogicComponents.GetFastEnumerator()) { if (((Il2CppObjectBase)(object)item).TryCast(out LogicOptions casted)) { casted.SetGameOptions(val); } } GameOptionsManager.Instance.CurrentGameOptions = val; } else { base.SendGameOptions(); } } public override void SendOptionsArray(Il2CppStructArray optionArray) { byte b = 0; foreach (GameLogicComponent item in GameManager.Instance.LogicComponents.GetFastEnumerator()) { if (((Il2CppObjectBase)(object)item).TryCast(out LogicOptions _)) { SendOptionsArray(optionArray, b, player.GetClientId()); } b++; } } public static void RemoveSender(PlayerControl player) { PlayerGameOptionsSender playerGameOptionsSender = GameOptionsSender.AllSenders.OfType().FirstOrDefault((PlayerGameOptionsSender sender) => sender.player.PlayerId == player.PlayerId); if (playerGameOptionsSender != null) { playerGameOptionsSender.player = null; GameOptionsSender.AllSenders.Remove(playerGameOptionsSender); } } public override IGameOptions BuildGameOptions() { if (Main.RealOptionsData == null) { Main.RealOptionsData = new OptionBackupData(GameOptionsManager.Instance.CurrentGameOptions); } IGameOptions opt = BasedGameOptions; if (GameStates.IsNormalGame) { AURoleOptions.SetOpt(opt); } else if (GameStates.IsHideNSeek) { return opt; } PlayerState playerState = Main.PlayerStates[player.PlayerId]; opt.BlackOut(playerState.IsBlackOut); CustomRoles customRole = player.GetCustomRole(); if (Options.CurrentGameMode == CustomGameMode.FFA) { if (FFAManager.FFALowerVisionList.ContainsKey(player.PlayerId)) { opt.SetVision(HasImpVision: true); opt.SetFloat((FloatOptionNames)4, FFAManager.FFA_LowerVision.GetFloat()); opt.SetFloat((FloatOptionNames)3, FFAManager.FFA_LowerVision.GetFloat()); } else { opt.SetVision(HasImpVision: true); opt.SetFloat((FloatOptionNames)4, 1.25f); opt.SetFloat((FloatOptionNames)3, 1.25f); } } if (player.Is(Custom_Team.Impostor)) { AURoleOptions.ShapeshifterCooldown = Options.DefaultShapeshiftCooldown.GetFloat(); opt.SetVision(HasImpVision: true); } if (customRole.IsGhostRole()) { AURoleOptions.GuardianAngelCooldown = Options.DefaultAngelCooldown.GetFloat(); } player.BuildCustomGameOptions(ref opt); AURoleOptions.EngineerCooldown = Mathf.Max(0.01f, AURoleOptions.EngineerCooldown); if (Main.AllPlayerKillCooldown.TryGetValue(player.PlayerId, out var value)) { AURoleOptions.KillCooldown = Mathf.Max(0.01f, value); } if (Main.AllPlayerSpeed.TryGetValue(player.PlayerId, out var value2)) { AURoleOptions.PlayerSpeedMod = Mathf.Clamp(value2, 0.0001f, 3f); } playerState.taskState.hasTasks = Utils.HasTasks(player.Data, ForRecompute: false); if (Options.GhostCanSeeOtherVotes.GetBool() && player.Data.IsDead) { opt.SetBool((BoolOptionNames)4, false); } if (Options.AdditionalEmergencyCooldown.GetBool() && Options.AdditionalEmergencyCooldownThreshold.GetInt() <= Utils.AllAlivePlayersCount) { opt.SetInt((Int32OptionNames)4, Options.AdditionalEmergencyCooldownTime.GetInt()); } if (Options.SyncButtonMode.GetBool() && Options.SyncedButtonCount.GetValue() <= Options.UsedButtonCount) { opt.SetInt((Int32OptionNames)4, 3600); } MeetingTimeManager.ApplyGameOptions(opt); AURoleOptions.ShapeshifterCooldown = Mathf.Max(1f, AURoleOptions.ShapeshifterCooldown); AURoleOptions.ProtectionDurationSeconds = 0f; AURoleOptions.ImpostorsCanSeeProtect = false; return opt; } public override bool AmValid() { if (base.AmValid() && (Object)(object)player != (Object)null && !player.Data.Disconnected) { return Main.RealOptionsData != null; } return false; } } public static class KillTimerManager { public static readonly Dictionary AllKillTimers = new Dictionary(); public static void Initializate() { AllKillTimers.Clear(); } public static float GetKillTimer(this PlayerControl pc) { if (!((InnerNetObject)pc).AmOwner) { return AllKillTimers[pc.PlayerId]; } return pc.killTimer; } public static float GetKillTimer(this byte playerId) { return AllKillTimers[playerId]; } public static void SetKillTimer(this PlayerControl pc, bool half = false, float CD = -1f) { float num; if (Math.Abs(CD - -1f) < 0.5f) { num = Main.AllPlayerKillCooldown.GetValueOrDefault(pc.PlayerId, 0f); if (half) { num /= 2f; } } else { num = CD; } if (!AllKillTimers.TryGetValue(pc.PlayerId, out var value) || !(value > num)) { AllKillTimers[pc.PlayerId] = num; } } public static void FixedUpdate(PlayerControl player) { if (!GameStates.IsMeeting && !player.inVent && !player.MyPhysics.Animations.IsPlayingEnterVentAnimation()) { byte playerId = player.PlayerId; if (!AllKillTimers.TryAdd(playerId, 10f) && player.GetKillTimer() > 0f) { AllKillTimers[playerId] -= Time.fixedDeltaTime; } } } } public interface ILogHandler { void Info(string text); void Warn(string text); void Error(string text); void Fatal(string text); void Msg(string text); void Exception(Exception ex); } internal class LogHandler : ILogHandler { public string Tag { get; } public LogHandler(string tag) { Tag = tag; base..ctor(); } public void Info(string text) { Logger.Info(text, Tag, escapeCRLF: true, 10, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } public void Warn(string text) { Logger.Warn(text, Tag, escapeCRLF: true, 12, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } public void Error(string text) { Logger.Error(text, Tag, escapeCRLF: true, 14, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } public void Fatal(string text) { Logger.Fatal(text, Tag, escapeCRLF: true, 16, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } public void Msg(string text) { Logger.Msg(text, Tag, escapeCRLF: true, 18, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } public void Exception(Exception ex) { Logger.Exception(ex, Tag, 20, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\LogHandler\\LogHandler.cs"); } } public class MeetingTimeManager { private static int DiscussionTime; private static int VotingTime; private static int DefaultDiscussionTime; private static int DefaultVotingTime; public static void Init() { DefaultDiscussionTime = Main.RealOptionsData.GetInt((Int32OptionNames)5); DefaultVotingTime = Main.RealOptionsData.GetInt((Int32OptionNames)6); Logger.Info($"DefaultDiscussionTime:{DefaultDiscussionTime}, DefaultVotingTime{DefaultVotingTime}", "MeetingTimeManager.Init", escapeCRLF: true, 19, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\MeetingTimeManager.cs"); ResetMeetingTime(); } public static void ApplyGameOptions(IGameOptions opt) { opt.SetInt((Int32OptionNames)5, DiscussionTime); opt.SetInt((Int32OptionNames)6, VotingTime); } private static void ResetMeetingTime() { DiscussionTime = DefaultDiscussionTime; VotingTime = DefaultVotingTime; } public static void OnReportDeadBody() { if (Options.AllAliveMeeting.GetBool() && Utils.IsAllAlive) { DiscussionTime = 0; VotingTime = Options.AllAliveMeetingTime.GetInt(); Logger.Info($"DiscussionTime:{DiscussionTime}, VotingTime{VotingTime}", "MeetingTimeManager.OnReportDeadBody", escapeCRLF: true, 38, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\MeetingTimeManager.cs"); return; } ResetMeetingTime(); int num = 0; int min = 0; int min2 = 0; int max = 300; if (TimeThief.HasEnabled) { min = TimeThief.LowerLimitVotingTime.GetInt(); num += TimeThief.TotalDecreasedMeetingTime(); } if (TimeManager.HasEnabled) { min2 = TimeManager.MadMinMeetingTimeLimit.GetInt(); max = TimeManager.MeetingTimeLimit.GetInt(); num += TimeManager.TotalIncreasedMeetingTime(); } int num2 = DiscussionTime + VotingTime; if (TimeManager.HasEnabled) { num = Math.Clamp(num2 + num, min2, max) - num2; } if (TimeThief.HasEnabled) { num = Math.Clamp(num2 + num, min, max) - num2; } if (!TimeManager.HasEnabled && !TimeThief.HasEnabled) { num = Math.Clamp(num2 + num, min, max) - num2; } if (num >= 0) { VotingTime += num; } else { DiscussionTime += num; if (DiscussionTime < 0) { VotingTime += DiscussionTime; DiscussionTime = 0; } } Logger.Info($"DiscussionTime:{DiscussionTime}, VotingTime{VotingTime}", "MeetingTimeManager.OnReportDeadBody", escapeCRLF: true, 77, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\MeetingTimeManager.cs"); } } public static class OptionSaver { public class SerializableOptionsData { public int Version { get; init; } public Dictionary SingleOptions { get; init; } public Dictionary PresetOptions { get; init; } } private static readonly DirectoryInfo SaveDataDirectoryInfo = new DirectoryInfo("./TOHE-DATA/SaveData/"); private static readonly FileInfo OptionSaverFileInfo = new FileInfo(SaveDataDirectoryInfo.FullName + "/Options.json"); public static readonly int Version = 1; public static void Initialize() { if (!SaveDataDirectoryInfo.Exists) { SaveDataDirectoryInfo.Create(); SaveDataDirectoryInfo.Attributes |= FileAttributes.Hidden; } if (!OptionSaverFileInfo.Exists) { OptionSaverFileInfo.Create().Dispose(); } } private static SerializableOptionsData GenerateOptionsData() { Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); foreach (OptionItem allOption in OptionItem.AllOptions) { if (allOption.IsSingleValue) { if (!dictionary.TryAdd(allOption.Id, allOption.SingleValue)) { Logger.Warn($"Duplicate SingleOption ID: {allOption.Id}", "Option Saver", escapeCRLF: true, 35, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionSaver.cs"); } } else if (!dictionary2.TryAdd(allOption.Id, allOption.AllValues)) { Logger.Warn($"Duplicate preset option ID: {allOption.Id}", "Option Saver", escapeCRLF: true, 40, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionSaver.cs"); } } return new SerializableOptionsData { Version = Version, SingleOptions = dictionary, PresetOptions = dictionary2 }; } private static void LoadOptionsData(SerializableOptionsData serializableOptionsData) { if (serializableOptionsData.Version != Version) { Logger.Info($"Loaded option version {serializableOptionsData.Version} does not match current version {Version}, overwriting with default value", "Option Saver", escapeCRLF: true, 56, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionSaver.cs"); Save(); return; } Dictionary singleOptions = serializableOptionsData.SingleOptions; Dictionary presetOptions = serializableOptionsData.PresetOptions; foreach (KeyValuePair item in singleOptions) { int key = item.Key; int value = item.Value; if (OptionItem.FastOptions.TryGetValue(key, out var value2)) { value2.SetValue(value, doSave: false, doSync: true); } } foreach (KeyValuePair item2 in presetOptions) { int key2 = item2.Key; int[] value3 = item2.Value; if (OptionItem.FastOptions.TryGetValue(key2, out var value4)) { value4.SetAllValues(value3); } } } public static void Save() { if (!((Object)(object)AmongUsClient.Instance != (Object)null) || ((InnerNetClient)AmongUsClient.Instance).AmHost) { string contents = JsonSerializer.Serialize(GenerateOptionsData(), new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(OptionSaverFileInfo.FullName, contents); } } public static void Load() { string text = File.ReadAllText(OptionSaverFileInfo.FullName); if (text.Length <= 0) { Logger.Info("Save default value as option data is empty", "Option Saver", escapeCRLF: true, 96, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\OptionSaver.cs"); Save(); } else { LoadOptionsData(JsonSerializer.Deserialize(text)); } } } public static class OutfitManager { public static void ResetPlayerOutfit(this PlayerControl player, PlayerOutfit Outfit = null, bool force = false) { if (Outfit == null) { Outfit = Main.PlayerStates[player.PlayerId].NormalOutfit; } if (player.CheckCamoflague() && !force) { Main.LateOutfits[player.PlayerId] = Setoutfit; return; } Main.LateOutfits.Remove(player.PlayerId); Setoutfit(); void Setoutfit() { //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Invalid comparison between Unknown and I4 //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) CustomRpcSender customRpcSender = CustomRpcSender.Create("Reset PlayerOufit for 『" + player.Data.PlayerName + "』", (SendOption)0); player.SetName(Outfit.PlayerName); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 6).Write(((InnerNetObject)player.Data).NetId).Write(Outfit.PlayerName) .EndRpc(); Main.AllPlayerNames[player.PlayerId] = Outfit.PlayerName; player.SetColor(Outfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 8).Write(((InnerNetObject)player.Data).NetId).Write((byte)Outfit.ColorId) .EndRpc(); player.SetHat(Outfit.HatId, Outfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 39).Write(Outfit.HatId).Write(player.GetNextRpcSequenceId((RpcCalls)39)) .EndRpc(); player.SetSkin(Outfit.SkinId, Outfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 40).Write(Outfit.SkinId).Write(player.GetNextRpcSequenceId((RpcCalls)40)) .EndRpc(); player.SetVisor(Outfit.VisorId, Outfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 42).Write(Outfit.VisorId).Write(player.GetNextRpcSequenceId((RpcCalls)42)) .EndRpc(); player.SetPet(Outfit.PetId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 41).Write(Outfit.PetId).Write(player.GetNextRpcSequenceId((RpcCalls)41)) .EndRpc(); player.SetNamePlate(Outfit.NamePlateId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 43).Write(Outfit.NamePlateId).Write(player.GetNextRpcSequenceId((RpcCalls)43)) .EndRpc(); customRpcSender.SendMessage(); PlayerOutfitType val = (PlayerOutfitType)((int)player.CurrentOutfitType == 1); player.Data.SetOutfit(val, Outfit); Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { ((InnerNetObject)enumerator.Current).SetDirtyBit(uint.MaxValue); } } } public static void SetNewOutfit(this PlayerControl player, PlayerOutfit newOutfit, bool setName = true, bool setNamePlate = true, uint newLevel = 500u) { CustomRpcSender customRpcSender = CustomRpcSender.Create("SetOutfit(" + player.Data.PlayerName + ")", (SendOption)0); if (setName) { player.SetName(newOutfit.PlayerName); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 6).Write(((InnerNetObject)player.Data).NetId).Write(newOutfit.PlayerName) .EndRpc(); Main.AllPlayerNames[player.PlayerId] = newOutfit.PlayerName; } player.SetColor(newOutfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 8).Write(((InnerNetObject)player.Data).NetId).Write((byte)newOutfit.ColorId) .EndRpc(); player.SetHat(newOutfit.HatId, newOutfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 39).Write(newOutfit.HatId).Write(player.GetNextRpcSequenceId((RpcCalls)39)) .EndRpc(); player.SetSkin(newOutfit.SkinId, newOutfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 40).Write(newOutfit.SkinId).Write(player.GetNextRpcSequenceId((RpcCalls)40)) .EndRpc(); player.SetVisor(newOutfit.VisorId, newOutfit.ColorId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 42).Write(newOutfit.VisorId).Write(player.GetNextRpcSequenceId((RpcCalls)42)) .EndRpc(); player.SetPet(newOutfit.PetId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 41).Write(newOutfit.PetId).Write(player.GetNextRpcSequenceId((RpcCalls)41)) .EndRpc(); if (setNamePlate) { player.SetNamePlate(newOutfit.NamePlateId); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 43).Write(newOutfit.NamePlateId).Write(player.GetNextRpcSequenceId((RpcCalls)43)) .EndRpc(); } if (newLevel != 500) { player.SetLevel(newLevel); customRpcSender.AutoStartRpc(((InnerNetObject)player).NetId, 38).WritePacked(newLevel).EndRpc(); } customRpcSender.SendMessage(); } } public static class RehostManager { public static GameObject RCountdownText; public static TextMeshPro RCountdownTextText; public static bool IsAutoRehostDone; public static bool ShouldPublic; public static void OnDisconnectInternal(DisconnectReasons reason) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!Main.AutoRehost.Value || !DebugModeManager.AmDebugger || (int)((InnerNetClient)AmongUsClient.Instance).mode != 2) { return; } ShouldPublic = ((InnerNetClient)AmongUsClient.Instance).IsGamePublic; if ((int)reason != 210 && (int)reason != 12 && (int)reason != 0) { new LateTask(delegate { IsAutoRehostDone = false; BeginAutoRehostCountdown(Options.AutoPlayAgainCountdown.GetInt()); }, 1f, "Begin Auto Rehost Countdown"); } } private static void BeginAutoRehostCountdown(int seconds) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if ((int)((InnerNetClient)AmongUsClient.Instance).mode != 0 || !Main.AutoRehost.Value || !DestroyableSingleton.Instance.loginFlowFinished || IsAutoRehostDone) { IsAutoRehostDone = true; if (((Behaviour)RCountdownTextText).isActiveAndEnabled) { ((TMP_Text)RCountdownTextText).text = string.Format(Translator.GetString("CancelStartCountDown")); } Logger.Info("Auto Rehost Cancelled!", "Rehost Manager", escapeCRLF: true, 41, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RehostManager.cs"); return; } if (seconds == Options.AutoPlayAgainCountdown.GetInt()) { RCountdownText = new GameObject("RCountdownText"); RCountdownText.transform.position = new Vector3(0f, -2.5f, 30f); RCountdownTextText = RCountdownText.AddComponent(); ((TMP_Text)RCountdownTextText).text = string.Format(Translator.GetString("CountdownText"), seconds); ((TMP_Text)RCountdownTextText).alignment = (TextAlignmentOptions)514; ((TMP_Text)RCountdownTextText).fontSize = 3f; } else { ((TMP_Text)RCountdownTextText).text = string.Format(Translator.GetString("CountdownText"), seconds); } if (seconds == 0) { DestroyableSingleton.Instance.CreateGame((GameModes)1); Logger.Info("Auto Rehost!", "Rehost Manager", escapeCRLF: true, 63, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\RehostManager.cs"); } else { new LateTask(delegate { BeginAutoRehostCountdown(seconds - 1); }, 1f, "Begin Auto Rehost Countdown"); } } } internal static class RoleBasisChanger { [HarmonyPatch(typeof(InnerNetClient), "Spawn")] public static class InnerNetClientSpawnPatch { public static bool Prefix(InnerNetClient __instance, [HarmonyArgument(0)] InnerNetObject netObjParent, [HarmonyArgument(1)] int ownerId, [HarmonyArgument(2)] SpawnFlags flags) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!IsChangeInProgress) { return true; } ownerId = ((ownerId == -3) ? __instance.ClientId : ownerId); MessageWriter val = ((Il2CppArrayBase)(object)__instance.Streams)[0]; __instance.WriteSpawnMessage(netObjParent, ownerId, flags, val); return false; } } [HarmonyPatch(typeof(InnerNetClient), "Despawn")] public static class InnerNetClientDespawnPatch { public static bool Prefix(InnerNetClient __instance, [HarmonyArgument(0)] InnerNetObject objToDespawn) { if (!IsChangeInProgress) { return true; } MessageWriter obj = ((Il2CppArrayBase)(object)__instance.Streams)[0]; obj.StartMessage((byte)5); obj.WritePacked(objToDespawn.NetId); obj.EndMessage(); __instance.RemoveNetObject(objToDespawn); return false; } } public static bool IsChangeInProgress; public static bool SkipTasksAfterAssignRole; public static void ChangeRoleBasis(this PlayerControl player, RoleTypes targetVNRole) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) if (!((InnerNetClient)AmongUsClient.Instance).AmHost) { return; } if (((InnerNetObject)(object)player).OwnedByHost()) { DestroyableSingleton.Instance.SetRole(player, targetVNRole); player.SyncSettings(); Utils.NotifyRoles(player); Utils.NotifyRoles(null, player); DestroyableSingleton.Instance.SetHudActive(player, player.Data.Role, !GameStates.IsMeeting); return; } IsChangeInProgress = true; SkipTasksAfterAssignRole = true; Vector2 truePosition = player.GetTruePosition(); PlayerControl val = Object.Instantiate(AmongUsClient.Instance.PlayerPrefab, Vector2.op_Implicit(truePosition), Quaternion.identity); val.PlayerId = player.PlayerId; val.FriendCode = player.FriendCode; val.Puid = player.Puid; ClientData client = player.GetClient(); player.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); ((InnerNetClient)AmongUsClient.Instance).Despawn((InnerNetObject)(object)player); ((InnerNetClient)AmongUsClient.Instance).Spawn((InnerNetObject)(object)val, ((InnerNetObject)player).OwnerId, (SpawnFlags)0); client.Character = val; ((InnerNetObject)val).OwnerId = ((InnerNetObject)player).OwnerId; client.InScene = true; client.IsReady = true; val.MyPhysics.ResetMoveState(true); GameData.Instance.RemovePlayer(player.PlayerId); GameData.Instance.AddPlayer(val, val.GetClient()); val.RpcSetRole(targetVNRole, true); Enumerator enumerator = GameData.Instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { ((InnerNetObject)enumerator.Current).SetDirtyBit(uint.MaxValue); } val.ReactorFlash(0.2f); val.RpcTeleport(truePosition); new LateTask(delegate { IsChangeInProgress = false; }, 5f, "Desync Role Basis"); new LateTask(delegate { SkipTasksAfterAssignRole = false; }, 8f, "Wait End Intro", shoudLog: false); } } public static class VersionChecker { private static bool Ischecked = false; public static bool IsSupported { get; private set; } = true; public static void Check() { if (!Ischecked) { Version version = Version.Parse(Application.version); Logger.Info($" {version}", "Among Us Version Check", escapeCRLF: true, 17, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\VersionChecker.cs"); Version version2 = Version.Parse("2024.8.13"); Logger.Info($" {version2}", "Supported Version Check", escapeCRLF: true, 20, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\VersionChecker.cs"); IsSupported = version >= version2; Logger.Info($" {IsSupported}", "Version Is Supported?", escapeCRLF: true, 23, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\VersionChecker.cs"); if (!IsSupported) { ErrorText.Instance.AddError(ErrorCode.UnsupportedVersion); } Ischecked = true; } } } } namespace TOHE.Modules.Extensions { public static class IGameManagerEx { public static void Set(this BoolOptionNames name, bool value, IGameOptions opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetBool(name, value); } public static void Set(this BoolOptionNames name, bool value, NormalGameOptionsV08 opt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) if ((int)name != 2) { opt.SetBool(name, value); } } public static void Set(this BoolOptionNames name, bool value, HideNSeekGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetBool(name, value); } public static void Set(this Int32OptionNames name, int value, IGameOptions opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetInt(name, value); } public static void Set(this Int32OptionNames name, int value, NormalGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetInt(name, value); } public static void Set(this Int32OptionNames name, int value, HideNSeekGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetInt(name, value); } public static void Set(this FloatOptionNames name, float value, IGameOptions opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetFloat(name, value); } public static void Set(this FloatOptionNames name, float value, NormalGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetFloat(name, value); } public static void Set(this FloatOptionNames name, float value, HideNSeekGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetFloat(name, value); } public static void Set(this ByteOptionNames name, byte value, IGameOptions opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetByte(name, value); } public static void Set(this ByteOptionNames name, byte value, NormalGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetByte(name, value); } public static void Set(this ByteOptionNames name, byte value, HideNSeekGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetByte(name, value); } public static void Set(this UInt32OptionNames name, uint value, IGameOptions opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetUInt(name, value); } public static void Set(this UInt32OptionNames name, uint value, NormalGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetUInt(name, value); } public static void Set(this UInt32OptionNames name, uint value, HideNSeekGameOptionsV08 opt) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) opt.SetUInt(name, value); } } } namespace TOHE.Modules.DelayNetworkDataSpawn { [HarmonyPatch(typeof(InnerNetClient))] public class InnerNetClientPatch { private static byte timer; [HarmonyPatch(typeof(InnerNetClient), "SendInitialData")] [HarmonyPrefix] public static bool SendInitialDataPrefix(InnerNetClient __instance, int clientId) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!Constants.IsVersionModded() || (int)__instance.NetworkMode != 1) { return true; } MessageWriter val = MessageWriter.Get((SendOption)1); val.StartMessage((byte)6); val.Write(__instance.GameId); val.WritePacked(clientId); lock (__instance.allObjects) { HashSet hashSet = new HashSet(); for (int i = 0; i < __instance.allObjects.Count; i++) { InnerNetObject val2 = __instance.allObjects[i]; if (Object.op_Implicit((Object)(object)val2) && (val2.OwnerId != -4 || __instance.AmModdedHost) && hashSet.Add(((Component)val2).gameObject)) { GameManager val3 = (GameManager)(object)((val2 is GameManager) ? val2 : null); if ((Object)(object)val3 != (Object)null) { __instance.SendGameManager(clientId, val3); } else if (!(val2 is NetworkedPlayerInfo)) { __instance.WriteSpawnMessage(val2, val2.OwnerId, val2.SpawnFlags, val); } } } val.EndMessage(); __instance.SendOrDisconnect(val); val.Recycle(); } DelaySpawnPlayerInfo(__instance, clientId); return false; } private static void DelaySpawnPlayerInfo(InnerNetClient __instance, int clientId) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) List list = ((IEnumerable)GameData.Instance.AllPlayers.ToArray()).ToList(); while (list.Count > 0) { List list2 = list.Take(5).ToList(); MessageWriter val = MessageWriter.Get((SendOption)1); val.StartMessage((byte)6); val.Write(__instance.GameId); val.WritePacked(clientId); foreach (NetworkedPlayerInfo item in list2) { if (val.Length > 1600) { break; } if ((Object)(object)item != (Object)null && item.ClientId != clientId && !item.Disconnected) { __instance.WriteSpawnMessage((InnerNetObject)(object)item, ((InnerNetObject)item).OwnerId, ((InnerNetObject)item).SpawnFlags, val); } list.Remove(item); } val.EndMessage(); __instance.SendOrDisconnect(val); val.Recycle(); } } [HarmonyPatch(typeof(InnerNetClient), "SendAllStreamedObjects")] [HarmonyPrefix] public static bool SendAllStreamedObjectsPrefix(InnerNetClient __instance, ref bool __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected I4, but got Unknown if (!Constants.IsVersionModded() || (int)__instance.NetworkMode != 1) { return true; } __result = false; lock (__instance.allObjects) { for (int i = 0; i < __instance.allObjects.Count; i++) { InnerNetObject val = __instance.allObjects[i]; if (!Object.op_Implicit((Object)(object)val) || val is NetworkedPlayerInfo || !val.IsDirty || (!val.AmOwner && (val.OwnerId != -2 || !__instance.AmHost))) { continue; } MessageWriter val2 = ((Il2CppArrayBase)(object)__instance.Streams)[(int)val.sendMode]; val2.StartMessage((byte)1); val2.WritePacked(val.NetId); try { if (val.Serialize(val2, false)) { val2.EndMessage(); } else { val2.CancelMessage(); } if (val.Chunked && val.IsDirty) { __result = true; } } catch (Exception ex) { Logger.Exception(ex, "SendAllStreamedObjectsPrefix", 117, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DelayNetworkedData.cs"); val2.CancelMessage(); } } } for (int j = 0; j < ((Il2CppArrayBase)(object)__instance.Streams).Length; j++) { MessageWriter val3 = ((Il2CppArrayBase)(object)__instance.Streams)[j]; if (val3.HasBytes(7)) { val3.EndMessage(); __instance.SendOrDisconnect(val3); val3.Clear((SendOption)(byte)j); val3.StartMessage((byte)5); val3.Write(__instance.GameId); } } return false; } [HarmonyPatch(typeof(InnerNetClient), "FixedUpdate")] [HarmonyPostfix] public static void FixedUpdatePostfix(InnerNetClient __instance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 if (!Constants.IsVersionModded() || (int)__instance.NetworkMode != 1 || !__instance.AmHost || __instance.Streams == null) { return; } if (timer == 0) { timer = 1; return; } NetworkedPlayerInfo val = ((IEnumerable)GameData.Instance.AllPlayers.ToArray()).FirstOrDefault((Func)((NetworkedPlayerInfo x) => ((InnerNetObject)x).IsDirty)); if (!((Object)(object)val != (Object)null)) { return; } timer = 0; MessageWriter val2 = MessageWriter.Get((SendOption)1); val2.StartMessage((byte)5); val2.Write(__instance.GameId); val2.StartMessage((byte)1); val2.WritePacked(((InnerNetObject)val).NetId); try { if (((InnerNetObject)val).Serialize(val2, false)) { val2.EndMessage(); val2.EndMessage(); __instance.SendOrDisconnect(val2); val2.Recycle(); } else { val2.CancelMessage(); ((InnerNetObject)val).ClearDirtyBits(); } } catch (Exception ex) { Logger.Exception(ex, "FixedUpdatePostfix", 180, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\DelayNetworkedData.cs"); val2.CancelMessage(); ((InnerNetObject)val).ClearDirtyBits(); } } } [HarmonyPatch(typeof(GameData), "DirtyAllData")] internal class DirtyAllDataPatch { public static bool Prefix() { return false; } } } namespace TOHE.Modules.ChatManager { public class ChatManager { public static bool cancel = false; private static List> chatHistory = new List>(); private static Dictionary LastSystemChatMsg = new Dictionary(); private const int maxHistorySize = 20; public static List ChatSentBySystem = new List(); public static void ResetHistory() { chatHistory = new List>(); LastSystemChatMsg = new Dictionary(); } public static void ClearLastSysMsg() { LastSystemChatMsg.Clear(); } public static void AddSystemChatHistory(byte playerId, string msg) { LastSystemChatMsg[playerId] = msg; } public static bool CheckCommond(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg == "/" + text) { return true; } } else if (msg.StartsWith("/" + text)) { msg = msg.Replace("/" + text, string.Empty); return true; } } return false; } public static bool CheckName(ref string msg, string command, bool exact = true) { string[] array = command.Split('|'); foreach (string text in array) { if (exact) { if (msg.Contains(text)) { return true; } continue; } int num = msg.IndexOf(text); if (num != -1) { msg = msg.Remove(num, text.Length); return true; } } return false; } private static string GetTextHash(string text) { using SHA256 sHA = SHA256.Create(); string text2 = BitConverter.ToString(sHA.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "").ToLower(); return string.Concat(text2.AsSpan(0, 5), text2.AsSpan(text2.Length - 4)); } public static void AddToHostMessage(string text) { if (text != "") { ChatSentBySystem.Add(GetTextHash(text)); } } public static void SendMessage(PlayerControl player, string message) { int num = 0; string msg = message; player.GetNameWithRole(); message = message.ToLower().TrimStart().TrimEnd(); if (GameStates.IsInGame) { num = 3; } if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id|編號|玩家編號")) { num = 1; } else if (CheckCommond(ref msg, "shoot|guess|bet|st|gs|bt|猜|赌|賭|sp|jj|tl|trial|审判|判|审|審判|審|compare|cmp|比较|比較|duel|sw|swap|st|换票|换|換票|換|finish|结束|结束会议|結束|結束會議|reveal|展示", exact: false)) { num = 2; } else if (ChatSentBySystem.Contains(GetTextHash(msg))) { num = 5; } if ((num == 1 || Blackmailer.CheckBlackmaile(player)) && player.IsAlive()) { Logger.Info("包含特殊信息,不记录", "ChatManager", escapeCRLF: true, 108, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ChatManager.cs"); message = msg; cancel = true; return; } switch (num) { case 2: Logger.Info("指令" + msg + ",不记录", "ChatManager", escapeCRLF: true, 114, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ChatManager.cs"); message = msg; cancel = false; break; case 4: Logger.Info("指令" + msg + ",不记录", "ChatManager", escapeCRLF: true, 120, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ChatManager.cs"); message = msg; SendPreviousMessagesToAll(); break; case 5: Logger.Info("system message" + msg + ",不记录", "ChatManager", escapeCRLF: true, 126, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ChatManager.cs"); message = msg; cancel = true; break; case 3: if (GameStates.IsExilling) { if (Options.HideExileChat.GetBool()) { Logger.Info("Message sent in exiling screen, spamming the chat", "ChatManager", escapeCRLF: true, 136, "C:\\Users\\fadee\\Desktop\\Моды\\0xDrMoe\\TownofHost-Enhanced\\Modules\\ChatManager.cs"); new LateTask(SendPreviousMessagesToAll, 0.3f, "Spamming the chat"); } } else if (player.IsAlive()) { message = msg; Dictionary item = new Dictionary { { player.PlayerId, message } }; chatHistory.Add(item); if (chatHistory.Count > 20) { chatHistory.RemoveAt(0); } cancel = false; } break; } } public static void SendPreviousMessagesToAll() { if (!((InnerNetClient)AmongUsClient.Instance).AmHost || !GameStates.IsModHost) { return; } if (GameStates.IsExilling && chatHistory.Count < 20) { PlayerControl val = Main.AllAlivePlayerControls.OrderBy((PlayerControl x) => x.PlayerId).FirstOrDefault(); if ((Object)(object)val == (Object)null) { return; } string text = "" + Translator.GetString("DefaultSystemMessageTitle") + ""; object obj; if (val == null) { obj = null; } else { NetworkedPlayerInfo data = val.Data; obj = ((data != null) ? data.PlayerName : null); } string text2 = (string)obj; string @string = Translator.GetString("ExileSpamMsg"); for (int i = 0; i < 20 - chatHistory.Count; i++) { int targetClientId = -1; val.SetName(text); DestroyableSingleton.Instance.Chat.AddChat(val, @string, true); val.SetName(text2); CustomRpcSender customRpcSender = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender.StartMessage(targetClientId); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(text) .EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)13).Write(@string).EndRpc(); customRpcSender.StartRpc(((InnerNetObject)val).NetId, (byte)6).Write(((InnerNetObject)val.Data).NetId).Write(text2) .EndRpc(); customRpcSender.EndMessage(); customRpcSender.SendMessage(); } } for (int j = 0; j < chatHistory.Count; j++) { Dictionary dictionary = chatHistory[j]; byte b = dictionary.Keys.First(); string text3 = dictionary[b]; PlayerControl playerById = Utils.GetPlayerById(b); if (!((Object)(object)playerById == (Object)null)) { bool num = !playerById.IsAlive(); if (num) { playerById.Revive(); } DestroyableSingleton.Instance.Chat.AddChat(playerById, text3, true); CustomRpcSender customRpcSender2 = CustomRpcSender.Create("MessagesToSend", (SendOption)0); customRpcSender2.StartMessage(); customRpcSender2.StartRpc(((InnerNetObject)playerById).NetId, (byte)13).Write(text3).EndRpc() .EndMessage() .SendMessage(); if (num) { playerById.Die((DeathReason)1, true); } } } byte[] array = LastSystemChatMsg.Keys.ToArray(); foreach (byte b2 in array) { if (!((Object)(object)Utils.GetPlayerById(b2) == (Object)null) || b2 == byte.MaxValue) { string title = "" + Translator.GetString("LastMessageReplay") + ""; Utils.SendMessage(LastSystemChatMsg[b2], b2, title, logforChatManager: false, noReplay: true); } } } } } namespace Costura { [CompilerGenerated] internal static class AssemblyLoader { private static object nullCacheLock = new object(); private static Dictionary nullCache = new Dictionary(); private static Dictionary assemblyNames = new Dictionary(); private static Dictionary symbolNames = new Dictionary(); private static int isAttached; private static string CultureToString(CultureInfo culture) { if (culture == null) { return ""; } return culture.Name; } private static Assembly ReadExistingAssembly(AssemblyName name) { AppDomain currentDomain = AppDomain.CurrentDomain; Assembly[] assemblies = currentDomain.GetAssemblies(); Assembly[] array = assemblies; foreach (Assembly assembly in array) { AssemblyName name2 = assembly.GetName(); if (string.Equals(name2.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) && string.Equals(CultureToString(name2.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase)) { return assembly; } } return null; } private static void CopyTo(Stream source, Stream destination) { byte[] array = new byte[81920]; int count; while ((count = source.Read(array, 0, array.Length)) != 0) { destination.Write(array, 0, count); } } private static Stream LoadStream(string fullName) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); if (fullName.EndsWith(".compressed")) { using (Stream stream = executingAssembly.GetManifestResourceStream(fullName)) { using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress); MemoryStream memoryStream = new MemoryStream(); CopyTo(source, memoryStream); memoryStream.Position = 0L; return memoryStream; } } return executingAssembly.GetManifestResourceStream(fullName); } private static Stream LoadStream(Dictionary resourceNames, string name) { if (resourceNames.TryGetValue(name, out var value)) { return LoadStream(value); } return null; } private static byte[] ReadStream(Stream stream) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); return array; } private static Assembly ReadFromEmbeddedResources(Dictionary assemblyNames, Dictionary symbolNames, AssemblyName requestedAssemblyName) { string text = requestedAssemblyName.Name.ToLowerInvariant(); if (requestedAssemblyName.CultureInfo != null && !string.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name)) { text = requestedAssemblyName.CultureInfo.Name + "." + text; } byte[] rawAssembly; using (Stream stream = LoadStream(assemblyNames, text)) { if (stream == null) { return null; } rawAssembly = ReadStream(stream); } using (Stream stream2 = LoadStream(symbolNames, text)) { if (stream2 != null) { byte[] rawSymbolStore = ReadStream(stream2); return Assembly.Load(rawAssembly, rawSymbolStore); } } return Assembly.Load(rawAssembly); } public static Assembly ResolveAssembly(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; } static AssemblyLoader() { assemblyNames.Add("csv", "costura.csv.dll.compressed"); } public static void Attach() { if (Interlocked.Exchange(ref isAttached, 1) == 1) { return; } AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) { lock (nullCacheLock) { if (nullCache.ContainsKey(e.Name)) { return null; } } AssemblyName assemblyName = new AssemblyName(e.Name); Assembly assembly = ReadExistingAssembly(assemblyName); if ((object)assembly != null) { return assembly; } assembly = ReadFromEmbeddedResources(assemblyNames, symbolNames, assemblyName); if ((object)assembly == null) { lock (nullCacheLock) { nullCache[e.Name] = true; } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assembly = Assembly.Load(assemblyName); } } return assembly; }; } } } internal class TOHE_ProcessedByFody { internal const string FodyVersion = "6.6.0.0"; internal const string Costura = "5.8.0"; }