using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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.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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(TTTMod), "Trouble In FordTown", "2.1.0", "JonLandonMods", null)] [assembly: MelonGame("Stress Level Zero", "BONELAB")] [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 bool IsValid => (Object)(object)Rig != (Object)null && (Object)(object)((Component)Rig).gameObject != (Object)null; public Vector3 Position { get { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_00aa: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0091: 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_0098: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) 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 const float GrabRadius = 1.2f; public static void RegisterDeath(string playerName, string roleName, string roleColor, Vector3 deathPosition, string weaponName = null, string avatarBarcode = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) SpawnRagdollCorpse(deathPosition, avatarBarcode, delegate(RigManager rig) { _corpses.Add(new CorpseProxy { Rig = rig, PlayerName = playerName, RoleName = roleName, RoleColor = roleColor, WeaponName = weaponName, TimeOfDeath = Time.realtimeSinceStartup }); }); } private static void SpawnRagdollCorpse(Vector3 position, string avatarBarcode, Action onSpawned) { //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) PlayerRepUtilities.CreateNewRig((Action)delegate(RigManager rig) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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 { rig.physicsRig.ShutdownRig(); rig.physicsRig.RagdollRig(); } catch { } ((Object)((Component)rig).gameObject).name = "[TIFT Corpse]"; onSpawned?.Invoke(rig); } catch { } }); } public static void Update() { //IL_005e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) if (!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 => _active.HasValue && _active.Value.Type == WeaponType.GoldenPistol; 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_0040: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_006e: 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_009a: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) _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 { Type type = ((object)componentsInChild).GetType(); FieldInfo field = type.GetField("damage", BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == typeof(float)) { field.SetValue(componentsInChild, 99999f); } } catch { } } } public static void OnLocalKill() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00c4: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) 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_0027: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00b7: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) 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_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0092: 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 }); } } [HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")] public static class GoldenPistolDamagePatch { [HarmonyPrefix] [HarmonyPriority(800)] public static void Prefix(PlayerDamageReceiver __instance, ref Attack attack) { if (!CustomWeapons.GoldenPistolActive) { 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 { } } } 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 = 1000; 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) { int value; return _karma.TryGetValue(player.SmallID, out value) ? value : 1000; } public static void AdjustKarma(PlayerID player, int delta) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00c2: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown if (Enabled) { EnsurePlayer(player); byte smallID = player.SmallID; _karma[smallID] = Math.Clamp(_karma[smallID] + delta, 0, 1000); 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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 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 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: 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_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: 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; } Team localTeam = gm.TeamManager.GetLocalTeam(); bool flag = localTeam == gm.TraitorTeam; HashSet hashSet = new HashSet(); 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 (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)) { hashSet.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; } List list = new List(); foreach (KeyValuePair label2 in _labels) { if (!hashSet.Contains(label2.Key)) { list.Add(label2.Key); } } foreach (ushort item in list) { 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_00c5: 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; public void Register() { //IL_001b: 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_0080: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0287: 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; }); _page = Page.Root.CreatePage("Roles Info", Color.white, 0, true); _page.CreateFunction("INNOCENT — Find & kill all Traitors to win", new Color(0.2f, 1f, 0.2f), (Action)delegate { }); _page.CreateFunction("TRAITOR — Eliminate everyone secretly to win", new Color(1f, 0.2f, 0.2f), (Action)delegate { }); _page.CreateFunction("DETECTIVE — Publicly known; leads the Innocents", new Color(0.2f, 0.6f, 1f), (Action)delegate { }); _page.CreateFunction("JESTER — Get an Innocent to kill you → become Psychopath", new Color(1f, 0.41f, 0.71f), (Action)delegate { }); _page.CreateFunction("PSYCHOPATH — Kill everyone after converting from Jester", new Color(0.8f, 0f, 0f), (Action)delegate { }); _page.CreateFunction("LONE WOLF — Be the last one alive to win", new Color(1f, 0.55f, 0f), (Action)delegate { }); _page.CreateFunction("GLITCH — Looks like a Traitor; secretly wins with Innocents", new Color(0f, 1f, 1f), (Action)delegate { }); _page.CreateFunction("SPECTATOR — Eliminated; wait for round end", new Color(0.67f, 0.67f, 0.67f), (Action)delegate { }); } public void Unregister() { 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) _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_00fa: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0077: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //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_00bb: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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_00f8: 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 { try { } 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 }); 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 static TroubleInFordTownGamemode _gamemode; private static bool _added; public static void AddMenuItems(TroubleInFordTownGamemode gamemode) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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(); }))); 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("Health Boost"))))); popUpMenu.radialPageView.Render(homePage); } catch { } _added = false; _gamemode = null; } private static void BuyHealth() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0077: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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 }); } } 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 const string MusicMetaKey = "tift_music"; 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"; 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 bool _roundStarted = false; private float _elapsedTime = 0f; private bool _oneMinuteLeft = false; private bool _gameEnded = false; private bool _localDied = false; private Vector3 _localDeathPos = Vector3.zero; private bool _hasLocalDeathPos = false; private float _roundLengthSeconds = 0f; private bool _stopScheduled = false; private float _stopDelayRemaining = 0f; 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 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 = 2.5f; 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 WinMusicEnabled { get; set; } = true; 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 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 override GroupElementData CreateSettingsGroup() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00b9: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_0153: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019d: 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_01c1: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_020d: 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_021e: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown GroupElementData val = ((Gamemode)this).CreateSettingsGroup(); GroupElementData val2 = new GroupElementData("General"); val.AddElement(val2); val2.AddElement(new IntElementData { Title = "Traitor Count", Value = TraitorCount, Increment = 1, MinValue = 1, MaxValue = 4, OnValueChanged = delegate(int v) { TraitorCount = v; } }); val2.AddElement(new IntElementData { Title = "Prep Time (Seconds)", Value = PrepSeconds, Increment = 5, MinValue = 5, MaxValue = 60, OnValueChanged = delegate(int v) { PrepSeconds = v; } }); val2.AddElement(new IntElementData { Title = "Round Length (Minutes)", Value = RoundMinutes, Increment = 1, MinValue = 1, MaxValue = 15, OnValueChanged = delegate(int v) { RoundMinutes = v; } }); GroupElementData val3 = new GroupElementData("Extra Roles"); val.AddElement(val3); val3.AddElement(new BoolElementData { Title = "Detective", Value = DetectiveEnabled, OnValueChanged = delegate(bool v) { DetectiveEnabled = v; } }); val3.AddElement(new BoolElementData { Title = "Jester", Value = JesterEnabled, OnValueChanged = delegate(bool v) { JesterEnabled = v; } }); val3.AddElement(new BoolElementData { Title = "Lone Wolf", Value = LoneWolfEnabled, OnValueChanged = delegate(bool v) { LoneWolfEnabled = v; } }); val3.AddElement(new BoolElementData { Title = "Glitch", Value = GlitchEnabled, OnValueChanged = delegate(bool v) { GlitchEnabled = v; } }); GroupElementData val4 = new GroupElementData("Win Music"); val.AddElement(val4); val4.AddElement(new BoolElementData { Title = "Play Win Song", Value = WinMusicEnabled, OnValueChanged = delegate(bool v) { WinMusicEnabled = v; } }); GroupElementData val5 = new GroupElementData("Karma"); val.AddElement(val5); val5.AddElement(new BoolElementData { Title = "Enable Karma System", Value = KarmaManager.Enabled, OnValueChanged = delegate(bool v) { KarmaManager.Enabled = v; } }); return val; } public override bool CheckReadyConditions() { return PlayerIDManager.PlayerIDs.Count >= 2; } public override void OnGamemodeRegistered() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0211: 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.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; _buyMenu.Register(this); _rolesInfoMenu.Register(); WinMusic.Initialize(); LocalHealth.OnRespawn += OnLocalRespawn; } private void OnLocalRespawn() { if (!((Gamemode)this).IsStarted) { return; } try { LocalPlayer.ReleaseGrips(); } catch { } } public override void OnGamemodeUnregistered() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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; _buyMenu.Unregister(); _rolesInfoMenu.Unregister(); } public override void OnGamemodeStarted() { //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown ((Gamemode)this).OnGamemodeStarted(); _roundStarted = false; _elapsedTime = 0f; _oneMinuteLeft = false; _gameEnded = false; _localDied = false; _hasLocalDeathPos = false; _roundLengthSeconds = 0f; _spawnedLoadoutItems.Clear(); _lastKnownPositions.Clear(); _recentKillers.Clear(); _recentKillTime.Clear(); _recentWeapons.Clear(); 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 { } } Playlist.SetPlaylist(AudioReference.CreateReferences(Defaults.Tracks)); Playlist.Shuffle(); Playlist.StartPlaylist(); 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; ClearSpectatorEffects(); _wristIndicator.Destroy(); _roleLabels.ClearAll(); 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() { if (!((Gamemode)this).IsStarted) { return; } Playlist.Update(); _elapsedTime += TimeReferences.DeltaTime; UpdateSpectators(); UpdateWristIndicator(); CorpseManager.Update(); _roleLabels.Update(this); 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); } foreach (PlayerID item in list) { TeamManager.TryAssignTeam(item, InnocentTeam); } } private void UpdateSpectators() { //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) 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 { } } 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); if (val.ForceHide != flag2) { val.ForceHide = flag2; } bool flag3 = flag2 && !flag; RigVoiceSource voiceSource = val.VoiceSource; VoiceSource val2 = ((voiceSource != null) ? voiceSource.VoiceSource : null); if ((Object)(object)((val2 != null) ? val2.AudioSource : null) != (Object)null && val2.AudioSource.mute != flag3) { val2.AudioSource.mute = flag3; } 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 != null) ? val2.AudioSource : null) != (Object)null) { val2.AudioSource.mute = false; } } } } private void UpdateWristIndicator() { if (_wristIndicator.TryCreate()) { _wristIndicator.SetText(GetWristText()); _wristIndicator.Update(); } } private string GetWristText() { if (!_roundStarted) { return "GET READY\nRoles incoming..."; } float num = Mathf.Max(_roundLengthSeconds - _elapsedTime, 0f); string text = TimeSpan.FromSeconds(num).ToString("mm\\:ss"); Team localTeam = TeamManager.GetLocalTeam(); string text2 = ((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 != SpectatorTeam) ? "NO ROLE" : "SPECTATING")))))))); return text2 + "\n" + text; } private void SpawnLoadout() { Team localTeam = TeamManager.GetLocalTeam(); if (localTeam != SpectatorTeam) { Random random = new Random(); SpawnLoadoutItem(Defaults.Sidearms[random.Next(Defaults.Sidearms.Length)]); SpawnLoadoutItem(Defaults.Primaries[random.Next(Defaults.Primaries.Length)]); if (localTeam == TraitorTeam) { SpawnLoadoutItem("c1534c5a-1fb8-477c-afbe-2a95436f6d62"); } } } private void SpawnLoadoutItem(string barcode) { //IL_001b: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (RigData.HasPlayer) { Transform headset = RigData.Refs.Headset; Vector3 position = headset.position + headset.forward * 0.4f; Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode); NetworkAssetSpawner.Spawn(new SpawnRequestInfo { Spawnable = spawnable, Position = position, Rotation = Quaternion.identity, SpawnEffect = false, SpawnCallback = delegate(SpawnCallbackInfo info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) _spawnedLoadoutItems.Add(info.Entity.ID); TryHolster(info.Spawned); } }); } } public void TryHolster(GameObject item) { 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; } InventorySlotReceiver[] rigSlots = RigData.Refs.RigSlots; foreach (InventorySlotReceiver val in rigSlots) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val._slottedWeapon != (Object)null)) { try { val.InsertInSlot(componentInChildren.interactableHost); } catch { continue; } if ((Object)(object)val._slottedWeapon != (Object)null) { break; } } } } private void DespawnLoadoutItems() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a8: 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_00c1: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Expected O, but got Unknown //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: 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_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: 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_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Expected O, but got Unknown //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Expected O, but got Unknown //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Expected O, but got Unknown //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0470: 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_047f: 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 (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) { 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()); } 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 != SpectatorTeam || !_roundStarted) { return; } string text2 = (_localDied ? "YOU ARE NOW SPECTATING" : "THE JESTER TRICKED YOU!"); string text3 = (_localDied ? "You can hear other dead players. Wait for the round to end." : "You killed the Jester — now you pay for it. Spectate until the round ends."); 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 + Vector3.up * 0.1f)); } } private static IEnumerator MoveSpectatorToBodyRoutine(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) { RigManagerExtensions.TeleportToPosition(RigData.Refs.RigManager, pos, true); } } catch { } yield return (object)new WaitForSeconds(0.1f); } } private void OnRoundStarted(string value) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0286: 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_02ad: 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_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: 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); } Team localTeam = TeamManager.GetLocalTeam(); if (localTeam != 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 text = default(string); foreach (byte player2 in GlitchTeam.Players) { PlayerID val2 = FindPlayerBySmallID(player2); if (val2 != null && MetadataHelper.TryGetDisplayName(val2, ref text)) { list.Add(text + " [GLITCH]"); } } string text2 = ((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(text2), ShowPopup = true, PopupLength = 7f, Type = (NotificationType)0 }); if (JesterTeam.PlayerCount <= 0) { return; } List list2 = new List(); string item2 = default(string); foreach (byte player3 in JesterTeam.Players) { PlayerID val3 = FindPlayerBySmallID(player3); if (val3 != null && MetadataHelper.TryGetDisplayName(val3, ref item2)) { list2.Add(item2); } } 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_00c9: 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_00cc: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Invalid comparison between Unknown and I4 //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_0051: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) if (player.IsMe) { _localDied = true; try { _localDeathPos = GetDeathPosition(player); _hasLocalDeathPos = true; } catch { } try { LocalPlayer.ReleaseGrips(); } catch { } } if (_roundStarted) { Vector3 deathPosition = GetDeathPosition(player); Team playerTeam = TeamManager.GetPlayerTeam(player); string roleName; string roleColor; if (playerTeam == TraitorTeam) { roleName = "Traitor"; roleColor = "#ff3333"; } else if (playerTeam == DetectiveTeam) { roleName = "Detective"; roleColor = "#3399ff"; } else if (playerTeam == JesterTeam) { roleName = "Jester"; roleColor = "#ff69b4"; } else if (playerTeam == PsychopathTeam) { roleName = "Psychopath"; roleColor = "#cc0000"; } else if (playerTeam == LoneWolfTeam) { roleName = "Lone Wolf"; roleColor = "#ff8c00"; } else if (playerTeam == GlitchTeam) { roleName = "Innocent"; roleColor = "#33ff33"; } else if (playerTeam == SpectatorTeam) { roleName = "Spectator"; roleColor = "#aaaaaa"; } else { roleName = "Innocent"; roleColor = "#33ff33"; } string weaponName = null; if (_recentWeapons.TryGetValue(player.SmallID, out var value)) { weaponName = value; } string avatarBarcode = null; NetworkPlayer val = default(NetworkPlayer); if (player.IsMe) { try { avatarBarcode = RigData.GetAvatarBarcode(); } catch { } } else if (NetworkPlayerManager.TryGetPlayer(player.SmallID, ref val)) { try { RigRefs rigRefs = val.RigRefs; object obj4; if (rigRefs == null) { obj4 = null; } else { RigManager rigManager = rigRefs.RigManager; if (rigManager == null) { obj4 = null; } else { AvatarCrateReference avatarCrate = rigManager.AvatarCrate; obj4 = ((avatarCrate != null) ? ((ScannableReference)avatarCrate).Barcode.ID : null); } } avatarBarcode = (string)obj4; } catch { } } string text = default(string); MetadataHelper.TryGetDisplayName(player, ref text); CorpseManager.RegisterDeath(text ?? "Unknown", roleName, roleColor, deathPosition, weaponName, avatarBarcode); } if (KarmaManager.Enabled) { KarmaManager.AwardRoundBonus(player); } if (!NetworkInfo.IsHost || !_roundStarted) { return; } if (JesterTeam.HasPlayer(player)) { bool flag = false; PlayerID val2 = null; if (_recentKillTime.TryGetValue(player.SmallID, out var value2) && Time.time - value2 <= 2.5f && _recentKillers.TryGetValue(player.SmallID, out var value3)) { val2 = FindPlayerBySmallID(value3); Team val3 = ((val2 != null) ? TeamManager.GetPlayerTeam(val2) : null); flag = val3 == InnocentTeam || val3 == DetectiveTeam || val3 == GlitchTeam; } _recentKillers.Remove(player.SmallID); _recentKillTime.Remove(player.SmallID); if (flag) { TeamManager.TryAssignTeam(player, PsychopathTeam); if (val2 != null && !SpectatorTeam.HasPlayer(val2)) { TeamManager.TryAssignTeam(val2, SpectatorTeam); } 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; } 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 Vector3 GetDeathPosition(PlayerID player) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (player.IsMe) { 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(JesterTeam, dyingPlayer); int num4 = CountAlive(PsychopathTeam, dyingPlayer); int num5 = CountAlive(LoneWolfTeam, dyingPlayer); if (num4 > 0 && num == 0 && num2 == 0 && num5 == 0 && num3 == 0) { _gameEnded = true; PsychopathVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Jester, WinMusicEnabled)); } else if (num5 > 0 && num == 0 && num2 == 0 && num4 == 0 && num3 == 0) { _gameEnded = true; LoneWolfVictoryEvent.TryInvoke(); ScheduleStop(0f); } else if (num > 0 && num2 == 0 && num4 == 0 && num5 == 0 && num3 == 0) { _gameEnded = true; TraitorVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Traitors, WinMusicEnabled)); } else if (num == 0 && num5 == 0 && num4 == 0 && num2 > 0) { _gameEnded = true; InnocentVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled)); } else if (num == 0 && num5 == 0 && num4 == 0 && num2 == 0 && num3 > 0) { _gameEnded = true; InnocentVictoryEvent.TryInvoke(); ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled)); } } } 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 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 }; Hand[] array2 = array; foreach (Hand val in array2) { 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(); } return string.IsNullOrEmpty(text) ? null : text; } 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_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0030: 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_0049: 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() { bool localWon = TeamManager.GetLocalTeam() == LoneWolfTeam; SendVictoryNotification("LONE WOLF WINS!", "The Lone Wolf outlasted 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_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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 == TraitorTeam) { return TraitorTeam.HasPlayer(id) || GlitchTeam.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 { public override void OnInitializeMelon() { GamemodeRegistration.LoadGamemodes(Assembly.GetExecutingAssembly()); ((MelonBase)this).LoggerInstance.Msg("Trouble In FordTown registered! Select it from the Fusion menu's Gamemodes tab."); } } 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 } 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 AudioSource _voiceSource; private static AudioSource _musicSource; private static bool _initialized; private static object _pendingSongRoutine; public static bool LocallyMuted = false; public static void Initialize() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; try { GameObject val = new GameObject("TIFT Win Music"); Object.DontDestroyOnLoad((Object)(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("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); LoadInto("jester_line3.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) { if (1 == 0) { } List result = side switch { WinSide.Traitors => _traitorLines, WinSide.Jester => _jesterLines, _ => _innocentLines, }; if (1 == 0) { } return result; } private static List SongsFor(WinSide side) { if (1 == 0) { } List result = side switch { WinSide.Traitors => _traitorSongs, WinSide.Jester => _jesterSongs, _ => _innocentSongs, }; if (1 == 0) { } return result; } 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_00cd: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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; } }