using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BoneLib.BoneMenu; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSLZ.Bonelab; using Il2CppSLZ.Marrow; using Il2CppSLZ.Marrow.AI; using Il2CppSLZ.Marrow.Audio; using Il2CppSLZ.Marrow.Combat; using Il2CppSLZ.Marrow.Data; using Il2CppSLZ.Marrow.Interaction; using Il2CppSLZ.Marrow.Pool; using Il2CppSLZ.Marrow.Warehouse; using Il2CppSystem; using Il2CppTMPro; using LabFusion.Data; using LabFusion.Entities; using LabFusion.Extensions; using LabFusion.Marrow; using LabFusion.Marrow.Integration; using LabFusion.Marrow.Pool; using LabFusion.Menu.Data; using LabFusion.Network; using LabFusion.Player; using LabFusion.RPC; using LabFusion.Representation; using LabFusion.SDK.Gamemodes; using LabFusion.SDK.Points; using LabFusion.SDK.Triggers; using LabFusion.Senders; using LabFusion.UI.Popups; using LabFusion.Utilities; using LabFusion.Voice; using MelonLoader; using TroubleInFordTown; using UnityEngine; using UnityEngine.Audio; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(TTTMod), "Trouble In FordTown", "2.1.0", "JonLandonMods", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [assembly: HarmonyDontPatchAll] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyVersion("0.0.0.0")] namespace TroubleInFordTown; public class CorpseProxy { public RigManager Rig; public string PlayerName; public string RoleName; public string RoleColor; public string WeaponName; public float TimeOfDeath; public ushort OwnerSmallID; public bool WasInnocentSide; public bool IsValid { get { if ((Object)(object)Rig != (Object)null) { return (Object)(object)((Component)Rig).gameObject != (Object)null; } return false; } } public Vector3 Position { get { //IL_0044: 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_003c: 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) try { if (IsValid) { PhysicsRig physicsRig = Rig.physicsRig; if ((Object)(object)((physicsRig != null) ? ((Rig)physicsRig).m_chest : null) != (Object)null) { return ((Rig)Rig.physicsRig).m_chest.position; } } } catch { } return Vector3.zero; } } public void Destroy() { try { if ((Object)(object)Rig != (Object)null && (Object)(object)((Component)Rig).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)Rig).gameObject); } } catch { } Rig = null; } } public class CorpseInspectorUI { private GameObject _root; private TextMeshPro _text; private CorpseProxy _showing; private static TMP_FontAsset _font; private static TMP_FontAsset GetFont() { if ((Object)(object)_font != (Object)null) { return _font; } Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); foreach (TMP_FontAsset item in val) { if (((Object)item).name.ToLower().Contains("arlon-medium")) { _font = item; break; } } if ((Object)(object)_font == (Object)null && val.Length > 0) { _font = val[0]; } return _font; } private bool TryCreate() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { return true; } if (!RigData.HasPlayer) { return false; } _root = new GameObject("TIFT Corpse Inspector"); Object.DontDestroyOnLoad((Object)(object)_root); ((Object)_root).hideFlags = (HideFlags)32; _root.SetActive(false); _text = _root.AddComponent(); ((TMP_Text)_text).fontSize = 0.55f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(1.4f, 0.6f); TMP_FontAsset font = GetFont(); if ((Object)(object)font != (Object)null) { ((TMP_Text)_text).font = font; } return true; } public void ShowFor(CorpseProxy corpse) { _showing = corpse; } public void Hide() { _showing = null; if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } public void Update() { //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_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_006b: 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_0072: 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_0098: 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_00b0: 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_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 (!TryCreate()) { return; } if (_showing == null || !_showing.IsValid) { _root.SetActive(false); return; } Transform headset = RigData.Refs.Headset; if ((Object)(object)headset == (Object)null) { _root.SetActive(false); return; } Vector3 val = _showing.Position + Vector3.up * 0.7f; Vector3 val2 = headset.position - val; if (((Vector3)(ref val2)).sqrMagnitude < 0.001f) { val2 = Vector3.forward; } _root.transform.position = val; _root.transform.rotation = Quaternion.LookRotation(-((Vector3)(ref val2)).normalized); float num = Time.realtimeSinceStartup - _showing.TimeOfDeath; string text = ((num < 60f) ? $"{Mathf.FloorToInt(num)}s ago" : $"{Mathf.FloorToInt(num / 60f)}m {Mathf.FloorToInt(num % 60f)}s ago"); string text2 = (string.IsNullOrEmpty(_showing.WeaponName) ? "Weapon: Unknown" : ("Weapon: " + _showing.WeaponName + "")); ((TMP_Text)_text).text = $"{_showing.PlayerName}\n{_showing.RoleName}\n" + text2 + "\n" + text + ""; if (!_root.activeSelf) { _root.SetActive(true); } } public void DestroyUI() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _text = null; _showing = null; } } public static class CorpseManager { private static readonly List _corpses = new List(); private static readonly CorpseInspectorUI _inspectorUI = new CorpseInspectorUI(); private static readonly Dictionary _recentlyRemoved = new Dictionary(); private const float GrabRadius = 1.2f; private const float SuppressSeconds = 2f; public static void RegisterDeath(string playerName, string roleName, string roleColor, Vector3 deathPosition, string weaponName = null, string avatarBarcode = null, ushort ownerSmallId = 0, bool wasInnocentSide = false) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) SpawnRagdollCorpse(deathPosition, avatarBarcode, delegate(RigManager rig) { if (ownerSmallId != 0 && _recentlyRemoved.TryGetValue(ownerSmallId, out var value) && Time.realtimeSinceStartup - value < 2f) { try { if ((Object)(object)rig != (Object)null && (Object)(object)((Component)rig).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)rig).gameObject); } return; } catch { return; } } _corpses.Add(new CorpseProxy { Rig = rig, PlayerName = playerName, RoleName = roleName, RoleColor = roleColor, WeaponName = weaponName, TimeOfDeath = Time.realtimeSinceStartup, OwnerSmallID = ownerSmallId, WasInnocentSide = wasInnocentSide }); }); } public static bool TryGetInnocentCorpseAlongRay(Vector3 origin, Vector3 direction, float maxDistance, out ushort ownerSmallId, out Vector3 corpsePos) { //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) //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_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) //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) //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_0056: 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_006e: 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_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_007d: Unknown result type (might be due to invalid IL or missing references) ownerSmallId = 0; corpsePos = Vector3.zero; direction = ((Vector3)(ref direction)).normalized; float num = float.MaxValue; CorpseProxy corpseProxy = null; foreach (CorpseProxy corpse in _corpses) { if (corpse == null || !corpse.IsValid || !corpse.WasInnocentSide) { continue; } Vector3 val = corpse.Position - origin; float num2 = Vector3.Dot(val, direction); if (!(num2 < 0f) && !(num2 > maxDistance)) { Vector3 val2 = val - direction * num2; float magnitude = ((Vector3)(ref val2)).magnitude; if (!(magnitude > 1f) && magnitude < num) { num = magnitude; corpseProxy = corpse; } } } if (corpseProxy != null) { ownerSmallId = corpseProxy.OwnerSmallID; corpsePos = corpseProxy.Position; return true; } return false; } public static void RemoveCorpseOf(ushort ownerSmallId) { for (int num = _corpses.Count - 1; num >= 0; num--) { if (_corpses[num] != null && _corpses[num].OwnerSmallID == ownerSmallId) { _corpses[num].Destroy(); _corpses.RemoveAt(num); } } if (ownerSmallId != 0) { _recentlyRemoved[ownerSmallId] = Time.realtimeSinceStartup; } } private static void SpawnRagdollCorpse(Vector3 position, string avatarBarcode, Action onSpawned) { //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) PlayerRepUtilities.CreateNewRig((Action)delegate(RigManager rig) { //IL_0007: 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_0065: Expected O, but got Unknown try { ((Component)rig).transform.position = position; try { foreach (InventorySlotReceiver componentsInChild in ((Component)rig).GetComponentsInChildren(true)) { ((Behaviour)componentsInChild).enabled = false; } } catch { } if (!string.IsNullOrEmpty(avatarBarcode)) { try { rig.SwapAvatarCrate(new Barcode(avatarBarcode), false, (Action)null); } catch { } } try { ControllerRig controllerRig = rig.ControllerRig; BaseController[] array = (BaseController[])(object)new BaseController[2] { (controllerRig != null) ? controllerRig.leftController : null, (controllerRig != null) ? controllerRig.rightController : null }; foreach (BaseController obj3 in array) { Haptor val = ((obj3 != null) ? obj3.haptor : null); if (!((Object)(object)val == (Object)null)) { val.hapticsAllowed = false; val.device_Controller = null; ((Behaviour)val).enabled = false; } } foreach (Haptor componentsInChild2 in ((Component)rig).GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild2 == (Object)null)) { componentsInChild2.hapticsAllowed = false; componentsInChild2.device_Controller = null; ((Behaviour)componentsInChild2).enabled = false; } } } catch { } try { rig.physicsRig.ShutdownRig(); rig.physicsRig.RagdollRig(); } catch { } try { ControllerRig controllerRig2 = rig.ControllerRig; BaseController[] array = (BaseController[])(object)new BaseController[2] { (controllerRig2 != null) ? controllerRig2.leftController : null, (controllerRig2 != null) ? controllerRig2.rightController : null }; foreach (BaseController val2 in array) { if (!((Object)(object)val2 == (Object)null)) { try { ((Behaviour)val2).enabled = false; } catch { } try { ((Component)val2).gameObject.SetActive(false); } catch { } } } } catch { } try { Hand[] array2 = (Hand[])(object)new Hand[2] { rig.physicsRig.leftHand, rig.physicsRig.rightHand }; foreach (Hand val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { try { HandPoseAnimator animator = val3.Animator; if ((Object)(object)animator != (Object)null) { ((Behaviour)animator).enabled = false; } } catch { } try { ((Behaviour)val3).enabled = false; } catch { } } } } catch { } ((Object)((Component)rig).gameObject).name = "[TIFT Corpse]"; onSpawned?.Invoke(rig); } catch { } }); } public static void Update() { //IL_0052: 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_0057: 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_0061: 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_0079: 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_007e: 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_00b1: 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_00b5: 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_00be: Unknown result type (might be due to invalid IL or missing references) if (!RigData.HasPlayer) { return; } Hand leftHand = RigData.Refs.LeftHand; Transform val = ((leftHand != null) ? ((Component)leftHand).transform : null); Hand rightHand = RigData.Refs.RightHand; Transform val2 = ((rightHand != null) ? ((Component)rightHand).transform : null); Transform headset = RigData.Refs.Headset; Vector3 val3 = (((Object)(object)headset != (Object)null) ? headset.position : Vector3.zero); Vector3 val4 = (((Object)(object)val != (Object)null) ? val.position : val3); Vector3 val5 = (((Object)(object)val2 != (Object)null) ? val2.position : val3); CorpseProxy corpseProxy = null; float num = 1.2f; foreach (CorpseProxy corpse in _corpses) { if (corpse.IsValid) { Vector3 position = corpse.Position; float num2 = Mathf.Min(Vector3.Distance(val4, position), Vector3.Distance(val5, position)); if (num2 < num) { num = num2; corpseProxy = corpse; } } } if (corpseProxy != null) { _inspectorUI.ShowFor(corpseProxy); } else { _inspectorUI.Hide(); } _inspectorUI.Update(); } public static void ClearAll() { _inspectorUI.Hide(); try { LocalPlayer.ReleaseGrips(); } catch { } foreach (CorpseProxy corpse in _corpses) { corpse.Destroy(); } _corpses.Clear(); } public static void DestroyUI() { _inspectorUI.DestroyUI(); } } public static class CustomWeapons { public enum WeaponType { GoldenPistol, ShadowKnife } private struct TrackedWeapon { public ushort EntityId; public WeaponType Type; } private static TrackedWeapon? _active; private const string PistolBarcode = "c1534c5a-fcfc-4f43-8fb0-d29531393131"; private const string KnifeBarcode = "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; public const int GoldenPistolCost = 3; public const int ShadowKnifeCost = 2; public static bool GoldenPistolActive { get { if (_active.HasValue) { return _active.Value.Type == WeaponType.GoldenPistol; } return false; } } public static void BuyGoldenPistol(TroubleInFordTownGamemode gamemode) { if (!TraitorPoints.TrySpend(3)) { ShowNotEnoughTP(3); } else { SpawnCustomWeapon("c1534c5a-fcfc-4f43-8fb0-d29531393131", WeaponType.GoldenPistol, ApplyGoldMaterial, gamemode); } } public static void BuyShadowKnife(TroubleInFordTownGamemode gamemode) { if (!TraitorPoints.TrySpend(2)) { ShowNotEnoughTP(2); } else { SpawnCustomWeapon("c1534c5a-1fb8-477c-afbe-2a95436f6d62", WeaponType.ShadowKnife, ApplyShadowMaterial, gamemode); } } private static void SpawnCustomWeapon(string barcode, WeaponType type, Action materializer, TroubleInFordTownGamemode gamemode) { //IL_0036: 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_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_0050: 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_0063: 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_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_0090: Unknown result type (might be due to invalid IL or missing references) if (!RigData.HasPlayer) { return; } Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode); Transform headset = RigData.Refs.Headset; Vector3 position = headset.position + headset.forward * 0.5f; NetworkAssetSpawner.Spawn(new SpawnRequestInfo { Spawnable = spawnable, Position = position, Rotation = Quaternion.identity, SpawnEffect = true, SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_000a: 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_005f: 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) _active = new TrackedWeapon { EntityId = info.Entity.ID, Type = type }; try { materializer(info.Spawned); } catch { } try { BoostDamage(info.Spawned); } catch { } gamemode.TryHolster(info.Spawned); } }); } private static void BoostDamage(GameObject item) { if ((Object)(object)item == (Object)null) { return; } foreach (MonoBehaviour componentsInChild in item.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild == (Object)null) { continue; } try { FieldInfo field = ((object)componentsInChild).GetType().GetField("damage", BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == typeof(float)) { field.SetValue(componentsInChild, 99999f); } } catch { } } } public static void OnLocalKill() { //IL_0030: 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_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_0072: 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_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_0093: 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_00aa: Expected O, but got Unknown if (_active.HasValue) { TrackedWeapon value = _active.Value; _active = null; try { LocalPlayer.ReleaseGrips(); } catch { } try { NetworkAssetSpawner.Despawn(new DespawnRequestInfo { EntityID = value.EntityId, DespawnEffect = true }); } catch { } string text = ((value.Type == WeaponType.GoldenPistol) ? "Golden Pistol" : "Shadow Knife"); Notifier.Send(new Notification { Title = NotificationText.op_Implicit(text), Message = NotificationText.op_Implicit("Your one-use weapon has disappeared."), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)0 }); } } public static void Reset() { _active = null; } private static void ApplyGoldMaterial(GameObject item) { //IL_002d: 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) Color baseColor = default(Color); ((Color)(ref baseColor))..ctor(1f, 0.78f, 0.1f); Color emissiveColor = default(Color); ((Color)(ref emissiveColor))..ctor(0.4f, 0.28f, 0f); TintAllRenderers(item, baseColor, emissiveColor); } private static void ApplyShadowMaterial(GameObject item) { //IL_002d: 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) Color baseColor = default(Color); ((Color)(ref baseColor))..ctor(0.06f, 0f, 0.12f); Color emissiveColor = default(Color); ((Color)(ref emissiveColor))..ctor(0.25f, 0f, 0.45f); TintAllRenderers(item, baseColor, emissiveColor); } private static void TintAllRenderers(GameObject item, Color baseColor, Color emissiveColor) { //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_004f: 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 ((Object)(object)item == (Object)null) { return; } foreach (MeshRenderer componentsInChild in item.GetComponentsInChildren(true)) { TintRenderer((Renderer)(object)componentsInChild, baseColor, emissiveColor); } foreach (SkinnedMeshRenderer componentsInChild2 in item.GetComponentsInChildren(true)) { TintRenderer((Renderer)(object)componentsInChild2, baseColor, emissiveColor); } } private static void TintRenderer(Renderer rend, Color baseColor, Color emissiveColor) { //IL_0035: 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_0067: 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_0099: 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_00cb: 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) Il2CppReferenceArray materials = rend.materials; for (int i = 0; i < ((Il2CppArrayBase)(object)materials).Length; i++) { Material val = ((Il2CppArrayBase)(object)materials)[i]; if (!((Object)(object)val == (Object)null)) { if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", baseColor); } if (val.HasProperty("_Color")) { val.SetColor("_Color", baseColor); } if (val.HasProperty("_MainColor")) { val.SetColor("_MainColor", baseColor); } if (val.HasProperty("_TintColor")) { val.SetColor("_TintColor", baseColor); } if (val.HasProperty("_AlbedoColor")) { val.SetColor("_AlbedoColor", baseColor); } if (val.HasProperty("_EmissiveColor")) { val.SetColor("_EmissiveColor", emissiveColor); } if (val.HasProperty("_EmissionColor")) { val.SetColor("_EmissionColor", emissiveColor); } if (val.HasProperty("_Emission")) { val.SetColor("_Emission", emissiveColor); } val.EnableKeyword("_EMISSION"); val.EnableKeyword("_EMISSIVE_COLOR_MAP"); } } rend.materials = materials; } private static void ShowNotEnoughTP(int cost) { //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_000b: 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_005f: 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_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_0087: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Not Enough Traitor Points"), Message = NotificationText.op_Implicit($"You need {cost} TP but only have {TraitorPoints.Points}."), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)1 }); } } public class HolsterHider { private const string KnifeBarcode = "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; private const string OneStabKnifeBarcode = "JonLandon.TFTknife.Spawnable.TFTknife"; private readonly Dictionary> _hiddenProps = new Dictionary>(); private readonly Dictionary _knifeCache = new Dictionary(); private static readonly List _localKnives = new List(); private readonly HashSet _found = new HashSet(); private readonly HashSet _evaluate = new HashSet(); private readonly List _dead = new List(); private float _timer; private const float RefreshInterval = 0.3f; public static void RegisterLocalKnife(GameObject go) { if ((Object)(object)go != (Object)null) { _localKnives.Add(go); } } public void Update() { foreach (KeyValuePair> hiddenProp in _hiddenProps) { List value = hiddenProp.Value; for (int i = 0; i < value.Count; i++) { Renderer val = value[i]; try { if ((Object)(object)val != (Object)null && !val.forceRenderingOff) { val.forceRenderingOff = true; } } catch { } } } _timer -= Time.deltaTime; if (_timer > 0f) { return; } _timer = 0.3f; _localKnives.RemoveAll((GameObject g) => (Object)(object)g == (Object)null); _found.Clear(); try { foreach (WeaponSlot item in Object.FindObjectsOfType()) { if (!((Object)(object)item == (Object)null) && IsKnife(item)) { Poolee componentInParent = ((Component)item).gameObject.GetComponentInParent(); GameObject val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)((Component)item).transform.root).gameObject); if ((Object)(object)val2 != (Object)null && !IsLocalKnife(val2)) { _found.Add(val2); } } } } catch { } _evaluate.Clear(); foreach (GameObject item2 in _found) { _evaluate.Add(item2); } foreach (GameObject key in _hiddenProps.Keys) { _evaluate.Add(key); } foreach (GameObject item3 in _evaluate) { if ((Object)(object)item3 == (Object)null) { DropHidden(item3); } else if (IsHeld(item3)) { Reveal(item3); } else { Conceal(item3); } } _dead.Clear(); foreach (GameObject key2 in _hiddenProps.Keys) { if ((Object)(object)key2 == (Object)null) { _dead.Add(key2); } } foreach (GameObject item4 in _dead) { DropHidden(item4); } } private void Conceal(GameObject prop) { if (_hiddenProps.ContainsKey(prop)) { return; } List list = new List(); try { foreach (Renderer componentsInChild in prop.GetComponentsInChildren(true)) { if (!((Object)(object)componentsInChild == (Object)null)) { componentsInChild.forceRenderingOff = true; list.Add(componentsInChild); } } } catch { } _hiddenProps[prop] = list; } private void Reveal(GameObject prop) { if (!_hiddenProps.TryGetValue(prop, out var value)) { return; } foreach (Renderer item in value) { try { if ((Object)(object)item != (Object)null) { item.forceRenderingOff = false; } } catch { } } _hiddenProps.Remove(prop); } private void DropHidden(GameObject prop) { _hiddenProps.Remove(prop); } private static bool IsHeld(GameObject propGO) { try { foreach (Grip componentsInChild in propGO.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null && componentsInChild.attachedHands != null && componentsInChild.attachedHands.Count > 0) { return true; } } } catch { } return false; } private static bool IsLocalKnife(GameObject propGO) { foreach (GameObject localKnife in _localKnives) { if ((Object)(object)localKnife == (Object)null) { continue; } if ((Object)(object)localKnife == (Object)(object)propGO) { return true; } try { if (localKnife.transform.IsChildOf(propGO.transform) || propGO.transform.IsChildOf(localKnife.transform)) { return true; } } catch { } } return false; } private bool IsKnife(WeaponSlot weapon) { int instanceID = ((Object)weapon).GetInstanceID(); if (_knifeCache.TryGetValue(instanceID, out var value)) { return value; } try { GameObject gameObject = ((Component)weapon).gameObject; Poolee val = Poolee.Cache.Get(gameObject); if ((Object)(object)val == (Object)null) { val = gameObject.GetComponentInParent(); } object obj; if (val == null) { obj = null; } else { SpawnableCrate spawnableCrate = val.SpawnableCrate; if (spawnableCrate == null) { obj = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj = ((barcode != null) ? barcode.ID : null); } } string text = (string)obj; if (!string.IsNullOrEmpty(text)) { bool flag = text == "c1534c5a-1fb8-477c-afbe-2a95436f6d62" || text == "JonLandon.TFTknife.Spawnable.TFTknife"; _knifeCache[instanceID] = flag; return flag; } } catch { } return false; } public void ClearAll() { foreach (KeyValuePair> hiddenProp in _hiddenProps) { foreach (Renderer item in hiddenProp.Value) { try { if ((Object)(object)item != (Object)null) { item.forceRenderingOff = false; } } catch { } } } _hiddenProps.Clear(); _knifeCache.Clear(); _localKnives.Clear(); } } public class HypnotistController { public const float BrainwashSeconds = 9.5f; public Action OnBrainwashComplete; private bool _charging; private ushort _targetId; private float _charge; private float _graceTimer; private GameObject _beamObj; private LineRenderer _beam; private AudioSource _audio; public static AudioClip ChargeClip; public void Update(string gunBarcode) { //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_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_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_008d: 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_00a1: Unknown result type (might be due to invalid IL or missing references) if (!RigData.HasPlayer) { StopCharge(); return; } Transform val = FindHeldGun(gunBarcode); if ((Object)(object)val == (Object)null) { StopCharge(); return; } Vector3 position = val.position; Vector3 forward = val.forward; if (CorpseManager.TryGetInnocentCorpseAlongRay(position, forward, 30f, out var ownerSmallId, out var corpsePos) && ownerSmallId != 0) { if (_charging && _targetId == ownerSmallId) { _charge += Time.deltaTime; } else { _charging = true; _targetId = ownerSmallId; _charge = 0f; PlayChargeOnce(corpsePos); } _graceTimer = 0.6f; ShowBeam(position, corpsePos); if (_charge >= 9.5f) { ushort targetId = _targetId; StopCharge(); OnBrainwashComplete?.Invoke(targetId); } } else if (_charging && _graceTimer > 0f) { _graceTimer -= Time.deltaTime; if ((Object)(object)_beamObj != (Object)null && _beamObj.activeSelf) { _beamObj.SetActive(false); } } else { StopCharge(); } } public void Cleanup() { StopCharge(); if ((Object)(object)_beamObj != (Object)null) { Object.Destroy((Object)(object)_beamObj); _beamObj = null; _beam = null; } if ((Object)(object)_audio != (Object)null) { Object.Destroy((Object)(object)((Component)_audio).gameObject); _audio = null; } } private static Transform FindHeldGun(string gunBarcode) { try { PhysicsRig physicsRig = RigData.Refs.RigManager.physicsRig; Hand[] array = (Hand[])(object)new Hand[2] { physicsRig.rightHand, physicsRig.leftHand }; foreach (Hand obj in array) { GameObject val = ((obj != null) ? obj.m_CurrentAttachedGO : null); if ((Object)(object)val == (Object)null) { continue; } Gun componentInChildren = ((Component)val.transform.root).GetComponentInChildren(true); Transform result = (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.firePointTransform != (Object)null) ? componentInChildren.firePointTransform : (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform : val.transform)); bool flag = false; if (!string.IsNullOrEmpty(gunBarcode)) { Poolee val2 = Poolee.Cache.Get(val); if ((Object)(object)val2 == (Object)null) { val2 = val.GetComponentInParent(); } object obj2; if (val2 == null) { obj2 = null; } else { SpawnableCrate spawnableCrate = val2.SpawnableCrate; if (spawnableCrate == null) { obj2 = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj2 = ((barcode != null) ? barcode.ID : null); } } if ((string?)obj2 == gunBarcode) { flag = true; } } if (flag || (Object)(object)componentInChildren != (Object)null) { return result; } } } catch { } return null; } private void ShowBeam(Vector3 from, Vector3 to) { //IL_0091: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_001e: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if ((Object)(object)_beamObj == (Object)null) { _beamObj = new GameObject("TIFT Brainwash Beam"); Object.DontDestroyOnLoad((Object)(object)_beamObj); _beam = _beamObj.AddComponent(); ((Renderer)_beam).material = new Material(Shader.Find("Sprites/Default")); _beam.widthMultiplier = 0.03f; _beam.numCapVertices = 4; } float num = Mathf.Clamp01(_charge / 9.5f); Color val = Color.Lerp(new Color(0.6f, 0f, 1f), new Color(1f, 0.2f, 0.6f), num); _beam.startColor = val; _beam.endColor = val; _beam.SetPosition(0, from); _beam.SetPosition(1, to); if (!_beamObj.activeSelf) { _beamObj.SetActive(true); } } private void PlayChargeOnce(Vector3 position) { //IL_00a0: 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_0027: Expected O, but got Unknown if (!((Object)(object)ChargeClip == (Object)null)) { if ((Object)(object)_audio == (Object)null) { GameObject val = new GameObject("TIFT Brainwash Audio"); Object.DontDestroyOnLoad((Object)(object)val); _audio = val.AddComponent(); _audio.loop = false; _audio.spatialBlend = 1f; _audio.minDistance = 2f; _audio.maxDistance = 25f; _audio.clip = ChargeClip; _audio.volume = 1f; } ((Component)_audio).transform.position = position; _audio.Stop(); _audio.Play(); } } private void StopCharge() { _charging = false; _charge = 0f; _targetId = 0; if ((Object)(object)_beamObj != (Object)null && _beamObj.activeSelf) { _beamObj.SetActive(false); } if ((Object)(object)_audio != (Object)null && _audio.isPlaying) { _audio.Stop(); } } } public static class KarmaManager { public static bool Enabled = false; private static readonly Dictionary _karma = new Dictionary(); public const int DefaultKarma = 1000; public const int MaxKarma = 2000; private const int KickThreshold = 350; private const int HighRiskThreshold = 500; private const int WarnThreshold = 700; public const int GoodKillReward = 200; public const int FriendlyFirePenalty = -400; public const int WrongKillPenalty = -300; public const int RoundParticipationBonus = 30; public static void EnsurePlayer(PlayerID player) { if (!_karma.ContainsKey(player.SmallID)) { _karma[player.SmallID] = 1000; } } public static void RemovePlayer(PlayerID player) { _karma.Remove(player.SmallID); } public static int GetKarma(PlayerID player) { if (!_karma.TryGetValue(player.SmallID, out var value)) { return 1000; } return value; } public static int GetLocalKarma() { PlayerID localID = PlayerIDManager.LocalID; if (localID == null) { return 1000; } return GetKarma(localID); } public static void AdjustKarma(PlayerID player, int delta) { //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_006b: 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_00ab: 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_00bc: 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_00d3: Expected O, but got Unknown if (Enabled) { EnsurePlayer(player); byte smallID = player.SmallID; _karma[smallID] = Math.Clamp(_karma[smallID] + delta, 0, 2000); if (player.IsMe) { int value = _karma[smallID]; string value2 = ((delta >= 0) ? "+" : ""); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Karma"), Message = NotificationText.op_Implicit($"{value2}{delta} karma — you now have {value}"), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)0 }); } if (NetworkInfo.IsHost) { CheckAndMaybeKick(player); } } } public static void AwardRoundBonus(PlayerID player) { AdjustKarma(player, 30); } private static void CheckAndMaybeKick(PlayerID player) { if (player.IsMe) { return; } int karma = GetKarma(player); if (karma <= 350) { TryKick(player, karma); } else if (karma <= 500) { if (Random.value < 0.6f) { TryKick(player, karma); } else { BroadcastLowKarmaWarning(player, karma); } } else if (karma <= 700) { BroadcastLowKarmaWarning(player, karma); } } private static void TryKick(PlayerID player, int karma) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00b2: 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_00f6: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown string value = default(string); MetadataHelper.TryGetDisplayName(player, ref value); MelonLogger.Msg($"[FordTown] Attempting to kick {value} for low karma ({karma})."); MelonLogger.Msg($"[FordTown Karma] Auto-kick triggered for {value} ({karma} karma) — no public kick API in this Fusion version."); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Player Kicked"), Message = NotificationText.op_Implicit($"{value} was kicked for low karma ({karma})."), ShowPopup = true, PopupLength = 5f, Type = (NotificationType)1 }); } private static void BroadcastLowKarmaWarning(PlayerID player, int karma) { //IL_0009: 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_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_0058: 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_0069: 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_0080: Expected O, but got Unknown string value = default(string); MetadataHelper.TryGetDisplayName(player, ref value); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Low Karma Warning"), Message = NotificationText.op_Implicit($"{value} has low karma ({karma}). Play properly!"), ShowPopup = true, PopupLength = 5f, Type = (NotificationType)1 }); } public static void Clear() { _karma.Clear(); } } public class RoleLabels { private class Label { public GameObject Root; public TextMeshPro Text; } private readonly Dictionary _labels = new Dictionary(); private static TMP_FontAsset _font; private readonly HashSet _wanted = new HashSet(); private readonly List _toRemove = new List(); private float _rebuildTimer; private const float RebuildInterval = 0.08f; private static readonly Color DetectiveBlue = new Color(0.2f, 0.6f, 1f); private static readonly Color TraitorRed = new Color(1f, 0.2f, 0.2f); private static readonly Color JesterPink = new Color(1f, 0.41f, 0.71f); private static readonly Color InnocentGreen = new Color(0.2f, 1f, 0.2f); private static readonly Color PsychopathRed = new Color(0.8f, 0f, 0f); private static readonly Color LoneWolfOrange = new Color(1f, 0.55f, 0f); private static readonly Color GlitchCyan = new Color(0f, 1f, 1f); private static readonly Color ZombieLime = new Color(0.37f, 0.8f, 0.1f); private static TMP_FontAsset GetFont() { if ((Object)(object)_font != (Object)null) { return _font; } Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); foreach (TMP_FontAsset item in val) { if (((Object)item).name.ToLower().Contains("arlon-medium")) { _font = item; break; } } if ((Object)(object)_font == (Object)null && val.Length > 0) { _font = val[0]; } return _font; } public void Update(TroubleInFordTownGamemode gm) { //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) //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) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: 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_0137: 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) //IL_028f: 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_029d: 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) //IL_02b1: 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_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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_0159: 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_02f6: 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_02d0: 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_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_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_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_01c3: 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) if (gm == null || !((Gamemode)gm).IsStarted || !RigData.HasPlayer) { ClearAll(); return; } Transform headset = RigData.Refs.Headset; if ((Object)(object)headset == (Object)null) { ClearAll(); return; } _rebuildTimer -= Time.deltaTime; if (_rebuildTimer > 0f) { return; } _rebuildTimer = 0.08f; Team localTeam = gm.TeamManager.GetLocalTeam(); bool flag = localTeam == gm.TraitorTeam; bool flag2 = localTeam == gm.SpectatorTeam; bool flag3 = localTeam == gm.ZombieTeam; HashSet wanted = _wanted; wanted.Clear(); foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID == null || playerID.IsMe) { continue; } Team playerTeam = gm.TeamManager.GetPlayerTeam(playerID); if (playerTeam == null || playerTeam == gm.SpectatorTeam) { continue; } string text; Color color; if (flag2) { if (playerTeam == gm.TraitorTeam) { text = "TRAITOR"; color = TraitorRed; } else if (playerTeam == gm.DetectiveTeam) { text = "DETECTIVE"; color = DetectiveBlue; } else if (playerTeam == gm.JesterTeam) { text = "JESTER"; color = JesterPink; } else if (playerTeam == gm.PsychopathTeam) { text = "PSYCHOPATH"; color = PsychopathRed; } else if (playerTeam == gm.LoneWolfTeam) { text = "LONE WOLF"; color = LoneWolfOrange; } else if (playerTeam == gm.GlitchTeam) { text = "GLITCH"; color = GlitchCyan; } else if (playerTeam == gm.ZombieTeam) { text = "ZOMBIE"; color = ZombieLime; } else { text = "INNOCENT"; color = InnocentGreen; } } else if (flag3 && playerTeam == gm.ZombieTeam) { text = "ZOMBIE"; color = ZombieLime; } else if (playerTeam == gm.DetectiveTeam) { text = "DETECTIVE"; color = DetectiveBlue; } else if (flag && playerTeam == gm.JesterTeam) { text = "JESTER"; color = JesterPink; } else { if (!flag || (playerTeam != gm.TraitorTeam && playerTeam != gm.GlitchTeam)) { continue; } text = "TRAITOR"; color = TraitorRed; } Transform head = GetHead(playerID); if (!((Object)(object)head == (Object)null)) { wanted.Add(playerID.SmallID); Label label = EnsureLabel(playerID.SmallID); ((TMP_Text)label.Text).text = text; ((Graphic)label.Text).color = color; Vector3 val = head.position + Vector3.up * 0.5f; Vector3 val2 = val - headset.position; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } label.Root.transform.position = val; label.Root.transform.rotation = Quaternion.LookRotation(val2); if (!label.Root.activeSelf) { label.Root.SetActive(true); } } } if (_labels.Count <= 0) { return; } _toRemove.Clear(); foreach (KeyValuePair label2 in _labels) { if (!wanted.Contains(label2.Key)) { _toRemove.Add(label2.Key); } } foreach (ushort item in _toRemove) { if ((Object)(object)_labels[item].Root != (Object)null) { Object.Destroy((Object)(object)_labels[item].Root); } _labels.Remove(item); } } private static Transform GetHead(PlayerID pid) { try { NetworkPlayer val = default(NetworkPlayer); if (NetworkPlayerManager.TryGetPlayer(pid.SmallID, ref val)) { RigRefs rigRefs = val.RigRefs; return (rigRefs != null) ? rigRefs.Head : null; } } catch { } return null; } private Label EnsureLabel(ushort smallId) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (_labels.TryGetValue(smallId, out var value) && (Object)(object)value.Root != (Object)null) { return value; } GameObject val = new GameObject($"TIFT Role Label {smallId}"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)32; TextMeshPro val2 = val.AddComponent(); TMP_FontAsset font = GetFont(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val2).font = font; } ((TMP_Text)val2).fontSize = 1.4f; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(2.5f, 0.7f); Label label = new Label { Root = val, Text = val2 }; _labels[smallId] = label; return label; } public void ClearAll() { foreach (KeyValuePair label in _labels) { if ((Object)(object)label.Value.Root != (Object)null) { Object.Destroy((Object)(object)label.Value.Root); } } _labels.Clear(); } } public class RolesInfoMenu { private Page _page; private Page _settingsPage; private FunctionElement _karmaDisplay; public void Register() { //IL_001a: 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_008f: 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_00ec: 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_0166: 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_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: 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_0341: Unknown result type (might be due to invalid IL or missing references) _settingsPage = Page.Root.CreatePage("TFT Settings", new Color(0.85f, 0.85f, 0.2f), 0, true); _settingsPage.CreateBool("Mute Win Music (local)", new Color(0.9f, 0.5f, 0.2f), WinMusic.LocallyMuted, (Action)delegate(bool v) { WinMusic.LocallyMuted = v; }); _karmaDisplay = _settingsPage.CreateFunction("Your Karma: —", new Color(0.4f, 0.8f, 1f), (Action)RefreshKarma); Menu.OnPageOpened += OnPageOpened; _page = Page.Root.CreatePage("Roles Info", Color.white, 7, true); AddRole("INNOCENT", new Color(0.2f, 1f, 0.2f), "Find and kill all the", "Traitors to win."); AddRole("TRAITOR", new Color(1f, 0.2f, 0.2f), "Secretly eliminate", "everyone else to win.", "Buy gear in the", "Traitor Shop."); AddRole("DETECTIVE", new Color(0.2f, 0.6f, 1f), "Publicly known to all.", "Leads the Innocents in", "hunting the Traitors."); AddRole("JESTER", new Color(1f, 0.41f, 0.71f), "Trick an Innocent into", "killing you to become", "the Psychopath. If a", "Traitor kills you, you lose."); AddRole("PSYCHOPATH", new Color(0.8f, 0f, 0f), "A second chance for the", "Jester after being killed", "by an Innocent. Kill", "everyone to win."); AddRole("LONE WOLF", new Color(1f, 0.55f, 0f), "A lone killer. Be the", "last one standing", "to win."); AddRole("GLITCH", new Color(0f, 1f, 1f), "Appears as a Traitor to", "the Traitors, but is", "secretly Innocent and", "wins with the Innocents."); AddRole("HYPNOTIST", new Color(0.61f, 0.19f, 1f), "A Traitor with a", "brainwashing gun. Aim it", "at a dead Innocent's", "corpse to revive them", "as a Traitor."); AddRole("ZOMBIE", new Color(0.37f, 0.8f, 0.1f), "Stab others with your", "knife to turn them into", "Zombies too. Infect", "everyone to win."); AddRole("SPECTATOR", new Color(0.67f, 0.67f, 0.67f), "You've been eliminated.", "Watch and wait for the", "round to end."); } private void AddRole(string name, Color color, params string[] lines) { //IL_0007: 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) Page val = _page.CreatePage(name, color, 0, true); foreach (string text in lines) { val.CreateFunction(text, Color.white, (Action)delegate { }); } } private void OnPageOpened(Page page) { if (page == _settingsPage) { RefreshKarma(); } } private void RefreshKarma() { if (_karmaDisplay != null) { string elementName = (KarmaManager.Enabled ? $"Your Karma: {KarmaManager.GetLocalKarma()}" : "Your Karma: (Karma disabled)"); ((Element)_karmaDisplay).ElementName = elementName; } } public void Unregister() { Menu.OnPageOpened -= OnPageOpened; if (_page != null) { Page.Root.RemovePage(_page); _page = null; } if (_settingsPage != null) { Page.Root.RemovePage(_settingsPage); _settingsPage = null; } } } public class TraitorBuyMenu { private Page _shopPage; private TroubleInFordTownGamemode _gamemode; private FunctionElement _tpHeader; private FunctionElement _pistolBtn; private FunctionElement _knifeBtn; private FunctionElement _healthBtn; private FunctionElement _statusLabel; public void Register(TroubleInFordTownGamemode gamemode) { //IL_0021: 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) _gamemode = gamemode; _shopPage = Page.Root.CreatePage("Traitor Shop", new Color(0.85f, 0.1f, 0.1f), 0, true); _statusLabel = _shopPage.CreateFunction("Traitors only — in-round", Color.gray, (Action)delegate { }); TraitorPoints.OnPointsChanged += Refresh; Menu.OnPageOpened += OnPageOpened; } private void OnPageOpened(Page page) { if (page == _shopPage) { Refresh(); } } public void Unregister() { TraitorPoints.OnPointsChanged -= Refresh; Menu.OnPageOpened -= OnPageOpened; if (_shopPage != null) { Page.Root.RemovePage(_shopPage); _shopPage = null; } _gamemode = null; } public void Refresh() { //IL_00db: 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_0110: 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_0115: 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) if (_shopPage == null || _gamemode == null) { return; } _shopPage.RemoveAll(); _tpHeader = null; _pistolBtn = null; _knifeBtn = null; _healthBtn = null; _statusLabel = null; if (!((Gamemode)_gamemode).IsStarted || _gamemode.TeamManager.GetLocalTeam() != _gamemode.TraitorTeam) { _statusLabel = _shopPage.CreateFunction("Traitors only — in-round", Color.gray, (Action)delegate { }); return; } int points = TraitorPoints.Points; _tpHeader = _shopPage.CreateFunction($"Traitor Points: {points}", Color.yellow, (Action)delegate { Refresh(); }); Color val = (Color)((points >= 1) ? new Color(0.2f, 0.9f, 0.3f) : Color.gray); _healthBtn = _shopPage.CreateFunction($"Health Boost [{1} TP] — restore full health", val, (Action)delegate { //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_009e: 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_00ae: 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_00bf: 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_00d6: Expected O, but got Unknown //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_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_006a: 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_007b: 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) //IL_0092: Expected O, but got Unknown if (!TraitorPoints.TrySpend(1)) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Not Enough Traitor Points"), Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."), ShowPopup = true, PopupLength = 2f, Type = (NotificationType)1 }); } else { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Health Boost!"), Message = NotificationText.op_Implicit("Your health has been restored."), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)0 }); Refresh(); } }); } } public static class TraitorPoints { public static int Points { get; private set; } public static event Action OnPointsChanged; public static void Reset() { Points = 2; TraitorPoints.OnPointsChanged?.Invoke(); } public static void Clear() { Points = 0; TraitorPoints.OnPointsChanged?.Invoke(); } public static void AddKillReward() { Points++; TraitorPoints.OnPointsChanged?.Invoke(); } public static bool TrySpend(int cost) { if (Points < cost) { return false; } Points -= cost; TraitorPoints.OnPointsChanged?.Invoke(); return true; } } public static class TraitorShopRadial { private const int HealthCost = 1; private const int KnifeCost = 2; private static TroubleInFordTownGamemode _gamemode; private static bool _added; public static void AddMenuItems(TroubleInFordTownGamemode gamemode) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown RemoveMenuItems(); _gamemode = gamemode; try { PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu; Page homePage = popUpMenu.radialPageView.m_HomePage; homePage.items.Add(new PageItem($"Health Boost [{1} TP]", (Directions)5, Action.op_Implicit((Action)delegate { popUpMenu.Deactivate(); BuyHealth(); }))); homePage.items.Add(new PageItem($"Knife [{2} TP]", (Directions)6, Action.op_Implicit((Action)delegate { popUpMenu.Deactivate(); BuyKnife(); }))); popUpMenu.radialPageView.Render(homePage); _added = true; } catch { } } public static void RemoveMenuItems() { if (!_added) { return; } try { PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu; Page homePage = popUpMenu.radialPageView.m_HomePage; homePage.items.RemoveAll(Predicate.op_Implicit((Func)((PageItem i) => i.name != null && (i.name.StartsWith("Golden Pistol") || i.name.StartsWith("Shadow Knife") || i.name.StartsWith("Knife") || i.name.StartsWith("Health Boost"))))); popUpMenu.radialPageView.Render(homePage); } catch { } _added = false; _gamemode = null; } private static void BuyHealth() { //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_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_006a: 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_007b: 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) //IL_0092: Expected O, but got Unknown //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_00bf: 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_00cf: 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_00e0: 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: Expected O, but got Unknown if (!TraitorPoints.TrySpend(1)) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Not Enough Traitor Points"), Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."), ShowPopup = true, PopupLength = 2f, Type = (NotificationType)1 }); return; } try { if (RigData.HasPlayer) { RigData.Refs.RigManager.health.SetFullHealth(); } } catch { } Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Health Boost!"), Message = NotificationText.op_Implicit("Your health has been restored."), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)0 }); } private static void BuyKnife() { //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_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_006a: 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_007b: 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) //IL_0092: Expected O, but got Unknown //IL_00a9: 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_00b4: 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_00c4: 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_00d5: 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_00ec: Expected O, but got Unknown if (!TraitorPoints.TrySpend(2)) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Not Enough Traitor Points"), Message = NotificationText.op_Implicit($"You need {2} TP but only have {TraitorPoints.Points}."), ShowPopup = true, PopupLength = 2f, Type = (NotificationType)1 }); } else { try { _gamemode?.GiveTraitorKnife(); } catch { } Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Knife Purchased"), Message = NotificationText.op_Implicit("A knife has been holstered. Others can't see it on your body."), ShowPopup = true, PopupLength = 3f, Type = (NotificationType)0 }); } } } public class TroubleInFordTownGamemode : Gamemode { public static class Defaults { public const int TraitorCount = 1; public const int PrepSeconds = 30; public const int RoundMinutes = 5; public const int WinnerBitReward = 100; public const int LoserBitReward = 25; public const int CorrectKillBitReward = 50; public static readonly MonoDiscReference[] Tracks = FusionMonoDiscPlaylists.AmbientPlaylist; public static readonly string[] Sidearms = new string[3] { "c1534c5a-fcfc-4f43-8fb0-d29531393131", "c1534c5a-2a4f-481f-8542-cc9545646572", "c1534c5a-bcb7-4f02-a4f5-da9550333530" }; public static readonly string[] Primaries = new string[9] { "c1534c5a-a6b5-4177-beb8-04d947756e41", "c1534c5a-9112-49e5-b022-9c955269666c", "c1534c5a-c061-4c5c-a5e2-3d955269666c", "c1534c5a-d00c-4aa8-adfd-3495534d474d", "c1534c5a-8d03-42de-93c7-f595534d4755", "c1534c5a-4c47-428d-b5a5-b05747756e56", "c1534c5a-7f05-402f-9320-609647756e35", "c1534c5a-2774-48db-84fd-778447756e46", "c1534c5a-04d7-41a0-b7b8-5a95534d4750" }; public const string TraitorKnife = "c1534c5a-1fb8-477c-afbe-2a95436f6d62"; } private enum JesterDeath { BecamePsychopath, KilledByEnemy, NoKillerYet } public const string BrainwashGunBarcode = "JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun"; private const string HypnotistMetaKey = "tift_hypnotist"; private ushort _hypnotistSmallID; private bool _brainwashGunGiven; private float _brainwashGunRetry; private const string MusicMetaKey = "tift_music"; private const string OneStabMetaKey = "tift_onestab"; public const string OneStabKnifeBarcode = "JonLandon.TFTknife.Spawnable.TFTknife"; private GameObject _oneStabKnife; private string _localPrimaryBarcode; private readonly HashSet _deadPlayers = new HashSet(); private float _killedJesterTime = -999f; private const string TraitorColor = "#ff3333"; private const string InnocentColor = "#33ff33"; private const string DetectiveColor = "#3399ff"; private const string SpectatorColor = "#aaaaaa"; public const string JesterColor = "#ff69b4"; public const string PsychopathColor = "#cc0000"; public const string LoneWolfColor = "#ff8c00"; public const string GlitchColor = "#00ffff"; public const string HypnotistColor = "#9b30ff"; public const string ZombieColor = "#5ecc1a"; private readonly MusicPlaylist _playlist = new MusicPlaylist(); private readonly TeamManager _teamManager = new TeamManager(); private readonly Team _traitorTeam = new Team("Traitors"); private readonly Team _innocentTeam = new Team("Innocents"); private readonly Team _detectiveTeam = new Team("Detectives"); private readonly Team _spectatorTeam = new Team("Spectators"); private readonly Team _jesterTeam = new Team("Jesters"); private readonly Team _psychopathTeam = new Team("Psychopaths"); private readonly Team _loneWolfTeam = new Team("Lone Wolves"); private readonly Team _glitchTeam = new Team("Glitches"); private readonly Team _zombieTeam = new Team("Zombies"); private bool _roundStarted; private float _elapsedTime; private bool _oneMinuteLeft; private bool _gameEnded; private bool _localDied; private Vector3 _localDeathPos = Vector3.zero; private bool _hasLocalDeathPos; private Vector3 _localLastAlivePos = Vector3.zero; private bool _hasLastAlivePos; private Vector3 _prevHeadPos = Vector3.zero; private bool _hasPrevHeadPos; private int _teleportCooldown; private float _roundLengthSeconds; private int _lastWristSecond = int.MinValue; private int _lastWristTP = int.MinValue; private object _lastWristTeam; private bool _wristTextInit; private float _spectatorTimer; private bool _stopScheduled; private float _stopDelayRemaining; private readonly WristIndicator _wristIndicator = new WristIndicator(); private readonly TraitorBuyMenu _buyMenu = new TraitorBuyMenu(); private readonly RolesInfoMenu _rolesInfoMenu = new RolesInfoMenu(); private readonly RoleLabels _roleLabels = new RoleLabels(); private readonly HolsterHider _holsterHider = new HolsterHider(); private readonly HypnotistController _hypnotist = new HypnotistController(); private readonly List _spawnedLoadoutItems = new List(); private readonly Dictionary _lastKnownPositions = new Dictionary(); private readonly Dictionary _recentKillers = new Dictionary(); private readonly Dictionary _recentKillTime = new Dictionary(); private const float KillFreshnessSeconds = 4f; private readonly Dictionary _recentWeapons = new Dictionary(); public override string Title => "Trouble In FordTown"; public override string Author => "JonLandonMods"; public override string Barcode => "JonLandonMods.TroubleInFordTown"; public override string Description => "Trouble In Traitor Town, in BONELAB! Traitors secretly eliminate Innocents. The Detective leads the good side. New roles: Jester (trick an Innocent into killing you to become Psychopath!), Lone Wolf (be the last one standing), and Glitch (appears as Traitor but wins with Innocents)."; public int TraitorCount { get; set; } = 1; public int PrepSeconds { get; set; } = 30; public int RoundMinutes { get; set; } = 5; public bool DetectiveEnabled { get; set; } = true; public bool JesterEnabled { get; set; } = true; public bool LoneWolfEnabled { get; set; } = true; public bool GlitchEnabled { get; set; } = true; public bool HypnotistEnabled { get; set; } = true; public bool ZombieEnabled { get; set; } = true; public bool WinMusicEnabled { get; set; } = true; public bool OneStabKnifeEnabled { get; set; } public override bool DisableDevTools => true; public override bool DisableSpawnGun => true; public override bool DisableManualUnragdoll => true; public MusicPlaylist Playlist => _playlist; public TeamManager TeamManager => _teamManager; public Team TraitorTeam => _traitorTeam; public Team InnocentTeam => _innocentTeam; public Team DetectiveTeam => _detectiveTeam; public Team SpectatorTeam => _spectatorTeam; public Team JesterTeam => _jesterTeam; public Team PsychopathTeam => _psychopathTeam; public Team LoneWolfTeam => _loneWolfTeam; public Team GlitchTeam => _glitchTeam; public Team ZombieTeam => _zombieTeam; public TriggerEvent RoundStartedEvent { get; set; } public TriggerEvent OneMinuteLeftEvent { get; set; } public TriggerEvent InnocentVictoryEvent { get; set; } public TriggerEvent TraitorVictoryEvent { get; set; } public TriggerEvent PsychopathVictoryEvent { get; set; } public TriggerEvent LoneWolfVictoryEvent { get; set; } public TriggerEvent TimeUpEvent { get; set; } public TriggerEvent BrainwashEvent { get; set; } public TriggerEvent ZombieVictoryEvent { get; set; } public TriggerEvent CorpseSpawnEvent { get; set; } public override GroupElementData CreateSettingsGroup() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //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_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_003c: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0062: 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_0072: 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_0085: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00ac: 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_00bc: 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_00cf: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //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) //IL_0118: 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_013b: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //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_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_01d8: 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_01e8: 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_020b: Expected O, but got Unknown //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: 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_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown //IL_0252: 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_0262: 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_0285: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_0298: 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_02a8: 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_02dd: Expected O, but got Unknown //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //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_0303: 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_0326: Expected O, but got Unknown GroupElementData obj = ((Gamemode)this).CreateSettingsGroup(); GroupElementData val = new GroupElementData("General"); obj.AddElement(val); val.AddElement(new IntElementData { Title = "Traitor Count", Value = TraitorCount, Increment = 1, MinValue = 1, MaxValue = 4, OnValueChanged = delegate(int v) { TraitorCount = v; } }); val.AddElement(new IntElementData { Title = "Prep Time (Seconds)", Value = PrepSeconds, Increment = 5, MinValue = 5, MaxValue = 60, OnValueChanged = delegate(int v) { PrepSeconds = v; } }); val.AddElement(new IntElementData { Title = "Round Length (Minutes)", Value = RoundMinutes, Increment = 1, MinValue = 1, MaxValue = 15, OnValueChanged = delegate(int v) { RoundMinutes = v; } }); GroupElementData val2 = new GroupElementData("Extra Roles"); obj.AddElement(val2); val2.AddElement(new BoolElementData { Title = "Detective", Value = DetectiveEnabled, OnValueChanged = delegate(bool v) { DetectiveEnabled = v; } }); val2.AddElement(new BoolElementData { Title = "Jester", Value = JesterEnabled, OnValueChanged = delegate(bool v) { JesterEnabled = v; } }); val2.AddElement(new BoolElementData { Title = "Lone Wolf", Value = LoneWolfEnabled, OnValueChanged = delegate(bool v) { LoneWolfEnabled = v; } }); val2.AddElement(new BoolElementData { Title = "Glitch", Value = GlitchEnabled, OnValueChanged = delegate(bool v) { GlitchEnabled = v; } }); val2.AddElement(new BoolElementData { Title = "Hypnotist (Traitor)", Value = HypnotistEnabled, OnValueChanged = delegate(bool v) { HypnotistEnabled = v; } }); val2.AddElement(new BoolElementData { Title = "Zombie", Value = ZombieEnabled, OnValueChanged = delegate(bool v) { ZombieEnabled = v; } }); GroupElementData val3 = new GroupElementData("Win Music"); obj.AddElement(val3); val3.AddElement(new BoolElementData { Title = "Play Win Song", Value = WinMusicEnabled, OnValueChanged = delegate(bool v) { WinMusicEnabled = v; } }); GroupElementData val4 = new GroupElementData("Karma"); obj.AddElement(val4); val4.AddElement(new BoolElementData { Title = "Enable Karma System", Value = KarmaManager.Enabled, OnValueChanged = delegate(bool v) { KarmaManager.Enabled = v; } }); GroupElementData val5 = new GroupElementData("Traitor Gear"); obj.AddElement(val5); val5.AddElement(new BoolElementData { Title = "One-Stab Knife (one-hit kill)", Value = OneStabKnifeEnabled, OnValueChanged = delegate(bool v) { OneStabKnifeEnabled = v; } }); return obj; } public override bool CheckReadyConditions() { return PlayerIDManager.PlayerIDs.Count >= 2; } public override void OnGamemodeRegistered() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown MultiplayerHooking.OnPlayerAction += new PlayerAction(OnPlayerAction); FusionOverrides.OnValidateNametag += new UserOverride(OnValidateNametag); TeamManager.Register((Gamemode)(object)this); TeamManager.AddTeam(TraitorTeam); TeamManager.AddTeam(InnocentTeam); TeamManager.AddTeam(DetectiveTeam); TeamManager.AddTeam(SpectatorTeam); TeamManager.AddTeam(JesterTeam); TeamManager.AddTeam(PsychopathTeam); TeamManager.AddTeam(LoneWolfTeam); TeamManager.AddTeam(GlitchTeam); TeamManager.AddTeam(ZombieTeam); TeamManager.OnAssignedToTeam += OnAssignedToTeam; RoundStartedEvent = new TriggerEvent("RoundStarted", ((Gamemode)this).Relay, true); RoundStartedEvent.OnTriggeredWithValue += OnRoundStarted; OneMinuteLeftEvent = new TriggerEvent("OneMinuteLeft", ((Gamemode)this).Relay, true); OneMinuteLeftEvent.OnTriggered += OnOneMinuteLeft; InnocentVictoryEvent = new TriggerEvent("InnocentVictory", ((Gamemode)this).Relay, true); InnocentVictoryEvent.OnTriggered += OnInnocentVictory; TraitorVictoryEvent = new TriggerEvent("TraitorVictory", ((Gamemode)this).Relay, true); TraitorVictoryEvent.OnTriggered += OnTraitorVictory; PsychopathVictoryEvent = new TriggerEvent("PsychopathVictory", ((Gamemode)this).Relay, true); PsychopathVictoryEvent.OnTriggered += OnPsychopathVictory; LoneWolfVictoryEvent = new TriggerEvent("LoneWolfVictory", ((Gamemode)this).Relay, true); LoneWolfVictoryEvent.OnTriggered += OnLoneWolfVictory; TimeUpEvent = new TriggerEvent("TimeUp", ((Gamemode)this).Relay, true); TimeUpEvent.OnTriggered += OnTimeUp; ZombieVictoryEvent = new TriggerEvent("ZombieVictory", ((Gamemode)this).Relay, true); ZombieVictoryEvent.OnTriggered += OnZombieVictory; BrainwashEvent = new TriggerEvent("Brainwash", ((Gamemode)this).Relay, false); BrainwashEvent.OnTriggeredWithValue += OnBrainwash; CorpseSpawnEvent = new TriggerEvent("CorpseSpawn", ((Gamemode)this).Relay, false); CorpseSpawnEvent.OnTriggeredWithValue += OnCorpseSpawn; try { _buyMenu.Register(this); } catch (Exception ex) { MelonLogger.Warning("[FordTown] Traitor Shop menu unavailable: " + ex.Message); } try { _rolesInfoMenu.Register(); } catch (Exception ex2) { MelonLogger.Warning("[FordTown] Roles Info menu unavailable: " + ex2.Message); } try { WinMusic.Initialize(); } catch (Exception ex3) { MelonLogger.Warning("[FordTown] Win music unavailable: " + ex3.Message); } HypnotistController hypnotist = _hypnotist; hypnotist.OnBrainwashComplete = (Action)Delegate.Combine(hypnotist.OnBrainwashComplete, (Action)delegate(ushort targetId) { //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_0023: 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_0033: 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_0044: 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: Expected O, but got Unknown try { BrainwashEvent.TryInvoke(targetId.ToString()); } catch { } Notifier.Send(new Notification { Title = NotificationText.op_Implicit("BRAINWASH COMPLETE!"), Message = NotificationText.op_Implicit("Their corpse has been turned into a Traitor."), ShowPopup = true, PopupLength = 4f, Type = (NotificationType)0 }); }); LocalHealth.OnRespawn += OnLocalRespawn; } private void OnLocalRespawn() { if (!((Gamemode)this).IsStarted) { return; } try { LocalPlayer.ReleaseGrips(); } catch { } } public override void OnGamemodeUnregistered() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown MultiplayerHooking.OnPlayerAction -= new PlayerAction(OnPlayerAction); FusionOverrides.OnValidateNametag -= new UserOverride(OnValidateNametag); LocalHealth.OnRespawn -= OnLocalRespawn; TeamManager.Unregister(); TeamManager.OnAssignedToTeam -= OnAssignedToTeam; RoundStartedEvent.UnregisterEvent(); RoundStartedEvent = null; OneMinuteLeftEvent.UnregisterEvent(); OneMinuteLeftEvent = null; InnocentVictoryEvent.UnregisterEvent(); InnocentVictoryEvent = null; TraitorVictoryEvent.UnregisterEvent(); TraitorVictoryEvent = null; PsychopathVictoryEvent.UnregisterEvent(); PsychopathVictoryEvent = null; LoneWolfVictoryEvent.UnregisterEvent(); LoneWolfVictoryEvent = null; TimeUpEvent.UnregisterEvent(); TimeUpEvent = null; ZombieVictoryEvent.UnregisterEvent(); ZombieVictoryEvent = null; BrainwashEvent.UnregisterEvent(); BrainwashEvent = null; CorpseSpawnEvent.UnregisterEvent(); CorpseSpawnEvent = null; _hypnotist.Cleanup(); try { _buyMenu.Unregister(); } catch { } try { _rolesInfoMenu.Unregister(); } catch { } } public override void OnGamemodeStarted() { //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_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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_020d: 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_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Expected O, but got Unknown ((Gamemode)this).OnGamemodeStarted(); _roundStarted = false; _elapsedTime = 0f; _oneMinuteLeft = false; _gameEnded = false; _localDied = false; _hasLocalDeathPos = false; _hasLastAlivePos = false; _hasPrevHeadPos = false; _teleportCooldown = 0; _wristTextInit = false; _spectatorTimer = 0f; _brainwashGunGiven = false; _brainwashGunRetry = 0f; _hypnotistSmallID = 0; _roundLengthSeconds = 0f; _spawnedLoadoutItems.Clear(); _lastKnownPositions.Clear(); _recentKillers.Clear(); _recentKillTime.Clear(); _recentWeapons.Clear(); _deadPlayers.Clear(); _killedJesterTime = -999f; _localPrimaryBarcode = null; _oneStabKnife = null; OneStabState.LocalHolding = false; if (KarmaManager.Enabled) { foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { KarmaManager.EnsurePlayer(playerID); } } if (NetworkInfo.IsHost) { try { ((Gamemode)this).Metadata.TrySetMetadata("tift_music", WinMusicEnabled ? "1" : "0"); } catch { } try { ((Gamemode)this).Metadata.TrySetMetadata("tift_onestab", OneStabKnifeEnabled ? "1" : "0"); } catch { } try { ((Gamemode)this).Metadata.TrySetMetadata("tift_hypnotist", "0"); } catch { } } LocalHealth.MortalityOverride = true; LocalControls.DisableSlowMo = true; GamemodeHelper.SetSpawnPoints((IEnumerable)GamemodeMarker.FilterMarkers((BoneTagReference)null)); GamemodeHelper.TeleportToSpawnPoint(); FusionOverrides.ForceUpdateOverrides(); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Trouble In FordTown"), Message = NotificationText.op_Implicit($"Roles will be assigned in {PrepSeconds} seconds. Get ready!"), ShowPopup = true, PopupLength = 5f, Type = (NotificationType)0 }); } public override void OnGamemodeStopped() { ((Gamemode)this).OnGamemodeStopped(); _roundStarted = false; _elapsedTime = 0f; _oneMinuteLeft = false; _localDied = false; _deadPlayers.Clear(); _oneStabKnife = null; OneStabState.LocalHolding = false; ClearSpectatorEffects(); _wristIndicator.Destroy(); _roleLabels.ClearAll(); _holsterHider.ClearAll(); ZombieState.LocalIsZombie = false; CorpseManager.ClearAll(); CorpseManager.DestroyUI(); TraitorShopRadial.RemoveMenuItems(); CustomWeapons.Reset(); TraitorPoints.Clear(); DespawnLoadoutItems(); Playlist.StopPlaylist(); LocalHealth.MortalityOverride = null; LocalHealth.VitalityOverride = null; LocalControls.DisableSlowMo = false; GamemodeHelper.ResetSpawnPoints(); if (NetworkInfo.IsHost) { TeamManager.UnassignAllPlayers(); } FusionOverrides.ForceUpdateOverrides(); _buyMenu.Refresh(); } protected override void OnUpdate() { //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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00be: 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_00ca: 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_00fb: 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_0109: Unknown result type (might be due to invalid IL or missing references) if (!((Gamemode)this).IsStarted) { return; } _elapsedTime += TimeReferences.DeltaTime; ZombieState.LocalIsZombie = _roundStarted && TeamManager.GetLocalTeam() == ZombieTeam; OneStabState.LocalHolding = _roundStarted && (Object)(object)_oneStabKnife != (Object)null && IsHeldByLocal(_oneStabKnife); if (_roundStarted && !_localDied && RigData.HasPlayer) { try { Transform headset = RigData.Refs.Headset; if ((Object)(object)headset != (Object)null) { Vector3 val = headset.position - Vector3.up * 0.6f; if (_hasPrevHeadPos) { Vector3 val2 = val - _prevHeadPos; if (((Vector3)(ref val2)).sqrMagnitude > 6.25f) { _teleportCooldown = 8; } } if (_teleportCooldown > 0) { _teleportCooldown--; } else { _localLastAlivePos = val; _hasLastAlivePos = true; } _prevHeadPos = val; _hasPrevHeadPos = true; } } catch { } } UpdateSpectators(); UpdateWristIndicator(); CorpseManager.Update(); _roleLabels.Update(this); if (_roundStarted) { _holsterHider.Update(); } if (_roundStarted && TeamManager.GetLocalTeam() == TraitorTeam && IsLocalHypnotist()) { if (!_brainwashGunGiven) { _brainwashGunRetry -= TimeReferences.DeltaTime; if (_brainwashGunRetry <= 0f) { _brainwashGunRetry = 1.5f; if (LocalHasBrainwashGun()) { _brainwashGunGiven = true; } else if (RigData.HasPlayer) { GiveBrainwashGun(); } } } _hypnotist.Update("JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun"); } if (NetworkInfo.IsHost && _stopScheduled) { _stopDelayRemaining -= TimeReferences.DeltaTime; if (_stopDelayRemaining <= 0f) { _stopScheduled = false; GamemodeManager.StopGamemode(); } } if (!NetworkInfo.IsHost || _gameEnded) { return; } if (!_roundStarted && _elapsedTime >= (float)PrepSeconds) { AssignRoles(); _roundStarted = true; _elapsedTime = 0f; RoundStartedEvent.TryInvoke(RoundMinutes.ToString()); } if (_roundStarted) { float num = (float)RoundMinutes * 60f; if (!_oneMinuteLeft && num - _elapsedTime <= 60f) { _oneMinuteLeft = true; OneMinuteLeftEvent.TryInvoke(); } if (_elapsedTime >= num) { _gameEnded = true; TimeUpEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled)); } } } private void AssignRoles() { List list = new List(PlayerIDManager.PlayerIDs); IEnumerableExtensions.Shuffle((IList)list); int count = list.Count; int num = Math.Min(TraitorCount, Math.Max(1, count / 3)); for (int i = 0; i < num; i++) { if (list.Count <= 0) { break; } TeamManager.TryAssignTeam(list[0], TraitorTeam); list.RemoveAt(0); } if (DetectiveEnabled && list.Count >= 2) { TeamManager.TryAssignTeam(list[0], DetectiveTeam); list.RemoveAt(0); } if (count >= 4 && JesterEnabled && list.Count > 1) { TeamManager.TryAssignTeam(list[0], JesterTeam); list.RemoveAt(0); } if (count >= 4 && LoneWolfEnabled && list.Count > 1) { TeamManager.TryAssignTeam(list[0], LoneWolfTeam); list.RemoveAt(0); } if (count >= 4 && GlitchEnabled && list.Count > 1) { TeamManager.TryAssignTeam(list[0], GlitchTeam); list.RemoveAt(0); } if (count >= 4 && ZombieEnabled && list.Count > 1) { TeamManager.TryAssignTeam(list[0], ZombieTeam); list.RemoveAt(0); } _hypnotistSmallID = 0; if (count >= 4 && HypnotistEnabled && list.Count > 1) { PlayerID val = list[0]; TeamManager.TryAssignTeam(val, TraitorTeam); _hypnotistSmallID = val.SmallID; list.RemoveAt(0); try { ((Gamemode)this).Metadata.TrySetMetadata("tift_hypnotist", _hypnotistSmallID.ToString()); } catch { } } else { try { ((Gamemode)this).Metadata.TrySetMetadata("tift_hypnotist", "0"); } catch { } } foreach (PlayerID item in list) { TeamManager.TryAssignTeam(item, InnocentTeam); } } private void UpdateSpectators() { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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) bool flag = _roundStarted && SpectatorTeam.HasPlayer(PlayerIDManager.LocalID); if (flag && RigData.HasPlayer) { try { PhysicsRig physicsRig = RigData.Refs.RigManager.physicsRig; Hand leftHand = physicsRig.leftHand; if ((Object)(object)((leftHand != null) ? leftHand.m_CurrentAttachedGO : null) != (Object)null) { HandExtensions.TryDetach(physicsRig.leftHand); } Hand rightHand = physicsRig.rightHand; if ((Object)(object)((rightHand != null) ? rightHand.m_CurrentAttachedGO : null) != (Object)null) { HandExtensions.TryDetach(physicsRig.rightHand); } } catch { } } _spectatorTimer -= TimeReferences.DeltaTime; if (_spectatorTimer > 0f) { return; } _spectatorTimer = 0.1f; NetworkPlayer val = default(NetworkPlayer); foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID.IsMe || !NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val)) { continue; } bool flag2 = _roundStarted && SpectatorTeam.HasPlayer(playerID); bool num = flag2 || _deadPlayers.Contains(playerID.SmallID); if (val.ForceHide != flag2) { val.ForceHide = flag2; } bool flag3 = _localDied || flag; bool flag4 = num && !flag3; RigVoiceSource voiceSource = val.VoiceSource; VoiceSource val2 = ((voiceSource != null) ? voiceSource.VoiceSource : null); if ((Object)(object)val2 != (Object)null && val2.Muted != flag4) { val2.Muted = flag4; } try { RigRefs rigRefs = val.RigRefs; Transform val3 = ((rigRefs != null) ? rigRefs.Headset : null); if ((Object)(object)val3 != (Object)null) { _lastKnownPositions[playerID.SmallID] = val3.position - Vector3.up * 0.6f; } } catch { } } } private void ClearSpectatorEffects() { NetworkPlayer val = default(NetworkPlayer); foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (!playerID.IsMe && NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val)) { val.ForceHide = false; RigVoiceSource voiceSource = val.VoiceSource; VoiceSource val2 = ((voiceSource != null) ? voiceSource.VoiceSource : null); if ((Object)(object)val2 != (Object)null) { val2.Muted = false; } } } } private void UpdateWristIndicator() { if (_wristIndicator.TryCreate()) { int num = (_roundStarted ? Mathf.CeilToInt(Mathf.Max(_roundLengthSeconds - _elapsedTime, 0f)) : (-1)); int points = TraitorPoints.Points; object obj = (_roundStarted ? TeamManager.GetLocalTeam() : null); if (!_wristTextInit || num != _lastWristSecond || points != _lastWristTP || obj != _lastWristTeam) { _wristTextInit = true; _lastWristSecond = num; _lastWristTP = points; _lastWristTeam = obj; _wristIndicator.SetText(GetWristText()); } _wristIndicator.Update(); } } private string GetWristText() { if (!_roundStarted) { return "GET READY\nRoles incoming..."; } string text = TimeSpan.FromSeconds(Mathf.Max(_roundLengthSeconds - _elapsedTime, 0f)).ToString("mm\\:ss"); Team localTeam = TeamManager.GetLocalTeam(); string text2 = ((localTeam == TraitorTeam && IsLocalHypnotist()) ? $"HYPNOTIST\nTP: {TraitorPoints.Points}" : ((localTeam == TraitorTeam) ? $"TRAITOR\nTP: {TraitorPoints.Points}" : ((localTeam == DetectiveTeam) ? "DETECTIVE" : ((localTeam == InnocentTeam) ? "INNOCENT" : ((localTeam == JesterTeam) ? "JESTER" : ((localTeam == PsychopathTeam) ? "PSYCHOPATH" : ((localTeam == LoneWolfTeam) ? "LONE WOLF" : ((localTeam == GlitchTeam) ? "GLITCH" : ((localTeam == ZombieTeam) ? "ZOMBIE" : ((localTeam != SpectatorTeam) ? "NO ROLE" : "SPECTATING")))))))))); return text2 + "\n" + text; } private void SpawnLoadout() { Team localTeam = TeamManager.GetLocalTeam(); if (localTeam != SpectatorTeam && localTeam != ZombieTeam) { Random random = new Random(); string item = Defaults.Sidearms[random.Next(Defaults.Sidearms.Length)]; string item2 = (_localPrimaryBarcode = Defaults.Primaries[random.Next(Defaults.Primaries.Length)]); List<(string, bool)> queue = new List<(string, bool)> { (item, true), (item2, false) }; SpawnLoadoutQueue(queue, 0); } } public void GiveTraitorKnife() { GiveKnife(useOneStabIfEnabled: true); } public void GiveZombieKnife() { GiveKnife(useOneStabIfEnabled: false); } private void GiveKnife(bool useOneStabIfEnabled) { bool oneStab = useOneStabIfEnabled && OneStabEnabledByHost(); if (oneStab && !SpawnableExists("JonLandon.TFTknife.Spawnable.TFTknife")) { MelonLogger.Warning("[FordTown] One-stab knife 'JonLandon.TFTknife.Spawnable.TFTknife' is not a loaded spawnable — the mod isn't installed, or the barcode is the pallet barcode instead of the CRATE/spawnable barcode (should look like Author.Pallet.Spawnable.Name). Giving the default knife instead."); oneStab = false; } string barcode = (oneStab ? "JonLandon.TFTknife.Spawnable.TFTknife" : "c1534c5a-1fb8-477c-afbe-2a95436f6d62"); SpawnLoadoutItem(barcode, preferLowSlot: true, null, delegate(GameObject go) { HolsterHider.RegisterLocalKnife(go); if (oneStab) { _oneStabKnife = go; } }); } private static bool SpawnableExists(string barcode) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (string.IsNullOrEmpty(barcode)) { return false; } try { AssetWarehouse instance = AssetWarehouse.Instance; return instance != null && instance.HasCrate(new Barcode(barcode)); } catch { return false; } } private void MakeOneStabKnifeUngrabbable() { GameObject oneStabKnife = _oneStabKnife; _oneStabKnife = null; OneStabState.LocalHolding = false; if ((Object)(object)oneStabKnife == (Object)null) { return; } try { LocalPlayer.ReleaseGrips(); } catch { } try { foreach (Grip componentsInChild in oneStabKnife.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null) { try { ((Behaviour)componentsInChild).enabled = false; } catch { } } } } catch { } } private void SpawnLoadoutQueue(List<(string barcode, bool low)> queue, int index) { if (index < queue.Count) { var (barcode, preferLowSlot) = queue[index]; SpawnLoadoutItem(barcode, preferLowSlot, delegate { SpawnLoadoutQueue(queue, index + 1); }); } } private void SpawnLoadoutItem(string barcode, bool preferLowSlot = false, Action onDone = null, Action onSpawned = null) { //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_006f: 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_0074: 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_0080: 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_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_009e: 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_00b8: 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_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_00e5: Unknown result type (might be due to invalid IL or missing references) if (!RigData.HasPlayer) { onDone?.Invoke(); return; } Transform headset = RigData.Refs.Headset; Vector3 val = headset.forward; val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val)).normalized : Vector3.forward); Vector3 position = headset.position + val * 0.5f - Vector3.up * 0.55f; Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode); NetworkAssetSpawner.Spawn(new SpawnRequestInfo { Spawnable = spawnable, Position = position, Rotation = Quaternion.identity, SpawnEffect = false, SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_000d: 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) GameObject val2 = null; try { _spawnedLoadoutItems.Add(info.Entity.ID); val2 = info.Spawned; } catch { } try { onSpawned?.Invoke(val2); } catch { } if ((Object)(object)val2 != (Object)null) { MelonCoroutines.Start(HolsterAfterInit(val2, preferLowSlot)); } onDone?.Invoke(); } }); } private IEnumerator HolsterAfterInit(GameObject item, bool preferLowSlot) { yield return (object)new WaitForSeconds(0.2f); if (!((Object)(object)item == (Object)null) && !IsHeldByLocal(item)) { TryHolster(item, preferLowSlot); } } private static bool IsHeldByLocal(GameObject go) { if ((Object)(object)go == (Object)null || !RigData.HasPlayer) { return false; } try { PhysicsRig physicsRig = RigData.Refs.RigManager.physicsRig; Hand[] array = (Hand[])(object)new Hand[2] { physicsRig.leftHand, physicsRig.rightHand }; foreach (Hand obj in array) { GameObject val = ((obj != null) ? obj.m_CurrentAttachedGO : null); if (!((Object)(object)val == (Object)null) && ((Object)(object)val == (Object)(object)go || val.transform.IsChildOf(go.transform) || go.transform.IsChildOf(val.transform))) { return true; } } } catch { } return false; } private void GiveBrainwashGun() { //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_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) //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_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_0060: Expected O, but got Unknown if (string.IsNullOrEmpty("JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun")) { _brainwashGunGiven = true; MelonLogger.Warning("[FordTown] Hypnotist assigned but BrainwashGunBarcode is not set — no gun spawned."); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE HYPNOTIST!"), Message = NotificationText.op_Implicit("Brainwash a dead Innocent back to life as a Traitor by aiming your gun at their corpse."), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); return; } SpawnLoadoutItem("JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun", preferLowSlot: false, null, delegate(GameObject go) { //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_001c: 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_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_003d: 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_0054: Expected O, but got Unknown if (!((Object)(object)go == (Object)null)) { _brainwashGunGiven = true; Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE HYPNOTIST!"), Message = NotificationText.op_Implicit("Aim your brainwashing gun at a dead Innocent's corpse for 10s to revive them as a Traitor."), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); } }); } private bool LocalHasBrainwashGun() { if (!RigData.HasPlayer) { return false; } try { foreach (Poolee componentsInChild in ((Component)RigData.Refs.RigManager).GetComponentsInChildren(true)) { object obj; if (componentsInChild == null) { obj = null; } else { SpawnableCrate spawnableCrate = componentsInChild.SpawnableCrate; if (spawnableCrate == null) { obj = null; } else { Barcode barcode = ((Scannable)spawnableCrate).Barcode; obj = ((barcode != null) ? barcode.ID : null); } } if ((string?)obj == "JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun") { return true; } } } catch { } return false; } public void TryHolster(GameObject item, bool preferLowSlot = false) { //IL_0075: 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_0080: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || !RigData.HasPlayer) { return; } WeaponSlot componentInChildren = item.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.interactableHost == (Object)null) { return; } List list = new List(); InventorySlotReceiver[] rigSlots = RigData.Refs.RigSlots; foreach (InventorySlotReceiver val in rigSlots) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val._slottedWeapon != (Object)null) && (val.slotType & componentInChildren.slotType) != 0) { list.Add(val); } } try { list.Sort(delegate(InventorySlotReceiver a, InventorySlotReceiver b) { //IL_0006: 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) float y = ((Component)a).transform.position.y; float y2 = ((Component)b).transform.position.y; return (!preferLowSlot) ? y2.CompareTo(y) : y.CompareTo(y2); }); } catch { } foreach (InventorySlotReceiver item2 in list) { try { item2.InsertInSlot(componentInChildren.interactableHost); } catch { continue; } if ((Object)(object)item2._slottedWeapon != (Object)null) { return; } } rigSlots = RigData.Refs.RigSlots; foreach (InventorySlotReceiver val2 in rigSlots) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2._slottedWeapon != (Object)null)) { try { val2.InsertInSlot(componentInChildren.interactableHost); } catch { continue; } if ((Object)(object)val2._slottedWeapon != (Object)null) { break; } } } } private void DespawnLoadoutItems() { //IL_0022: 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) try { LocalPlayer.ReleaseGrips(); } catch { } foreach (ushort spawnedLoadoutItem in _spawnedLoadoutItems) { NetworkAssetSpawner.Despawn(new DespawnRequestInfo { EntityID = spawnedLoadoutItem, DespawnEffect = false }); } _spawnedLoadoutItems.Clear(); } private void OnAssignedToTeam(PlayerID player, Team team) { //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) //IL_00b9: 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_00cf: 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_00e0: 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: Expected O, but got Unknown //IL_01f2: 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_01fd: 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_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: 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_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: 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_01d1: 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_01e8: Expected O, but got Unknown //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_024a: 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_025a: 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_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Expected O, but got Unknown //IL_0151: 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) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0297: 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_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Expected O, but got Unknown //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_016c: 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: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_02dc: 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_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0301: 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_0313: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Expected O, but got Unknown //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_038c: 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_039c: 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_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Expected O, but got Unknown //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03df: 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_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Expected O, but got Unknown //IL_0455: 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_0460: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0445: 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_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Expected O, but got Unknown //IL_0500: 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_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Expected O, but got Unknown //IL_054f: Unknown result type (might be due to invalid IL or missing references) FusionOverrides.ForceUpdateOverrides(); if (player.IsMe && team != null && !_roundStarted) { _roundStarted = true; } if (KarmaManager.Enabled) { KarmaManager.EnsurePlayer(player); } if (team == PsychopathTeam || team == ZombieTeam) { try { CorpseManager.RemoveCorpseOf(player.SmallID); } catch { } } if (team == SpectatorTeam) { _deadPlayers.Add(player.SmallID); } else if (team != null) { _deadPlayers.Remove(player.SmallID); } if (player.IsMe) { _buyMenu.Refresh(); } if (team == DetectiveTeam && !player.IsMe) { string text = default(string); MetadataHelper.TryGetDisplayName(player, ref text); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("DETECTIVE"), Message = NotificationText.op_Implicit(text + " is the Detective!"), ShowPopup = true, PopupLength = 5f, Type = (NotificationType)0 }); } if (!player.IsMe) { return; } if (team == TraitorTeam) { TraitorShopRadial.AddMenuItems(this); } else { TraitorShopRadial.RemoveMenuItems(); } if (team == TraitorTeam) { if (_localDied) { _localDied = false; LocalHealth.MortalityOverride = true; LocalHealth.SetFullHealth(); MelonCoroutines.Start(ReviveAtPositionRoutine(_hasLocalDeathPos ? _localDeathPos : Vector3.zero)); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU'VE BEEN BRAINWASHED!"), Message = NotificationText.op_Implicit("The Hypnotist revived you — you are now a TRAITOR. Eliminate the Innocents!"), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); } else { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE A TRAITOR!"), Message = NotificationText.op_Implicit("Eliminate all Innocents. Open the Traitor Shop in the radial menu!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); } } else if (team == InnocentTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE INNOCENT!"), Message = NotificationText.op_Implicit("Find and eliminate the Traitors!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); } else if (team == DetectiveTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE DETECTIVE!"), Message = NotificationText.op_Implicit("Lead the Innocents and find the Traitors!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); } else if (team == JesterTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE JESTER!"), Message = NotificationText.op_Implicit("Trick an Innocent into killing you to become the Psychopath! If a Traitor kills you instead, you lose."), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); } else if (team == PsychopathTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE NOW THE PSYCHOPATH!"), Message = NotificationText.op_Implicit("Second chance! Kill everyone to win!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); LocalHealth.MortalityOverride = true; LocalHealth.VitalityOverride = 1.5f; try { GamemodeHelper.TeleportToSpawnPoint(); } catch { } MelonCoroutines.Start(RevicePsychopathRoutine()); if (!string.IsNullOrEmpty(_localPrimaryBarcode)) { SpawnLoadoutItem(_localPrimaryBarcode); } } else if (team == LoneWolfTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE LONE WOLF!"), Message = NotificationText.op_Implicit("Kill everyone and be the last one standing to win!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); } else if (team == GlitchTeam) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE THE GLITCH!"), Message = NotificationText.op_Implicit("You appear as a Traitor to Traitors — but you're secretly Innocent. Help Innocents win from the inside!"), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); } else if (team == ZombieTeam) { bool localDied = _localDied; if (localDied) { _localDied = false; LocalHealth.MortalityOverride = true; LocalHealth.SetFullHealth(); MelonCoroutines.Start(ReviveAtPositionRoutine(_hasLocalDeathPos ? _localDeathPos : Vector3.zero)); } Notifier.Send(new Notification { Title = NotificationText.op_Implicit("YOU ARE A ZOMBIE!"), Message = NotificationText.op_Implicit(localDied ? "You've been infected! Stab others with your knife to turn them into Zombies too." : "Patient zero! Stab others with your knife to spread the infection. Turn everyone!"), ShowPopup = true, PopupLength = 8f, Type = (NotificationType)0 }); GiveZombieKnife(); } else { if (team != SpectatorTeam || !_roundStarted) { return; } bool num = Time.time - _killedJesterTime <= 5f; _killedJesterTime = -999f; string text2 = (num ? "THE JESTER TRICKED YOU!" : "YOU ARE NOW SPECTATING"); string text3 = (num ? "You killed the Jester — now you pay for it. Spectate until the round ends." : "You can hear other dead players. Wait for the round to end."); Notifier.Send(new Notification { Title = NotificationText.op_Implicit(text2), Message = NotificationText.op_Implicit(text3), ShowPopup = true, PopupLength = 5f, Type = (NotificationType)1 }); LocalHealth.MortalityOverride = false; if (!_hasLocalDeathPos) { try { GamemodeHelper.TeleportToSpawnPoint(); return; } catch { return; } } MelonCoroutines.Start(MoveSpectatorToBodyRoutine(_localDeathPos)); } } private static IEnumerator MoveSpectatorToBodyRoutine(Vector3 bodyPos) { //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) Vector3 target = bodyPos + new Vector3(0.9f, 0.75f, 0f); yield return (object)new WaitForSeconds(0.25f); for (int i = 0; i < 16; i++) { try { if (RigData.HasPlayer) { RigManagerExtensions.TeleportToPosition(RigData.Refs.RigManager, target, true); } } catch { } yield return (object)new WaitForSeconds(0.1f); } } private void OnRoundStarted(string value) { //IL_0151: 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_015c: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown //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_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_0235: 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_0246: 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_025d: Expected O, but got Unknown _roundStarted = true; _elapsedTime = 0f; _roundLengthSeconds = (int.TryParse(value, out var result) ? ((float)result * 60f) : 300f); SpawnLoadout(); if (TeamManager.GetLocalTeam() != SpectatorTeam) { LocalInventory.SetAmmo(100000); } if (TeamManager.GetLocalTeam() != TraitorTeam) { return; } TraitorPoints.Reset(); _buyMenu.Refresh(); List list = new List(); string item = default(string); foreach (byte player in TraitorTeam.Players) { PlayerID val = FindPlayerBySmallID(player); if (val != null && !val.IsMe && MetadataHelper.TryGetDisplayName(val, ref item)) { list.Add(item); } } string item2 = default(string); foreach (byte player2 in GlitchTeam.Players) { PlayerID val2 = FindPlayerBySmallID(player2); if (val2 != null && MetadataHelper.TryGetDisplayName(val2, ref item2)) { list.Add(item2); } } string text = ((list.Count > 0) ? ("Your crew: " + string.Join(", ", list)) : "You are the only Traitor."); Notifier.Send(new Notification { Title = NotificationText.op_Implicit("TRAITORS"), Message = NotificationText.op_Implicit(text), ShowPopup = true, PopupLength = 7f, Type = (NotificationType)0 }); if (JesterTeam.PlayerCount <= 0) { return; } List list2 = new List(); string item3 = default(string); foreach (byte player3 in JesterTeam.Players) { PlayerID val3 = FindPlayerBySmallID(player3); if (val3 != null && MetadataHelper.TryGetDisplayName(val3, ref item3)) { list2.Add(item3); } } if (list2.Count > 0) { Notifier.Send(new Notification { Title = NotificationText.op_Implicit("JESTER ALERT"), Message = NotificationText.op_Implicit("Jester: " + string.Join(", ", list2) + " — if an Innocent kills them, they become Psychopath!"), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)1 }); } } private void OnPlayerAction(PlayerID player, PlayerActionType type, PlayerID otherPlayer = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Invalid comparison between Unknown and I4 if (!((Gamemode)this).IsStarted || _gameEnded) { return; } if ((int)type == 5 && otherPlayer != null) { _recentKillers[player.SmallID] = otherPlayer.SmallID; _recentKillTime[player.SmallID] = Time.time; RigManager rig = null; NetworkPlayer val = default(NetworkPlayer); if (otherPlayer.IsMe) { rig = RigData.Refs.RigManager; } else if (NetworkPlayerManager.TryGetPlayer(otherPlayer.SmallID, ref val)) { RigRefs rigRefs = val.RigRefs; rig = ((rigRefs != null) ? rigRefs.RigManager : null); } string value = TryGetHeldWeaponName(rig); if (!string.IsNullOrEmpty(value)) { _recentWeapons[player.SmallID] = value; } } if ((int)type != 2) { if ((int)type == 5) { OnPlayerKilled(player, otherPlayer); } } else { OnPlayerDeath(player); } } private void OnPlayerDeath(PlayerID player) { //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if (_roundStarted) { _deadPlayers.Add(player.SmallID); } if (player.IsMe) { _localDied = true; try { _localDeathPos = GetDeathPosition(player); _hasLocalDeathPos = true; } catch { } try { LocalPlayer.ReleaseGrips(); } catch { } } if (_roundStarted && player.IsMe) { Team playerTeam = TeamManager.GetPlayerTeam(player); string text; string text2; if (playerTeam == TraitorTeam) { text = "Traitor"; text2 = "#ff3333"; } else if (playerTeam == DetectiveTeam) { text = "Detective"; text2 = "#3399ff"; } else if (playerTeam == JesterTeam) { text = "Jester"; text2 = "#ff69b4"; } else if (playerTeam == PsychopathTeam) { text = "Psychopath"; text2 = "#cc0000"; } else if (playerTeam == LoneWolfTeam) { text = "Lone Wolf"; text2 = "#ff8c00"; } else if (playerTeam == GlitchTeam) { text = "Innocent"; text2 = "#33ff33"; } else if (playerTeam == ZombieTeam) { text = "Zombie"; text2 = "#5ecc1a"; } else if (playerTeam == SpectatorTeam) { text = "Spectator"; text2 = "#aaaaaa"; } else { text = "Innocent"; text2 = "#33ff33"; } string value; string text3 = (_recentWeapons.TryGetValue(player.SmallID, out value) ? value : ""); string text4 = ""; try { text4 = RigData.GetAvatarBarcode() ?? ""; } catch { } Vector3 val = (_hasLocalDeathPos ? _localDeathPos : GetDeathPosition(player)); CultureInfo invariantCulture = CultureInfo.InvariantCulture; string text5 = string.Join("|", player.SmallID.ToString(), val.x.ToString(invariantCulture), val.y.ToString(invariantCulture), val.z.ToString(invariantCulture), text, text2, text3, text4); try { CorpseSpawnEvent.TryInvoke(text5); } catch { } } if (KarmaManager.Enabled) { KarmaManager.AwardRoundBonus(player); } if (!NetworkInfo.IsHost || !_roundStarted) { return; } if (JesterTeam.HasPlayer(player)) { switch (ResolveJesterDeath(player)) { case JesterDeath.BecamePsychopath: return; case JesterDeath.NoKillerYet: MelonCoroutines.Start(ResolveJesterDeathLater(player)); return; } } FinishDeathResolution(player); } private JesterDeath ResolveJesterDeath(PlayerID player) { if (!_recentKillTime.TryGetValue(player.SmallID, out var value) || !(Time.time - value <= 4f) || !_recentKillers.TryGetValue(player.SmallID, out var value2)) { return JesterDeath.NoKillerYet; } PlayerID val = FindPlayerBySmallID(value2); Team val2 = ((val != null) ? TeamManager.GetPlayerTeam(val) : null); if (val2 == null) { return JesterDeath.NoKillerYet; } _recentKillers.Remove(player.SmallID); _recentKillTime.Remove(player.SmallID); if (val2 == InnocentTeam || val2 == DetectiveTeam || val2 == GlitchTeam) { TeamManager.TryAssignTeam(player, PsychopathTeam); if (val != null && !SpectatorTeam.HasPlayer(val)) { TeamManager.TryAssignTeam(val, SpectatorTeam); } CheckWinConditions(); return JesterDeath.BecamePsychopath; } return JesterDeath.KilledByEnemy; } private IEnumerator ResolveJesterDeathLater(PlayerID player) { float deadline = Time.time + 2f; while (Time.time < deadline) { yield return (object)new WaitForSeconds(0.15f); if (player == null || !((Gamemode)this).IsStarted || !NetworkInfo.IsHost || !JesterTeam.HasPlayer(player)) { yield break; } JesterDeath jesterDeath = ResolveJesterDeath(player); if (jesterDeath == JesterDeath.BecamePsychopath) { yield break; } if (jesterDeath == JesterDeath.KilledByEnemy) { break; } } if (((Gamemode)this).IsStarted && NetworkInfo.IsHost && JesterTeam.HasPlayer(player)) { FinishDeathResolution(player); } } private void FinishDeathResolution(PlayerID player) { if (!ZombieTeam.HasPlayer(player) && _recentKillTime.TryGetValue(player.SmallID, out var value) && Time.time - value <= 4f && _recentKillers.TryGetValue(player.SmallID, out var value2)) { PlayerID val = FindPlayerBySmallID(value2); if (val != null && ZombieTeam.HasPlayer(val)) { _recentKillers.Remove(player.SmallID); _recentKillTime.Remove(player.SmallID); TeamManager.TryAssignTeam(player, ZombieTeam); CheckWinConditions(); return; } } if (!SpectatorTeam.HasPlayer(player)) { TeamManager.TryAssignTeam(player, SpectatorTeam); } CheckWinConditions(player); } private void OnPlayerKilled(PlayerID victim, PlayerID killer) { if (killer == null || !killer.IsMe || victim.IsMe || !_roundStarted) { return; } Team localTeam = TeamManager.GetLocalTeam(); Team playerTeam = TeamManager.GetPlayerTeam(victim); if (playerTeam == SpectatorTeam) { return; } if ((Object)(object)_oneStabKnife != (Object)null && IsHeldByLocal(_oneStabKnife)) { MakeOneStabKnifeUngrabbable(); } if (playerTeam == JesterTeam && (localTeam == InnocentTeam || localTeam == DetectiveTeam || localTeam == GlitchTeam)) { _killedJesterTime = Time.time; } bool flag = localTeam == TraitorTeam; bool flag2 = localTeam == GlitchTeam; bool flag3 = playerTeam == TraitorTeam; bool flag4 = playerTeam == GlitchTeam; bool flag5 = playerTeam == InnocentTeam || playerTeam == DetectiveTeam; if (flag && flag4) { return; } bool flag6 = (flag && !flag3) || (!flag && !flag2 && flag3) || (flag2 && flag3); if (flag6) { PointItemManager.RewardBits(50, true); } if (KarmaManager.Enabled) { if (flag6) { KarmaManager.AdjustKarma(PlayerIDManager.LocalID, 200); } else if (flag && flag3) { KarmaManager.AdjustKarma(PlayerIDManager.LocalID, -400); } else if (!flag && flag5) { KarmaManager.AdjustKarma(PlayerIDManager.LocalID, -300); } } if (flag && !flag3 && !flag4) { TraitorPoints.AddKillReward(); } if (flag) { CustomWeapons.OnLocalKill(); } } private static IEnumerator RevicePsychopathRoutine() { for (int i = 0; i < 10; i++) { try { if (RigData.HasPlayer) { LocalHealth.SetFullHealth(); LocalRagdoll.ToggleRagdoll(false); } } catch { } yield return (object)new WaitForSeconds(0.15f); } } private static IEnumerator ReviveAtPositionRoutine(Vector3 pos) { //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) for (int i = 0; i < 12; i++) { try { if (RigData.HasPlayer) { LocalHealth.SetFullHealth(); LocalRagdoll.ToggleRagdoll(false); if (pos != Vector3.zero) { RigManagerExtensions.TeleportToPosition(RigData.Refs.RigManager, pos + Vector3.up * 0.1f, true); } } } catch { } yield return (object)new WaitForSeconds(0.12f); } } private Vector3 GetDeathPosition(PlayerID player) { //IL_005c: 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_0077: 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_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_004a: 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_0054: 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_00a6: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: 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) if (player.IsMe) { if (_hasLastAlivePos) { return _localLastAlivePos; } try { if (RigData.HasPlayer && (Object)(object)RigData.Refs.Headset != (Object)null) { return RigData.Refs.Headset.position - Vector3.up * 0.6f; } } catch { } return Vector3.zero; } if (_lastKnownPositions.TryGetValue(player.SmallID, out var value)) { return value; } try { NetworkPlayer val = default(NetworkPlayer); if (NetworkPlayerManager.TryGetPlayer(player.SmallID, ref val)) { RigRefs rigRefs = val.RigRefs; Transform val2 = ((rigRefs != null) ? rigRefs.Headset : null); if ((Object)(object)val2 != (Object)null) { return val2.position - Vector3.up * 0.6f; } } } catch { } return Vector3.zero; } private void CheckWinConditions(PlayerID dyingPlayer = null) { if (!_gameEnded) { int num = CountAlive(TraitorTeam, dyingPlayer); int num2 = CountAlive(InnocentTeam, dyingPlayer) + CountAlive(DetectiveTeam, dyingPlayer) + CountAlive(GlitchTeam, dyingPlayer); int num3 = CountAlive(PsychopathTeam, dyingPlayer); int num4 = CountAlive(LoneWolfTeam, dyingPlayer); int num5 = CountAlive(JesterTeam, dyingPlayer); int num6 = CountAlive(ZombieTeam, dyingPlayer); bool flag = num2 > 0 && num == 0 && num3 == 0 && num4 == 0 && num5 == 0 && num6 == 0; bool flag2 = num > 0 && num2 == 0 && num3 == 0 && num4 == 0 && num5 == 0 && num6 == 0; bool num7 = num3 > 0 && num2 == 0 && num == 0 && num4 == 0 && num5 == 0 && num6 == 0; bool flag3 = num4 > 0 && num2 == 0 && num == 0 && num3 == 0 && num5 == 0 && num6 == 0; bool flag4 = num6 > 0 && num2 == 0 && num == 0 && num3 == 0 && num4 == 0 && num5 == 0; if (num7) { _gameEnded = true; PsychopathVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Jester, WinMusicEnabled)); } else if (flag3) { _gameEnded = true; LoneWolfVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.LoneWolf, WinMusicEnabled)); } else if (flag2) { _gameEnded = true; TraitorVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Traitors, WinMusicEnabled)); } else if (flag) { _gameEnded = true; InnocentVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled)); } else if (flag4) { _gameEnded = true; ZombieVictoryEvent.TryInvoke(); ScheduleStop(0f); } else if (num2 == 0 && num == 0 && num3 == 0 && num4 == 0 && num6 == 0) { _gameEnded = true; ScheduleStop(0f); } } } private void ScheduleStop(float musicLength) { if (NetworkInfo.IsHost) { if (musicLength > 0.1f) { _stopScheduled = true; _stopDelayRemaining = musicLength + 1.5f; } else { GamemodeManager.StopGamemode(); } } } private int CountAlive(Team team, PlayerID dyingPlayer) { int num = team.PlayerCount; if (dyingPlayer != null && team.HasPlayer(dyingPlayer)) { num--; } return Mathf.Max(0, num); } private static PlayerID FindPlayerBySmallID(ushort smallId) { foreach (PlayerID playerID in PlayerIDManager.PlayerIDs) { if (playerID.SmallID == smallId) { return playerID; } } return null; } private bool SongsEnabledByHost() { try { string text = default(string); if (((Gamemode)this).Metadata.TryGetMetadata("tift_music", ref text)) { return text != "0"; } } catch { } return true; } private bool OneStabEnabledByHost() { try { string text = default(string); if (((Gamemode)this).Metadata.TryGetMetadata("tift_onestab", ref text)) { return text == "1"; } } catch { } return OneStabKnifeEnabled; } private ushort GetHypnotistSmallID() { try { string s = default(string); if (((Gamemode)this).Metadata.TryGetMetadata("tift_hypnotist", ref s) && ushort.TryParse(s, out var result)) { return result; } } catch { } return _hypnotistSmallID; } private bool IsLocalHypnotist() { PlayerID localID = PlayerIDManager.LocalID; if (localID != null && GetHypnotistSmallID() != 0) { return localID.SmallID == GetHypnotistSmallID(); } return false; } private void OnBrainwash(string value) { if (!ushort.TryParse(value, out var result) || result == 0) { return; } try { CorpseManager.RemoveCorpseOf(result); } catch { } if (NetworkInfo.IsHost && _roundStarted) { PlayerID val = FindPlayerBySmallID(result); if (val != null && SpectatorTeam.HasPlayer(val)) { TeamManager.TryAssignTeam(val, TraitorTeam); CheckWinConditions(); } } } private void OnCorpseSpawn(string value) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) try { string[] array = value.Split('|'); if (array.Length >= 8) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; ushort num = ushort.Parse(array[0]); Vector3 deathPosition = default(Vector3); ((Vector3)(ref deathPosition))..ctor(float.Parse(array[1], invariantCulture), float.Parse(array[2], invariantCulture), float.Parse(array[3], invariantCulture)); string text = array[4]; string roleColor = array[5]; string weaponName = (string.IsNullOrEmpty(array[6]) ? null : array[6]); string avatarBarcode = (string.IsNullOrEmpty(array[7]) ? null : array[7]); string playerName = "Unknown"; PlayerID val = FindPlayerBySmallID(num); string text2 = default(string); if (val != null && MetadataHelper.TryGetDisplayName(val, ref text2)) { playerName = text2; } bool wasInnocentSide = text == "Innocent" || text == "Detective"; CorpseManager.RegisterDeath(playerName, text, roleColor, deathPosition, weaponName, avatarBarcode, num, wasInnocentSide); } } catch { } } private static string TryGetHeldWeaponName(RigManager rig) { if ((Object)(object)rig == (Object)null) { return null; } Hand[] array = (Hand[])(object)new Hand[2] { rig.physicsRig.leftHand, rig.physicsRig.rightHand }; foreach (Hand val in array) { try { GameObject val2 = ((val != null) ? val.m_CurrentAttachedGO : null); if (!((Object)(object)val2 == (Object)null)) { GameObject val3 = val2; MarrowEntity componentInParent = val2.GetComponentInParent(); val3 = ((!((Object)(object)componentInParent != (Object)null)) ? ((Component)val2.transform.root).gameObject : ((Component)componentInParent).gameObject); string text = CleanWeaponName(((Object)val3).name); if (!string.IsNullOrEmpty(text)) { return text; } } } catch { } } return null; } private static string CleanWeaponName(string raw) { if (string.IsNullOrEmpty(raw)) { return null; } string text = raw.Replace("(Clone)", "").Replace("[item]", "").Replace("_", " ") .Trim(); int num = text.LastIndexOf(' '); if (num > 0 && int.TryParse(text.Substring(num + 1), out var _)) { text = text.Substring(0, num).Trim(); } if (!string.IsNullOrEmpty(text)) { return text; } return null; } protected override void OnPlayerJoined(PlayerID playerId) { if (KarmaManager.Enabled) { KarmaManager.EnsurePlayer(playerId); } if (NetworkInfo.IsHost && _roundStarted) { TeamManager.TryAssignTeam(playerId, SpectatorTeam); } } protected override void OnPlayerLeft(PlayerID playerId) { KarmaManager.RemovePlayer(playerId); _lastKnownPositions.Remove(playerId.SmallID); _recentKillers.Remove(playerId.SmallID); if (NetworkInfo.IsHost && _roundStarted) { CheckWinConditions(playerId); } } private void OnOneMinuteLeft() { //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_000b: 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) //IL_0025: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit("Trouble In FordTown"), Message = NotificationText.op_Implicit("One minute left! Traitors, hurry up!"), ShowPopup = true, PopupLength = 4f, Type = (NotificationType)0 }); } private void OnInnocentVictory() { WinMusic.PlayWin(WinSide.Innocents, SongsEnabledByHost()); Team localTeam = TeamManager.GetLocalTeam(); bool localWon = localTeam == InnocentTeam || localTeam == DetectiveTeam || localTeam == GlitchTeam; SendVictoryNotification("INNOCENTS WIN!", "All Traitors have been eliminated!", localWon); } private void OnTraitorVictory() { WinMusic.PlayWin(WinSide.Traitors, SongsEnabledByHost()); bool localWon = TeamManager.GetLocalTeam() == TraitorTeam; SendVictoryNotification("TRAITORS WIN!", "All Innocents have been eliminated!", localWon); } private void OnPsychopathVictory() { WinMusic.PlayWin(WinSide.Jester, SongsEnabledByHost()); bool localWon = TeamManager.GetLocalTeam() == PsychopathTeam; SendVictoryNotification("JESTER WINS!", "The Jester got the last laugh — everyone else is dead!", localWon); } private void OnLoneWolfVictory() { WinMusic.PlayWin(WinSide.LoneWolf, SongsEnabledByHost()); bool localWon = TeamManager.GetLocalTeam() == LoneWolfTeam; SendVictoryNotification("LONE WOLF WINS!", "The Lone Wolf outlasted everyone!", localWon); } private void OnZombieVictory() { bool localWon = TeamManager.GetLocalTeam() == ZombieTeam; SendVictoryNotification("ZOMBIES WIN!", "The infection spread to everyone!", localWon); } private void OnTimeUp() { WinMusic.PlayWin(WinSide.Innocents, SongsEnabledByHost()); Team localTeam = TeamManager.GetLocalTeam(); bool localWon = localTeam == InnocentTeam || localTeam == DetectiveTeam || localTeam == GlitchTeam; SendVictoryNotification("INNOCENTS WIN!", "The Traitors ran out of time!", localWon); } private void SendVictoryNotification(string title, string message, bool localWon) { //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_0007: 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_0027: 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_0038: 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_004f: Expected O, but got Unknown Notifier.Send(new Notification { Title = NotificationText.op_Implicit(title), Message = NotificationText.op_Implicit(message + (localWon ? " YOU WON!" : " You lost.")), ShowPopup = true, PopupLength = 6f, Type = (NotificationType)0 }); if (KarmaManager.Enabled && localWon) { KarmaManager.AwardRoundBonus(PlayerIDManager.LocalID); } PointItemManager.RewardBits(localWon ? 100 : 25, true); } protected bool OnValidateNametag(PlayerID id) { if (!((Gamemode)this).IsStarted || !_roundStarted) { return true; } Team localTeam = TeamManager.GetLocalTeam(); if (localTeam == SpectatorTeam) { return true; } if (localTeam == TraitorTeam) { if (!TraitorTeam.HasPlayer(id)) { return GlitchTeam.HasPlayer(id); } return true; } if (localTeam == ZombieTeam) { return ZombieTeam.HasPlayer(id); } return false; } public override bool CanAttack(PlayerID player) { if (!((Gamemode)this).IsStarted || !_roundStarted) { return !((Gamemode)this).IsStarted; } Team localTeam = TeamManager.GetLocalTeam(); Team playerTeam = TeamManager.GetPlayerTeam(player); if (localTeam == SpectatorTeam || playerTeam == SpectatorTeam) { return false; } return true; } } public class TTTMod : MelonMod { private bool _registered; private bool _patched; public override void OnInitializeMelon() { ApplyPatches(); TryRegisterGamemode(); } public override void OnLateInitializeMelon() { ApplyPatches(); TryRegisterGamemode(); } private void ApplyPatches() { if (_patched) { return; } try { ((MelonBase)this).HarmonyInstance.CreateClassProcessor(typeof(ZombieBiteDamagePatch)).Patch(); _patched = true; } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Zombie damage patch could not be applied on this build (zombies may not one-shot, everything else still works): " + ex.Message); } } private void TryRegisterGamemode() { if (_registered) { return; } try { GamemodeRegistration.LoadGamemodes(Assembly.GetExecutingAssembly()); _registered = true; ((MelonBase)this).LoggerInstance.Msg("Trouble In FordTown registered! Select it from the Fusion menu's Gamemodes tab."); } catch (Exception ex) { ((MelonBase)this).LoggerInstance.Warning("Gamemode registration deferred/failed (will retry): " + ex.Message); } } } public static class WavLoader { public static AudioClip Load(byte[] data, string name) { try { return Parse(data, name); } catch (Exception ex) { MelonLogger.Warning("WinMusic: failed to decode WAV " + name + ": " + ex.Message); return null; } } private static AudioClip Parse(byte[] data, string name) { if (data.Length < 12 || data[0] != 82 || data[1] != 73 || data[2] != 70 || data[3] != 70 || data[8] != 87 || data[9] != 65 || data[10] != 86 || data[11] != 69) { MelonLogger.Warning("WinMusic: " + name + " is not a valid WAV file"); return null; } int num = 2; int num2 = 44100; int num3 = 16; int num4 = 1; int num5 = -1; int num6 = 0; int num7 = 12; while (num7 + 8 <= data.Length) { string text = $"{data[num7]}{data[num7 + 1]}{data[num7 + 2]}{data[num7 + 3]}"; int num8 = BitConverter.ToInt32(data, num7 + 4); int num9 = num7 + 8; if (text == "fmt ") { num4 = BitConverter.ToInt16(data, num9); num = BitConverter.ToInt16(data, num9 + 2); num2 = BitConverter.ToInt32(data, num9 + 4); num3 = BitConverter.ToInt16(data, num9 + 14); } else if (text == "data") { num5 = num9; num6 = num8; } num7 = num9 + num8 + (num8 & 1); } if (num5 < 0 || num <= 0) { MelonLogger.Warning("WinMusic: " + name + " missing data/fmt chunk"); return null; } if (num5 + num6 > data.Length) { num6 = data.Length - num5; } int num10 = num3 / 8; int num11 = num6 / num10; float[] array = new float[num11]; for (int i = 0; i < num11; i++) { int num12 = num5 + i * num10; switch (num3) { case 8: array[i] = (float)(data[num12] - 128) / 128f; break; case 16: array[i] = (float)BitConverter.ToInt16(data, num12) / 32768f; break; case 24: { int num13 = data[num12] | (data[num12 + 1] << 8) | ((sbyte)data[num12 + 2] << 16); array[i] = (float)num13 / 8388608f; break; } case 32: array[i] = ((num4 == 3) ? BitConverter.ToSingle(data, num12) : ((float)BitConverter.ToInt32(data, num12) / 2.1474836E+09f)); break; default: return null; } } AudioClip val = AudioClip.Create(name, num11 / num, num, num2, false); Il2CppStructArray val2 = new Il2CppStructArray((long)num11); for (int j = 0; j < num11; j++) { ((Il2CppArrayBase)(object)val2)[j] = array[j]; } val.SetData(val2, 0); ((Object)val).hideFlags = (HideFlags)32; return val; } } public enum WinSide { Innocents, Traitors, Jester, LoneWolf } public static class WinMusic { private static readonly List _innocentLines = new List(); private static readonly List _innocentSongs = new List(); private static readonly List _traitorLines = new List(); private static readonly List _traitorSongs = new List(); private static readonly List _jesterLines = new List(); private static readonly List _jesterSongs = new List(); private static readonly List _loneWolfSongs = new List(); private static AudioSource _voiceSource; private static AudioSource _musicSource; private static bool _initialized; private static object _pendingSongRoutine; public static bool LocallyMuted = false; private static readonly List _noLines = new List(); public static void Initialize() { //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: Expected O, but got Unknown //IL_001e: 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) if (_initialized) { return; } _initialized = true; try { GameObject val = new GameObject("TIFT Win Music"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; _voiceSource = val.AddComponent(); _voiceSource.spatialBlend = 0f; _voiceSource.volume = 1f; _voiceSource.playOnAwake = false; _musicSource = val.AddComponent(); _musicSource.spatialBlend = 0f; _musicSource.volume = 1f; _musicSource.playOnAwake = false; LoadInto("innocents_song1.wav", _innocentSongs); LoadInto("innocents_song2.wav", _innocentSongs); LoadInto("traitors_song1.wav", _traitorSongs); LoadInto("traitors_song2.wav", _traitorSongs); LoadInto("jester_song1.wav", _jesterSongs); LoadInto("jester_song2.wav", _jesterSongs); LoadInto("lonewolf_song1.wav", _loneWolfSongs); AudioClip val2 = LoadEmbedded("brainwash_charge.wav"); if ((Object)(object)val2 != (Object)null) { HypnotistController.ChargeClip = val2; } LoadInto("innocents_line1.wav", _innocentLines); LoadInto("innocents_line2.wav", _innocentLines); LoadInto("traitors_line1.wav", _traitorLines); LoadInto("traitors_line2.wav", _traitorLines); LoadInto("jester_line1.wav", _jesterLines); LoadInto("jester_line2.wav", _jesterLines); } catch (Exception ex) { MelonLogger.Warning("WinMusic init failed: " + ex.Message); } } public static void PlayWin(WinSide side, bool playSong) { if ((Object)(object)_voiceSource == (Object)null || (Object)(object)_musicSource == (Object)null) { return; } AudioClip val = RandomClip(LinesFor(side)); AudioClip val2 = RandomClip(SongsFor(side)); bool flag = playSong && !LocallyMuted; try { if (_pendingSongRoutine != null) { MelonCoroutines.Stop(_pendingSongRoutine); _pendingSongRoutine = null; } _voiceSource.Stop(); _musicSource.Stop(); ApplyMixerGroups(); if ((Object)(object)val != (Object)null) { _voiceSource.PlayOneShot(val); if ((Object)(object)val2 != (Object)null && flag) { _pendingSongRoutine = MelonCoroutines.Start(PlayAfter(val.length, val2)); } } else if ((Object)(object)val2 != (Object)null && flag) { _musicSource.clip = val2; _musicSource.Play(); } } catch { } } private static void ApplyMixerGroups() { try { AudioMixerGroup hardInteraction = Audio3dManager.hardInteraction; AudioMixerGroup nonDiegeticMusic = Audio3dManager.nonDiegeticMusic; if ((Object)(object)hardInteraction != (Object)null) { _voiceSource.outputAudioMixerGroup = hardInteraction; } if ((Object)(object)nonDiegeticMusic != (Object)null) { _musicSource.outputAudioMixerGroup = nonDiegeticMusic; } } catch { } } public static float GetMaxDuration(WinSide side, bool includeSong) { float num = MaxLength(LinesFor(side)); float num2 = (includeSong ? MaxLength(SongsFor(side)) : 0f); if (num <= 0f && num2 <= 0f) { return 0f; } return num + num2 + 1.5f; } public static void Stop() { try { if (_pendingSongRoutine != null) { MelonCoroutines.Stop(_pendingSongRoutine); _pendingSongRoutine = null; } if ((Object)(object)_voiceSource != (Object)null && _voiceSource.isPlaying) { _voiceSource.Stop(); } if ((Object)(object)_musicSource != (Object)null && _musicSource.isPlaying) { _musicSource.Stop(); } } catch { } } private static IEnumerator PlayAfter(float delay, AudioClip song) { yield return (object)new WaitForSeconds(delay); if ((Object)(object)_musicSource != (Object)null && (Object)(object)song != (Object)null) { _musicSource.clip = song; _musicSource.Play(); } _pendingSongRoutine = null; } private static List LinesFor(WinSide side) { return side switch { WinSide.Traitors => _traitorLines, WinSide.Jester => _jesterLines, WinSide.LoneWolf => _noLines, _ => _innocentLines, }; } private static List SongsFor(WinSide side) { return side switch { WinSide.Traitors => _traitorSongs, WinSide.Jester => _jesterSongs, WinSide.LoneWolf => _loneWolfSongs, _ => _innocentSongs, }; } private static AudioClip RandomClip(List clips) { if (clips == null || clips.Count == 0) { return null; } return clips[Random.Range(0, clips.Count)]; } private static float MaxLength(List clips) { float num = 0f; if (clips != null) { foreach (AudioClip clip in clips) { if ((Object)(object)clip != (Object)null && clip.length > num) { num = clip.length; } } } return num; } private static void LoadInto(string fileName, List target) { AudioClip val = LoadEmbedded(fileName); if ((Object)(object)val != (Object)null) { target.Add(val); } } private static AudioClip LoadEmbedded(string fileName) { try { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string text = null; string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (text2.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)) { text = text2; break; } } if (text == null) { MelonLogger.Warning("WinMusic: embedded resource '" + fileName + "' not found"); return null; } using Stream stream = executingAssembly.GetManifestResourceStream(text); using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); AudioClip val = WavLoader.Load(memoryStream.ToArray(), Path.GetFileNameWithoutExtension(fileName)); if ((Object)(object)val != (Object)null) { MelonLogger.Msg($"WinMusic: loaded {fileName} ({val.length:0.0}s)"); } return val; } catch (Exception ex) { MelonLogger.Warning("WinMusic: failed to load " + fileName + ": " + ex.Message); return null; } } } public class WristIndicator { private GameObject _root; private TextMeshPro _text; private static TMP_FontAsset _font; public bool IsCreated => (Object)(object)_root != (Object)null; private static TMP_FontAsset GetFont() { if ((Object)(object)_font != (Object)null) { return _font; } Il2CppArrayBase val = Resources.FindObjectsOfTypeAll(); foreach (TMP_FontAsset item in val) { if (((Object)item).name.ToLower().Contains("arlon-medium")) { _font = item; break; } } if ((Object)(object)_font == (Object)null && val.Length > 0) { _font = val[0]; } return _font; } public bool TryCreate() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if (IsCreated) { return true; } if (!RigData.HasPlayer || (Object)(object)RigData.Refs.LeftHand == (Object)null) { return false; } _root = new GameObject("TIFT Wrist Indicator"); Object.DontDestroyOnLoad((Object)(object)_root); ((Object)_root).hideFlags = (HideFlags)32; _text = _root.AddComponent(); TMP_FontAsset font = GetFont(); if ((Object)(object)font != (Object)null) { ((TMP_Text)_text).font = font; } ((TMP_Text)_text).fontSize = 0.21f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(0.18f, 0.08f); ((TMP_Text)_text).text = ""; return true; } public void SetText(string value) { if ((Object)(object)_text != (Object)null) { ((TMP_Text)_text).text = value; } } public void Update() { //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) //IL_004e: 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_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_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_0065: 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_00a4: 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_00f7: 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) if (!IsCreated || !RigData.HasPlayer) { return; } Hand leftHand = RigData.Refs.LeftHand; Transform headset = RigData.Refs.Headset; if (!((Object)(object)leftHand == (Object)null) && !((Object)(object)headset == (Object)null)) { Vector3 val = ((Component)leftHand).transform.position + Vector3.up * 0.12f; Vector3 val2 = val - headset.position; float magnitude = ((Vector3)(ref val2)).magnitude; bool flag = false; try { flag = (Object)(object)leftHand.m_CurrentAttachedGO != (Object)null; } catch { } bool flag2 = !flag && magnitude < 1.2f && magnitude > 0.05f && Vector3.Dot(headset.forward, val2 / magnitude) > 0.55f; if (_root.activeSelf != flag2) { _root.SetActive(flag2); } if (flag2) { _root.transform.position = val; _root.transform.rotation = Quaternion.LookRotation(val2); } } } public void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; _text = null; } } public static class ZombieState { public static bool LocalIsZombie; } public static class OneStabState { public static bool LocalHolding; } [HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")] public static class ZombieBiteDamagePatch { [HarmonyPrefix] [HarmonyPriority(800)] public static void Prefix(PlayerDamageReceiver __instance, ref Attack attack) { if (!ZombieState.LocalIsZombie && !OneStabState.LocalHolding) { return; } try { TriggerRefProxy proxy = attack.proxy; if (!((Object)(object)proxy == (Object)null) && !((Object)(object)proxy.root == (Object)null)) { RigManager val = RigManager.Cache.Get(proxy.root); if ((Object)(object)val != (Object)null && FusionPlayer.IsLocalPlayer(val)) { attack.damage = 999999f; } } } catch { } } }