Decompiled source of TroubleInFordTown v1.1.9

Mods/TroubleInFordTown.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.Audio;
using Il2CppSLZ.Marrow.Combat;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Interaction;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem;
using Il2CppTMPro;
using LabFusion.Data;
using LabFusion.Entities;
using LabFusion.Extensions;
using LabFusion.Marrow;
using LabFusion.Marrow.Integration;
using LabFusion.Marrow.Pool;
using LabFusion.Menu.Data;
using LabFusion.Network;
using LabFusion.Player;
using LabFusion.RPC;
using LabFusion.Representation;
using LabFusion.SDK.Gamemodes;
using LabFusion.SDK.Points;
using LabFusion.SDK.Triggers;
using LabFusion.Senders;
using LabFusion.UI.Popups;
using LabFusion.Utilities;
using LabFusion.Voice;
using MelonLoader;
using TroubleInFordTown;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(TTTMod), "Trouble In FordTown", "2.1.0", "JonLandonMods", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: HarmonyDontPatchAll]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace TroubleInFordTown;

public class CorpseProxy
{
	public RigManager Rig;

	public string PlayerName;

	public string RoleName;

	public string RoleColor;

	public string WeaponName;

	public float TimeOfDeath;

	public ushort OwnerSmallID;

	public bool WasInnocentSide;

	public bool IsValid
	{
		get
		{
			if ((Object)(object)Rig != (Object)null)
			{
				return (Object)(object)((Component)Rig).gameObject != (Object)null;
			}
			return false;
		}
	}

	public Vector3 Position
	{
		get
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (IsValid)
				{
					PhysicsRig physicsRig = Rig.physicsRig;
					if ((Object)(object)((physicsRig != null) ? ((Rig)physicsRig).m_chest : null) != (Object)null)
					{
						return ((Rig)Rig.physicsRig).m_chest.position;
					}
				}
			}
			catch
			{
			}
			return Vector3.zero;
		}
	}

	public void Destroy()
	{
		try
		{
			if ((Object)(object)Rig != (Object)null && (Object)(object)((Component)Rig).gameObject != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Rig).gameObject);
			}
		}
		catch
		{
		}
		Rig = null;
	}
}
public class CorpseInspectorUI
{
	private GameObject _root;

	private TextMeshPro _text;

	private CorpseProxy _showing;

	private static TMP_FontAsset _font;

	private static TMP_FontAsset GetFont()
	{
		if ((Object)(object)_font != (Object)null)
		{
			return _font;
		}
		Il2CppArrayBase<TMP_FontAsset> val = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
		foreach (TMP_FontAsset item in val)
		{
			if (((Object)item).name.ToLower().Contains("arlon-medium"))
			{
				_font = item;
				break;
			}
		}
		if ((Object)(object)_font == (Object)null && val.Length > 0)
		{
			_font = val[0];
		}
		return _font;
	}

	private bool TryCreate()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_root != (Object)null)
		{
			return true;
		}
		if (!RigData.HasPlayer)
		{
			return false;
		}
		_root = new GameObject("TIFT Corpse Inspector");
		Object.DontDestroyOnLoad((Object)(object)_root);
		((Object)_root).hideFlags = (HideFlags)32;
		_root.SetActive(false);
		_text = _root.AddComponent<TextMeshPro>();
		((TMP_Text)_text).fontSize = 0.55f;
		((TMP_Text)_text).alignment = (TextAlignmentOptions)514;
		((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(1.4f, 0.6f);
		TMP_FontAsset font = GetFont();
		if ((Object)(object)font != (Object)null)
		{
			((TMP_Text)_text).font = font;
		}
		return true;
	}

	public void ShowFor(CorpseProxy corpse)
	{
		_showing = corpse;
	}

	public void Hide()
	{
		_showing = null;
		if ((Object)(object)_root != (Object)null)
		{
			_root.SetActive(false);
		}
	}

	public void Update()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		if (!TryCreate())
		{
			return;
		}
		if (_showing == null || !_showing.IsValid)
		{
			_root.SetActive(false);
			return;
		}
		Transform headset = RigData.Refs.Headset;
		if ((Object)(object)headset == (Object)null)
		{
			_root.SetActive(false);
			return;
		}
		Vector3 val = _showing.Position + Vector3.up * 0.7f;
		Vector3 val2 = headset.position - val;
		if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
		{
			val2 = Vector3.forward;
		}
		_root.transform.position = val;
		_root.transform.rotation = Quaternion.LookRotation(-((Vector3)(ref val2)).normalized);
		float num = Time.realtimeSinceStartup - _showing.TimeOfDeath;
		string text = ((num < 60f) ? $"{Mathf.FloorToInt(num)}s ago" : $"{Mathf.FloorToInt(num / 60f)}m {Mathf.FloorToInt(num % 60f)}s ago");
		string text2 = (string.IsNullOrEmpty(_showing.WeaponName) ? "<size=85%><color=#aaaaaa>Weapon: Unknown</color></size>" : ("<size=85%>Weapon: <b>" + _showing.WeaponName + "</b></size>"));
		((TMP_Text)_text).text = $"<b>{_showing.PlayerName}</b>\n<color={_showing.RoleColor}>{_showing.RoleName}</color>\n" + text2 + "\n<size=80%><color=#cccccc>" + text + "</color></size>";
		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<CorpseProxy> _corpses = new List<CorpseProxy>();

	private static readonly CorpseInspectorUI _inspectorUI = new CorpseInspectorUI();

	private static readonly Dictionary<ushort, float> _recentlyRemoved = new Dictionary<ushort, float>();

	private const float GrabRadius = 1.2f;

	private const float SuppressSeconds = 2f;

	public static void RegisterDeath(string playerName, string roleName, string roleColor, Vector3 deathPosition, string weaponName = null, string avatarBarcode = null, ushort ownerSmallId = 0, bool wasInnocentSide = false)
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		SpawnRagdollCorpse(deathPosition, avatarBarcode, delegate(RigManager rig)
		{
			if (ownerSmallId != 0 && _recentlyRemoved.TryGetValue(ownerSmallId, out var value) && Time.realtimeSinceStartup - value < 2f)
			{
				try
				{
					if ((Object)(object)rig != (Object)null && (Object)(object)((Component)rig).gameObject != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)rig).gameObject);
					}
					return;
				}
				catch
				{
					return;
				}
			}
			_corpses.Add(new CorpseProxy
			{
				Rig = rig,
				PlayerName = playerName,
				RoleName = roleName,
				RoleColor = roleColor,
				WeaponName = weaponName,
				TimeOfDeath = Time.realtimeSinceStartup,
				OwnerSmallID = ownerSmallId,
				WasInnocentSide = wasInnocentSide
			});
		});
	}

	public static bool TryGetInnocentCorpseAlongRay(Vector3 origin, Vector3 direction, float maxDistance, out ushort ownerSmallId, out Vector3 corpsePos)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		ownerSmallId = 0;
		corpsePos = Vector3.zero;
		direction = ((Vector3)(ref direction)).normalized;
		float num = float.MaxValue;
		CorpseProxy corpseProxy = null;
		foreach (CorpseProxy corpse in _corpses)
		{
			if (corpse == null || !corpse.IsValid || !corpse.WasInnocentSide)
			{
				continue;
			}
			Vector3 val = corpse.Position - origin;
			float num2 = Vector3.Dot(val, direction);
			if (!(num2 < 0f) && !(num2 > maxDistance))
			{
				Vector3 val2 = val - direction * num2;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!(magnitude > 1f) && magnitude < num)
				{
					num = magnitude;
					corpseProxy = corpse;
				}
			}
		}
		if (corpseProxy != null)
		{
			ownerSmallId = corpseProxy.OwnerSmallID;
			corpsePos = corpseProxy.Position;
			return true;
		}
		return false;
	}

	public static void RemoveCorpseOf(ushort ownerSmallId)
	{
		for (int num = _corpses.Count - 1; num >= 0; num--)
		{
			if (_corpses[num] != null && _corpses[num].OwnerSmallID == ownerSmallId)
			{
				_corpses[num].Destroy();
				_corpses.RemoveAt(num);
			}
		}
		if (ownerSmallId != 0)
		{
			_recentlyRemoved[ownerSmallId] = Time.realtimeSinceStartup;
		}
	}

	private static void SpawnRagdollCorpse(Vector3 position, string avatarBarcode, Action<RigManager> onSpawned)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		PlayerRepUtilities.CreateNewRig((Action<RigManager>)delegate(RigManager rig)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			try
			{
				((Component)rig).transform.position = position;
				try
				{
					foreach (InventorySlotReceiver componentsInChild in ((Component)rig).GetComponentsInChildren<InventorySlotReceiver>(true))
					{
						((Behaviour)componentsInChild).enabled = false;
					}
				}
				catch
				{
				}
				if (!string.IsNullOrEmpty(avatarBarcode))
				{
					try
					{
						rig.SwapAvatarCrate(new Barcode(avatarBarcode), false, (Action<bool>)null);
					}
					catch
					{
					}
				}
				try
				{
					ControllerRig controllerRig = rig.ControllerRig;
					BaseController[] array = (BaseController[])(object)new BaseController[2]
					{
						(controllerRig != null) ? controllerRig.leftController : null,
						(controllerRig != null) ? controllerRig.rightController : null
					};
					foreach (BaseController obj3 in array)
					{
						Haptor val = ((obj3 != null) ? obj3.haptor : null);
						if (!((Object)(object)val == (Object)null))
						{
							val.hapticsAllowed = false;
							val.device_Controller = null;
							((Behaviour)val).enabled = false;
						}
					}
					foreach (Haptor componentsInChild2 in ((Component)rig).GetComponentsInChildren<Haptor>(true))
					{
						if (!((Object)(object)componentsInChild2 == (Object)null))
						{
							componentsInChild2.hapticsAllowed = false;
							componentsInChild2.device_Controller = null;
							((Behaviour)componentsInChild2).enabled = false;
						}
					}
				}
				catch
				{
				}
				try
				{
					rig.physicsRig.ShutdownRig();
					rig.physicsRig.RagdollRig();
				}
				catch
				{
				}
				try
				{
					ControllerRig controllerRig2 = rig.ControllerRig;
					BaseController[] array = (BaseController[])(object)new BaseController[2]
					{
						(controllerRig2 != null) ? controllerRig2.leftController : null,
						(controllerRig2 != null) ? controllerRig2.rightController : null
					};
					foreach (BaseController val2 in array)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							try
							{
								((Behaviour)val2).enabled = false;
							}
							catch
							{
							}
							try
							{
								((Component)val2).gameObject.SetActive(false);
							}
							catch
							{
							}
						}
					}
				}
				catch
				{
				}
				try
				{
					Hand[] array2 = (Hand[])(object)new Hand[2]
					{
						rig.physicsRig.leftHand,
						rig.physicsRig.rightHand
					};
					foreach (Hand val3 in array2)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							try
							{
								HandPoseAnimator animator = val3.Animator;
								if ((Object)(object)animator != (Object)null)
								{
									((Behaviour)animator).enabled = false;
								}
							}
							catch
							{
							}
							try
							{
								((Behaviour)val3).enabled = false;
							}
							catch
							{
							}
						}
					}
				}
				catch
				{
				}
				((Object)((Component)rig).gameObject).name = "[TIFT Corpse]";
				onSpawned?.Invoke(rig);
			}
			catch
			{
			}
		});
	}

	public static void Update()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (!RigData.HasPlayer)
		{
			return;
		}
		Hand leftHand = RigData.Refs.LeftHand;
		Transform val = ((leftHand != null) ? ((Component)leftHand).transform : null);
		Hand rightHand = RigData.Refs.RightHand;
		Transform val2 = ((rightHand != null) ? ((Component)rightHand).transform : null);
		Transform headset = RigData.Refs.Headset;
		Vector3 val3 = (((Object)(object)headset != (Object)null) ? headset.position : Vector3.zero);
		Vector3 val4 = (((Object)(object)val != (Object)null) ? val.position : val3);
		Vector3 val5 = (((Object)(object)val2 != (Object)null) ? val2.position : val3);
		CorpseProxy corpseProxy = null;
		float num = 1.2f;
		foreach (CorpseProxy corpse in _corpses)
		{
			if (corpse.IsValid)
			{
				Vector3 position = corpse.Position;
				float num2 = Mathf.Min(Vector3.Distance(val4, position), Vector3.Distance(val5, position));
				if (num2 < num)
				{
					num = num2;
					corpseProxy = corpse;
				}
			}
		}
		if (corpseProxy != null)
		{
			_inspectorUI.ShowFor(corpseProxy);
		}
		else
		{
			_inspectorUI.Hide();
		}
		_inspectorUI.Update();
	}

	public static void ClearAll()
	{
		_inspectorUI.Hide();
		try
		{
			LocalPlayer.ReleaseGrips();
		}
		catch
		{
		}
		foreach (CorpseProxy corpse in _corpses)
		{
			corpse.Destroy();
		}
		_corpses.Clear();
	}

	public static void DestroyUI()
	{
		_inspectorUI.DestroyUI();
	}
}
public static class CustomWeapons
{
	public enum WeaponType
	{
		GoldenPistol,
		ShadowKnife
	}

	private struct TrackedWeapon
	{
		public ushort EntityId;

		public WeaponType Type;
	}

	private static TrackedWeapon? _active;

	private const string PistolBarcode = "c1534c5a-fcfc-4f43-8fb0-d29531393131";

	private const string KnifeBarcode = "c1534c5a-1fb8-477c-afbe-2a95436f6d62";

	public const int GoldenPistolCost = 3;

	public const int ShadowKnifeCost = 2;

	public static bool GoldenPistolActive
	{
		get
		{
			if (_active.HasValue)
			{
				return _active.Value.Type == WeaponType.GoldenPistol;
			}
			return false;
		}
	}

	public static void BuyGoldenPistol(TroubleInFordTownGamemode gamemode)
	{
		if (!TraitorPoints.TrySpend(3))
		{
			ShowNotEnoughTP(3);
		}
		else
		{
			SpawnCustomWeapon("c1534c5a-fcfc-4f43-8fb0-d29531393131", WeaponType.GoldenPistol, ApplyGoldMaterial, gamemode);
		}
	}

	public static void BuyShadowKnife(TroubleInFordTownGamemode gamemode)
	{
		if (!TraitorPoints.TrySpend(2))
		{
			ShowNotEnoughTP(2);
		}
		else
		{
			SpawnCustomWeapon("c1534c5a-1fb8-477c-afbe-2a95436f6d62", WeaponType.ShadowKnife, ApplyShadowMaterial, gamemode);
		}
	}

	private static void SpawnCustomWeapon(string barcode, WeaponType type, Action<GameObject> materializer, TroubleInFordTownGamemode gamemode)
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		if (!RigData.HasPlayer)
		{
			return;
		}
		Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode);
		Transform headset = RigData.Refs.Headset;
		Vector3 position = headset.position + headset.forward * 0.5f;
		NetworkAssetSpawner.Spawn(new SpawnRequestInfo
		{
			Spawnable = spawnable,
			Position = position,
			Rotation = Quaternion.identity,
			SpawnEffect = true,
			SpawnCallback = delegate(SpawnCallbackInfo info)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				_active = new TrackedWeapon
				{
					EntityId = info.Entity.ID,
					Type = type
				};
				try
				{
					materializer(info.Spawned);
				}
				catch
				{
				}
				try
				{
					BoostDamage(info.Spawned);
				}
				catch
				{
				}
				gamemode.TryHolster(info.Spawned);
			}
		});
	}

	private static void BoostDamage(GameObject item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		foreach (MonoBehaviour componentsInChild in item.GetComponentsInChildren<MonoBehaviour>(true))
		{
			if ((Object)(object)componentsInChild == (Object)null)
			{
				continue;
			}
			try
			{
				FieldInfo field = ((object)componentsInChild).GetType().GetField("damage", BindingFlags.Instance | BindingFlags.Public);
				if (field != null && field.FieldType == typeof(float))
				{
					field.SetValue(componentsInChild, 99999f);
				}
			}
			catch
			{
			}
		}
	}

	public static void OnLocalKill()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		if (_active.HasValue)
		{
			TrackedWeapon value = _active.Value;
			_active = null;
			try
			{
				LocalPlayer.ReleaseGrips();
			}
			catch
			{
			}
			try
			{
				NetworkAssetSpawner.Despawn(new DespawnRequestInfo
				{
					EntityID = value.EntityId,
					DespawnEffect = true
				});
			}
			catch
			{
			}
			string text = ((value.Type == WeaponType.GoldenPistol) ? "Golden Pistol" : "Shadow Knife");
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit(text),
				Message = NotificationText.op_Implicit("Your one-use weapon has disappeared."),
				ShowPopup = true,
				PopupLength = 3f,
				Type = (NotificationType)0
			});
		}
	}

	public static void Reset()
	{
		_active = null;
	}

	private static void ApplyGoldMaterial(GameObject item)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		Color baseColor = default(Color);
		((Color)(ref baseColor))..ctor(1f, 0.78f, 0.1f);
		Color emissiveColor = default(Color);
		((Color)(ref emissiveColor))..ctor(0.4f, 0.28f, 0f);
		TintAllRenderers(item, baseColor, emissiveColor);
	}

	private static void ApplyShadowMaterial(GameObject item)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		Color baseColor = default(Color);
		((Color)(ref baseColor))..ctor(0.06f, 0f, 0.12f);
		Color emissiveColor = default(Color);
		((Color)(ref emissiveColor))..ctor(0.25f, 0f, 0.45f);
		TintAllRenderers(item, baseColor, emissiveColor);
	}

	private static void TintAllRenderers(GameObject item, Color baseColor, Color emissiveColor)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		foreach (MeshRenderer componentsInChild in item.GetComponentsInChildren<MeshRenderer>(true))
		{
			TintRenderer((Renderer)(object)componentsInChild, baseColor, emissiveColor);
		}
		foreach (SkinnedMeshRenderer componentsInChild2 in item.GetComponentsInChildren<SkinnedMeshRenderer>(true))
		{
			TintRenderer((Renderer)(object)componentsInChild2, baseColor, emissiveColor);
		}
	}

	private static void TintRenderer(Renderer rend, Color baseColor, Color emissiveColor)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		Il2CppReferenceArray<Material> materials = rend.materials;
		for (int i = 0; i < ((Il2CppArrayBase<Material>)(object)materials).Length; i++)
		{
			Material val = ((Il2CppArrayBase<Material>)(object)materials)[i];
			if (!((Object)(object)val == (Object)null))
			{
				if (val.HasProperty("_BaseColor"))
				{
					val.SetColor("_BaseColor", baseColor);
				}
				if (val.HasProperty("_Color"))
				{
					val.SetColor("_Color", baseColor);
				}
				if (val.HasProperty("_MainColor"))
				{
					val.SetColor("_MainColor", baseColor);
				}
				if (val.HasProperty("_TintColor"))
				{
					val.SetColor("_TintColor", baseColor);
				}
				if (val.HasProperty("_AlbedoColor"))
				{
					val.SetColor("_AlbedoColor", baseColor);
				}
				if (val.HasProperty("_EmissiveColor"))
				{
					val.SetColor("_EmissiveColor", emissiveColor);
				}
				if (val.HasProperty("_EmissionColor"))
				{
					val.SetColor("_EmissionColor", emissiveColor);
				}
				if (val.HasProperty("_Emission"))
				{
					val.SetColor("_Emission", emissiveColor);
				}
				val.EnableKeyword("_EMISSION");
				val.EnableKeyword("_EMISSIVE_COLOR_MAP");
			}
		}
		rend.materials = materials;
	}

	private static void ShowNotEnoughTP(int cost)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
			Message = NotificationText.op_Implicit($"You need {cost} TP but only have {TraitorPoints.Points}."),
			ShowPopup = true,
			PopupLength = 3f,
			Type = (NotificationType)1
		});
	}
}
public class HolsterHider
{
	private const string KnifeBarcode = "c1534c5a-1fb8-477c-afbe-2a95436f6d62";

	private const string OneStabKnifeBarcode = "JonLandon.TFTknife.Spawnable.TFTknife";

	private readonly Dictionary<GameObject, List<Renderer>> _hiddenProps = new Dictionary<GameObject, List<Renderer>>();

	private readonly Dictionary<int, bool> _knifeCache = new Dictionary<int, bool>();

	private static readonly List<GameObject> _localKnives = new List<GameObject>();

	private readonly HashSet<GameObject> _found = new HashSet<GameObject>();

	private readonly HashSet<GameObject> _evaluate = new HashSet<GameObject>();

	private readonly List<GameObject> _dead = new List<GameObject>();

	private float _timer;

	private const float RefreshInterval = 0.3f;

	public static void RegisterLocalKnife(GameObject go)
	{
		if ((Object)(object)go != (Object)null)
		{
			_localKnives.Add(go);
		}
	}

	public void Update()
	{
		foreach (KeyValuePair<GameObject, List<Renderer>> hiddenProp in _hiddenProps)
		{
			List<Renderer> value = hiddenProp.Value;
			for (int i = 0; i < value.Count; i++)
			{
				Renderer val = value[i];
				try
				{
					if ((Object)(object)val != (Object)null && !val.forceRenderingOff)
					{
						val.forceRenderingOff = true;
					}
				}
				catch
				{
				}
			}
		}
		_timer -= Time.deltaTime;
		if (_timer > 0f)
		{
			return;
		}
		_timer = 0.3f;
		_localKnives.RemoveAll((GameObject g) => (Object)(object)g == (Object)null);
		_found.Clear();
		try
		{
			foreach (WeaponSlot item in Object.FindObjectsOfType<WeaponSlot>())
			{
				if (!((Object)(object)item == (Object)null) && IsKnife(item))
				{
					Poolee componentInParent = ((Component)item).gameObject.GetComponentInParent<Poolee>();
					GameObject val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).gameObject : ((Component)((Component)item).transform.root).gameObject);
					if ((Object)(object)val2 != (Object)null && !IsLocalKnife(val2))
					{
						_found.Add(val2);
					}
				}
			}
		}
		catch
		{
		}
		_evaluate.Clear();
		foreach (GameObject item2 in _found)
		{
			_evaluate.Add(item2);
		}
		foreach (GameObject key in _hiddenProps.Keys)
		{
			_evaluate.Add(key);
		}
		foreach (GameObject item3 in _evaluate)
		{
			if ((Object)(object)item3 == (Object)null)
			{
				DropHidden(item3);
			}
			else if (IsHeld(item3))
			{
				Reveal(item3);
			}
			else
			{
				Conceal(item3);
			}
		}
		_dead.Clear();
		foreach (GameObject key2 in _hiddenProps.Keys)
		{
			if ((Object)(object)key2 == (Object)null)
			{
				_dead.Add(key2);
			}
		}
		foreach (GameObject item4 in _dead)
		{
			DropHidden(item4);
		}
	}

	private void Conceal(GameObject prop)
	{
		if (_hiddenProps.ContainsKey(prop))
		{
			return;
		}
		List<Renderer> list = new List<Renderer>();
		try
		{
			foreach (Renderer componentsInChild in prop.GetComponentsInChildren<Renderer>(true))
			{
				if (!((Object)(object)componentsInChild == (Object)null))
				{
					componentsInChild.forceRenderingOff = true;
					list.Add(componentsInChild);
				}
			}
		}
		catch
		{
		}
		_hiddenProps[prop] = list;
	}

	private void Reveal(GameObject prop)
	{
		if (!_hiddenProps.TryGetValue(prop, out var value))
		{
			return;
		}
		foreach (Renderer item in value)
		{
			try
			{
				if ((Object)(object)item != (Object)null)
				{
					item.forceRenderingOff = false;
				}
			}
			catch
			{
			}
		}
		_hiddenProps.Remove(prop);
	}

	private void DropHidden(GameObject prop)
	{
		_hiddenProps.Remove(prop);
	}

	private static bool IsHeld(GameObject propGO)
	{
		try
		{
			foreach (Grip componentsInChild in propGO.GetComponentsInChildren<Grip>(true))
			{
				if ((Object)(object)componentsInChild != (Object)null && componentsInChild.attachedHands != null && componentsInChild.attachedHands.Count > 0)
				{
					return true;
				}
			}
		}
		catch
		{
		}
		return false;
	}

	private static bool IsLocalKnife(GameObject propGO)
	{
		foreach (GameObject localKnife in _localKnives)
		{
			if ((Object)(object)localKnife == (Object)null)
			{
				continue;
			}
			if ((Object)(object)localKnife == (Object)(object)propGO)
			{
				return true;
			}
			try
			{
				if (localKnife.transform.IsChildOf(propGO.transform) || propGO.transform.IsChildOf(localKnife.transform))
				{
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	private bool IsKnife(WeaponSlot weapon)
	{
		int instanceID = ((Object)weapon).GetInstanceID();
		if (_knifeCache.TryGetValue(instanceID, out var value))
		{
			return value;
		}
		try
		{
			GameObject gameObject = ((Component)weapon).gameObject;
			Poolee val = Poolee.Cache.Get(gameObject);
			if ((Object)(object)val == (Object)null)
			{
				val = gameObject.GetComponentInParent<Poolee>();
			}
			object obj;
			if (val == null)
			{
				obj = null;
			}
			else
			{
				SpawnableCrate spawnableCrate = val.SpawnableCrate;
				if (spawnableCrate == null)
				{
					obj = null;
				}
				else
				{
					Barcode barcode = ((Scannable)spawnableCrate).Barcode;
					obj = ((barcode != null) ? barcode.ID : null);
				}
			}
			string text = (string)obj;
			if (!string.IsNullOrEmpty(text))
			{
				bool flag = text == "c1534c5a-1fb8-477c-afbe-2a95436f6d62" || text == "JonLandon.TFTknife.Spawnable.TFTknife";
				_knifeCache[instanceID] = flag;
				return flag;
			}
		}
		catch
		{
		}
		return false;
	}

	public void ClearAll()
	{
		foreach (KeyValuePair<GameObject, List<Renderer>> hiddenProp in _hiddenProps)
		{
			foreach (Renderer item in hiddenProp.Value)
			{
				try
				{
					if ((Object)(object)item != (Object)null)
					{
						item.forceRenderingOff = false;
					}
				}
				catch
				{
				}
			}
		}
		_hiddenProps.Clear();
		_knifeCache.Clear();
		_localKnives.Clear();
	}
}
public class HypnotistController
{
	public const float BrainwashSeconds = 9.5f;

	public Action<ushort> OnBrainwashComplete;

	private bool _charging;

	private ushort _targetId;

	private float _charge;

	private float _graceTimer;

	private GameObject _beamObj;

	private LineRenderer _beam;

	private AudioSource _audio;

	public static AudioClip ChargeClip;

	public void Update(string gunBarcode)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		if (!RigData.HasPlayer)
		{
			StopCharge();
			return;
		}
		Transform val = FindHeldGun(gunBarcode);
		if ((Object)(object)val == (Object)null)
		{
			StopCharge();
			return;
		}
		Vector3 position = val.position;
		Vector3 forward = val.forward;
		if (CorpseManager.TryGetInnocentCorpseAlongRay(position, forward, 30f, out var ownerSmallId, out var corpsePos) && ownerSmallId != 0)
		{
			if (_charging && _targetId == ownerSmallId)
			{
				_charge += Time.deltaTime;
			}
			else
			{
				_charging = true;
				_targetId = ownerSmallId;
				_charge = 0f;
				PlayChargeOnce(corpsePos);
			}
			_graceTimer = 0.6f;
			ShowBeam(position, corpsePos);
			if (_charge >= 9.5f)
			{
				ushort targetId = _targetId;
				StopCharge();
				OnBrainwashComplete?.Invoke(targetId);
			}
		}
		else if (_charging && _graceTimer > 0f)
		{
			_graceTimer -= Time.deltaTime;
			if ((Object)(object)_beamObj != (Object)null && _beamObj.activeSelf)
			{
				_beamObj.SetActive(false);
			}
		}
		else
		{
			StopCharge();
		}
	}

	public void Cleanup()
	{
		StopCharge();
		if ((Object)(object)_beamObj != (Object)null)
		{
			Object.Destroy((Object)(object)_beamObj);
			_beamObj = null;
			_beam = null;
		}
		if ((Object)(object)_audio != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)_audio).gameObject);
			_audio = null;
		}
	}

	private static Transform FindHeldGun(string gunBarcode)
	{
		try
		{
			PhysicsRig physicsRig = RigData.Refs.RigManager.physicsRig;
			Hand[] array = (Hand[])(object)new Hand[2] { physicsRig.rightHand, physicsRig.leftHand };
			foreach (Hand obj in array)
			{
				GameObject val = ((obj != null) ? obj.m_CurrentAttachedGO : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Gun componentInChildren = ((Component)val.transform.root).GetComponentInChildren<Gun>(true);
				Transform result = (((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.firePointTransform != (Object)null) ? componentInChildren.firePointTransform : (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform : val.transform));
				bool flag = false;
				if (!string.IsNullOrEmpty(gunBarcode))
				{
					Poolee val2 = Poolee.Cache.Get(val);
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = val.GetComponentInParent<Poolee>();
					}
					object obj2;
					if (val2 == null)
					{
						obj2 = null;
					}
					else
					{
						SpawnableCrate spawnableCrate = val2.SpawnableCrate;
						if (spawnableCrate == null)
						{
							obj2 = null;
						}
						else
						{
							Barcode barcode = ((Scannable)spawnableCrate).Barcode;
							obj2 = ((barcode != null) ? barcode.ID : null);
						}
					}
					if ((string?)obj2 == gunBarcode)
					{
						flag = true;
					}
				}
				if (flag || (Object)(object)componentInChildren != (Object)null)
				{
					return result;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private void ShowBeam(Vector3 from, Vector3 to)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Expected O, but got Unknown
		if ((Object)(object)_beamObj == (Object)null)
		{
			_beamObj = new GameObject("TIFT Brainwash Beam");
			Object.DontDestroyOnLoad((Object)(object)_beamObj);
			_beam = _beamObj.AddComponent<LineRenderer>();
			((Renderer)_beam).material = new Material(Shader.Find("Sprites/Default"));
			_beam.widthMultiplier = 0.03f;
			_beam.numCapVertices = 4;
		}
		float num = Mathf.Clamp01(_charge / 9.5f);
		Color val = Color.Lerp(new Color(0.6f, 0f, 1f), new Color(1f, 0.2f, 0.6f), num);
		_beam.startColor = val;
		_beam.endColor = val;
		_beam.SetPosition(0, from);
		_beam.SetPosition(1, to);
		if (!_beamObj.activeSelf)
		{
			_beamObj.SetActive(true);
		}
	}

	private void PlayChargeOnce(Vector3 position)
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		if (!((Object)(object)ChargeClip == (Object)null))
		{
			if ((Object)(object)_audio == (Object)null)
			{
				GameObject val = new GameObject("TIFT Brainwash Audio");
				Object.DontDestroyOnLoad((Object)(object)val);
				_audio = val.AddComponent<AudioSource>();
				_audio.loop = false;
				_audio.spatialBlend = 1f;
				_audio.minDistance = 2f;
				_audio.maxDistance = 25f;
				_audio.clip = ChargeClip;
				_audio.volume = 1f;
			}
			((Component)_audio).transform.position = position;
			_audio.Stop();
			_audio.Play();
		}
	}

	private void StopCharge()
	{
		_charging = false;
		_charge = 0f;
		_targetId = 0;
		if ((Object)(object)_beamObj != (Object)null && _beamObj.activeSelf)
		{
			_beamObj.SetActive(false);
		}
		if ((Object)(object)_audio != (Object)null && _audio.isPlaying)
		{
			_audio.Stop();
		}
	}
}
public static class KarmaManager
{
	public static bool Enabled = false;

	private static readonly Dictionary<ushort, int> _karma = new Dictionary<ushort, int>();

	public const int DefaultKarma = 1000;

	public const int MaxKarma = 2000;

	private const int KickThreshold = 350;

	private const int HighRiskThreshold = 500;

	private const int WarnThreshold = 700;

	public const int GoodKillReward = 200;

	public const int FriendlyFirePenalty = -400;

	public const int WrongKillPenalty = -300;

	public const int RoundParticipationBonus = 30;

	public static void EnsurePlayer(PlayerID player)
	{
		if (!_karma.ContainsKey(player.SmallID))
		{
			_karma[player.SmallID] = 1000;
		}
	}

	public static void RemovePlayer(PlayerID player)
	{
		_karma.Remove(player.SmallID);
	}

	public static int GetKarma(PlayerID player)
	{
		if (!_karma.TryGetValue(player.SmallID, out var value))
		{
			return 1000;
		}
		return value;
	}

	public static int GetLocalKarma()
	{
		PlayerID localID = PlayerIDManager.LocalID;
		if (localID == null)
		{
			return 1000;
		}
		return GetKarma(localID);
	}

	public static void AdjustKarma(PlayerID player, int delta)
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		if (Enabled)
		{
			EnsurePlayer(player);
			byte smallID = player.SmallID;
			_karma[smallID] = Math.Clamp(_karma[smallID] + delta, 0, 2000);
			if (player.IsMe)
			{
				int value = _karma[smallID];
				string value2 = ((delta >= 0) ? "+" : "");
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Karma"),
					Message = NotificationText.op_Implicit($"{value2}{delta} karma — you now have {value}"),
					ShowPopup = true,
					PopupLength = 3f,
					Type = (NotificationType)0
				});
			}
			if (NetworkInfo.IsHost)
			{
				CheckAndMaybeKick(player);
			}
		}
	}

	public static void AwardRoundBonus(PlayerID player)
	{
		AdjustKarma(player, 30);
	}

	private static void CheckAndMaybeKick(PlayerID player)
	{
		if (player.IsMe)
		{
			return;
		}
		int karma = GetKarma(player);
		if (karma <= 350)
		{
			TryKick(player, karma);
		}
		else if (karma <= 500)
		{
			if (Random.value < 0.6f)
			{
				TryKick(player, karma);
			}
			else
			{
				BroadcastLowKarmaWarning(player, karma);
			}
		}
		else if (karma <= 700)
		{
			BroadcastLowKarmaWarning(player, karma);
		}
	}

	private static void TryKick(PlayerID player, int karma)
	{
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		string value = default(string);
		MetadataHelper.TryGetDisplayName(player, ref value);
		MelonLogger.Msg($"[FordTown] Attempting to kick {value} for low karma ({karma}).");
		MelonLogger.Msg($"[FordTown Karma] Auto-kick triggered for {value} ({karma} karma) — no public kick API in this Fusion version.");
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Player Kicked"),
			Message = NotificationText.op_Implicit($"{value} was kicked for low karma ({karma})."),
			ShowPopup = true,
			PopupLength = 5f,
			Type = (NotificationType)1
		});
	}

	private static void BroadcastLowKarmaWarning(PlayerID player, int karma)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		string value = default(string);
		MetadataHelper.TryGetDisplayName(player, ref value);
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Low Karma Warning"),
			Message = NotificationText.op_Implicit($"{value} has low karma ({karma}). Play properly!"),
			ShowPopup = true,
			PopupLength = 5f,
			Type = (NotificationType)1
		});
	}

	public static void Clear()
	{
		_karma.Clear();
	}
}
public class RoleLabels
{
	private class Label
	{
		public GameObject Root;

		public TextMeshPro Text;
	}

	private readonly Dictionary<ushort, Label> _labels = new Dictionary<ushort, Label>();

	private static TMP_FontAsset _font;

	private readonly HashSet<ushort> _wanted = new HashSet<ushort>();

	private readonly List<ushort> _toRemove = new List<ushort>();

	private float _rebuildTimer;

	private const float RebuildInterval = 0.08f;

	private static readonly Color DetectiveBlue = new Color(0.2f, 0.6f, 1f);

	private static readonly Color TraitorRed = new Color(1f, 0.2f, 0.2f);

	private static readonly Color JesterPink = new Color(1f, 0.41f, 0.71f);

	private static readonly Color InnocentGreen = new Color(0.2f, 1f, 0.2f);

	private static readonly Color PsychopathRed = new Color(0.8f, 0f, 0f);

	private static readonly Color LoneWolfOrange = new Color(1f, 0.55f, 0f);

	private static readonly Color GlitchCyan = new Color(0f, 1f, 1f);

	private static readonly Color ZombieLime = new Color(0.37f, 0.8f, 0.1f);

	private static TMP_FontAsset GetFont()
	{
		if ((Object)(object)_font != (Object)null)
		{
			return _font;
		}
		Il2CppArrayBase<TMP_FontAsset> val = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
		foreach (TMP_FontAsset item in val)
		{
			if (((Object)item).name.ToLower().Contains("arlon-medium"))
			{
				_font = item;
				break;
			}
		}
		if ((Object)(object)_font == (Object)null && val.Length > 0)
		{
			_font = val[0];
		}
		return _font;
	}

	public void Update(TroubleInFordTownGamemode gm)
	{
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		if (gm == null || !((Gamemode)gm).IsStarted || !RigData.HasPlayer)
		{
			ClearAll();
			return;
		}
		Transform headset = RigData.Refs.Headset;
		if ((Object)(object)headset == (Object)null)
		{
			ClearAll();
			return;
		}
		_rebuildTimer -= Time.deltaTime;
		if (_rebuildTimer > 0f)
		{
			return;
		}
		_rebuildTimer = 0.08f;
		Team localTeam = gm.TeamManager.GetLocalTeam();
		bool flag = localTeam == gm.TraitorTeam;
		bool flag2 = localTeam == gm.SpectatorTeam;
		bool flag3 = localTeam == gm.ZombieTeam;
		HashSet<ushort> wanted = _wanted;
		wanted.Clear();
		foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
		{
			if (playerID == null || playerID.IsMe)
			{
				continue;
			}
			Team playerTeam = gm.TeamManager.GetPlayerTeam(playerID);
			if (playerTeam == null || playerTeam == gm.SpectatorTeam)
			{
				continue;
			}
			string text;
			Color color;
			if (flag2)
			{
				if (playerTeam == gm.TraitorTeam)
				{
					text = "TRAITOR";
					color = TraitorRed;
				}
				else if (playerTeam == gm.DetectiveTeam)
				{
					text = "DETECTIVE";
					color = DetectiveBlue;
				}
				else if (playerTeam == gm.JesterTeam)
				{
					text = "JESTER";
					color = JesterPink;
				}
				else if (playerTeam == gm.PsychopathTeam)
				{
					text = "PSYCHOPATH";
					color = PsychopathRed;
				}
				else if (playerTeam == gm.LoneWolfTeam)
				{
					text = "LONE WOLF";
					color = LoneWolfOrange;
				}
				else if (playerTeam == gm.GlitchTeam)
				{
					text = "GLITCH";
					color = GlitchCyan;
				}
				else if (playerTeam == gm.ZombieTeam)
				{
					text = "ZOMBIE";
					color = ZombieLime;
				}
				else
				{
					text = "INNOCENT";
					color = InnocentGreen;
				}
			}
			else if (flag3 && playerTeam == gm.ZombieTeam)
			{
				text = "ZOMBIE";
				color = ZombieLime;
			}
			else if (playerTeam == gm.DetectiveTeam)
			{
				text = "DETECTIVE";
				color = DetectiveBlue;
			}
			else if (flag && playerTeam == gm.JesterTeam)
			{
				text = "JESTER";
				color = JesterPink;
			}
			else
			{
				if (!flag || (playerTeam != gm.TraitorTeam && playerTeam != gm.GlitchTeam))
				{
					continue;
				}
				text = "TRAITOR";
				color = TraitorRed;
			}
			Transform head = GetHead(playerID);
			if (!((Object)(object)head == (Object)null))
			{
				wanted.Add(playerID.SmallID);
				Label label = EnsureLabel(playerID.SmallID);
				((TMP_Text)label.Text).text = text;
				((Graphic)label.Text).color = color;
				Vector3 val = head.position + Vector3.up * 0.5f;
				Vector3 val2 = val - headset.position;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val2 = Vector3.forward;
				}
				label.Root.transform.position = val;
				label.Root.transform.rotation = Quaternion.LookRotation(val2);
				if (!label.Root.activeSelf)
				{
					label.Root.SetActive(true);
				}
			}
		}
		if (_labels.Count <= 0)
		{
			return;
		}
		_toRemove.Clear();
		foreach (KeyValuePair<ushort, Label> label2 in _labels)
		{
			if (!wanted.Contains(label2.Key))
			{
				_toRemove.Add(label2.Key);
			}
		}
		foreach (ushort item in _toRemove)
		{
			if ((Object)(object)_labels[item].Root != (Object)null)
			{
				Object.Destroy((Object)(object)_labels[item].Root);
			}
			_labels.Remove(item);
		}
	}

	private static Transform GetHead(PlayerID pid)
	{
		try
		{
			NetworkPlayer val = default(NetworkPlayer);
			if (NetworkPlayerManager.TryGetPlayer(pid.SmallID, ref val))
			{
				RigRefs rigRefs = val.RigRefs;
				return (rigRefs != null) ? rigRefs.Head : null;
			}
		}
		catch
		{
		}
		return null;
	}

	private Label EnsureLabel(ushort smallId)
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		if (_labels.TryGetValue(smallId, out var value) && (Object)(object)value.Root != (Object)null)
		{
			return value;
		}
		GameObject val = new GameObject($"TIFT Role Label {smallId}");
		Object.DontDestroyOnLoad((Object)(object)val);
		((Object)val).hideFlags = (HideFlags)32;
		TextMeshPro val2 = val.AddComponent<TextMeshPro>();
		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<ushort, Label> label in _labels)
		{
			if ((Object)(object)label.Value.Root != (Object)null)
			{
				Object.Destroy((Object)(object)label.Value.Root);
			}
		}
		_labels.Clear();
	}
}
public class RolesInfoMenu
{
	private Page _page;

	private Page _settingsPage;

	private FunctionElement _karmaDisplay;

	public void Register()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0341: Unknown result type (might be due to invalid IL or missing references)
		_settingsPage = Page.Root.CreatePage("TFT Settings", new Color(0.85f, 0.85f, 0.2f), 0, true);
		_settingsPage.CreateBool("Mute Win Music (local)", new Color(0.9f, 0.5f, 0.2f), WinMusic.LocallyMuted, (Action<bool>)delegate(bool v)
		{
			WinMusic.LocallyMuted = v;
		});
		_karmaDisplay = _settingsPage.CreateFunction("Your Karma: —", new Color(0.4f, 0.8f, 1f), (Action)RefreshKarma);
		Menu.OnPageOpened += OnPageOpened;
		_page = Page.Root.CreatePage("Roles Info", Color.white, 7, true);
		AddRole("INNOCENT", new Color(0.2f, 1f, 0.2f), "Find and kill all the", "Traitors to win.");
		AddRole("TRAITOR", new Color(1f, 0.2f, 0.2f), "Secretly eliminate", "everyone else to win.", "Buy gear in the", "Traitor Shop.");
		AddRole("DETECTIVE", new Color(0.2f, 0.6f, 1f), "Publicly known to all.", "Leads the Innocents in", "hunting the Traitors.");
		AddRole("JESTER", new Color(1f, 0.41f, 0.71f), "Trick an Innocent into", "killing you to become", "the Psychopath. If a", "Traitor kills you, you lose.");
		AddRole("PSYCHOPATH", new Color(0.8f, 0f, 0f), "A second chance for the", "Jester after being killed", "by an Innocent. Kill", "everyone to win.");
		AddRole("LONE WOLF", new Color(1f, 0.55f, 0f), "A lone killer. Be the", "last one standing", "to win.");
		AddRole("GLITCH", new Color(0f, 1f, 1f), "Appears as a Traitor to", "the Traitors, but is", "secretly Innocent and", "wins with the Innocents.");
		AddRole("HYPNOTIST", new Color(0.61f, 0.19f, 1f), "A Traitor with a", "brainwashing gun. Aim it", "at a dead Innocent's", "corpse to revive them", "as a Traitor.");
		AddRole("ZOMBIE", new Color(0.37f, 0.8f, 0.1f), "Stab others with your", "knife to turn them into", "Zombies too. Infect", "everyone to win.");
		AddRole("SPECTATOR", new Color(0.67f, 0.67f, 0.67f), "You've been eliminated.", "Watch and wait for the", "round to end.");
	}

	private void AddRole(string name, Color color, params string[] lines)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		Page val = _page.CreatePage(name, color, 0, true);
		foreach (string text in lines)
		{
			val.CreateFunction(text, Color.white, (Action)delegate
			{
			});
		}
	}

	private void OnPageOpened(Page page)
	{
		if (page == _settingsPage)
		{
			RefreshKarma();
		}
	}

	private void RefreshKarma()
	{
		if (_karmaDisplay != null)
		{
			string elementName = (KarmaManager.Enabled ? $"Your Karma: {KarmaManager.GetLocalKarma()}" : "Your Karma: (Karma disabled)");
			((Element)_karmaDisplay).ElementName = elementName;
		}
	}

	public void Unregister()
	{
		Menu.OnPageOpened -= OnPageOpened;
		if (_page != null)
		{
			Page.Root.RemovePage(_page);
			_page = null;
		}
		if (_settingsPage != null)
		{
			Page.Root.RemovePage(_settingsPage);
			_settingsPage = null;
		}
	}
}
public class TraitorBuyMenu
{
	private Page _shopPage;

	private TroubleInFordTownGamemode _gamemode;

	private FunctionElement _tpHeader;

	private FunctionElement _pistolBtn;

	private FunctionElement _knifeBtn;

	private FunctionElement _healthBtn;

	private FunctionElement _statusLabel;

	public void Register(TroubleInFordTownGamemode gamemode)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		_gamemode = gamemode;
		_shopPage = Page.Root.CreatePage("Traitor Shop", new Color(0.85f, 0.1f, 0.1f), 0, true);
		_statusLabel = _shopPage.CreateFunction("Traitors only — in-round", Color.gray, (Action)delegate
		{
		});
		TraitorPoints.OnPointsChanged += Refresh;
		Menu.OnPageOpened += OnPageOpened;
	}

	private void OnPageOpened(Page page)
	{
		if (page == _shopPage)
		{
			Refresh();
		}
	}

	public void Unregister()
	{
		TraitorPoints.OnPointsChanged -= Refresh;
		Menu.OnPageOpened -= OnPageOpened;
		if (_shopPage != null)
		{
			Page.Root.RemovePage(_shopPage);
			_shopPage = null;
		}
		_gamemode = null;
	}

	public void Refresh()
	{
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		if (_shopPage == null || _gamemode == null)
		{
			return;
		}
		_shopPage.RemoveAll();
		_tpHeader = null;
		_pistolBtn = null;
		_knifeBtn = null;
		_healthBtn = null;
		_statusLabel = null;
		if (!((Gamemode)_gamemode).IsStarted || _gamemode.TeamManager.GetLocalTeam() != _gamemode.TraitorTeam)
		{
			_statusLabel = _shopPage.CreateFunction("Traitors only — in-round", Color.gray, (Action)delegate
			{
			});
			return;
		}
		int points = TraitorPoints.Points;
		_tpHeader = _shopPage.CreateFunction($"Traitor Points: {points}", Color.yellow, (Action)delegate
		{
			Refresh();
		});
		Color val = (Color)((points >= 1) ? new Color(0.2f, 0.9f, 0.3f) : Color.gray);
		_healthBtn = _shopPage.CreateFunction($"Health Boost  [{1} TP]  — restore full health", val, (Action)delegate
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			if (!TraitorPoints.TrySpend(1))
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
					Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."),
					ShowPopup = true,
					PopupLength = 2f,
					Type = (NotificationType)1
				});
			}
			else
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Health Boost!"),
					Message = NotificationText.op_Implicit("Your health has been restored."),
					ShowPopup = true,
					PopupLength = 3f,
					Type = (NotificationType)0
				});
				Refresh();
			}
		});
	}
}
public static class TraitorPoints
{
	public static int Points { get; private set; }

	public static event Action OnPointsChanged;

	public static void Reset()
	{
		Points = 2;
		TraitorPoints.OnPointsChanged?.Invoke();
	}

	public static void Clear()
	{
		Points = 0;
		TraitorPoints.OnPointsChanged?.Invoke();
	}

	public static void AddKillReward()
	{
		Points++;
		TraitorPoints.OnPointsChanged?.Invoke();
	}

	public static bool TrySpend(int cost)
	{
		if (Points < cost)
		{
			return false;
		}
		Points -= cost;
		TraitorPoints.OnPointsChanged?.Invoke();
		return true;
	}
}
public static class TraitorShopRadial
{
	private const int HealthCost = 1;

	private const int KnifeCost = 2;

	private static TroubleInFordTownGamemode _gamemode;

	private static bool _added;

	public static void AddMenuItems(TroubleInFordTownGamemode gamemode)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Expected O, but got Unknown
		RemoveMenuItems();
		_gamemode = gamemode;
		try
		{
			PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu;
			Page homePage = popUpMenu.radialPageView.m_HomePage;
			homePage.items.Add(new PageItem($"Health Boost [{1} TP]", (Directions)5, Action.op_Implicit((Action)delegate
			{
				popUpMenu.Deactivate();
				BuyHealth();
			})));
			homePage.items.Add(new PageItem($"Knife [{2} TP]", (Directions)6, Action.op_Implicit((Action)delegate
			{
				popUpMenu.Deactivate();
				BuyKnife();
			})));
			popUpMenu.radialPageView.Render(homePage);
			_added = true;
		}
		catch
		{
		}
	}

	public static void RemoveMenuItems()
	{
		if (!_added)
		{
			return;
		}
		try
		{
			PopUpMenuView popUpMenu = UIRig.Instance.popUpMenu;
			Page homePage = popUpMenu.radialPageView.m_HomePage;
			homePage.items.RemoveAll(Predicate<PageItem>.op_Implicit((Func<PageItem, bool>)((PageItem i) => i.name != null && (i.name.StartsWith("Golden Pistol") || i.name.StartsWith("Shadow Knife") || i.name.StartsWith("Knife") || i.name.StartsWith("Health Boost")))));
			popUpMenu.radialPageView.Render(homePage);
		}
		catch
		{
		}
		_added = false;
		_gamemode = null;
	}

	private static void BuyHealth()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Expected O, but got Unknown
		if (!TraitorPoints.TrySpend(1))
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
				Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."),
				ShowPopup = true,
				PopupLength = 2f,
				Type = (NotificationType)1
			});
			return;
		}
		try
		{
			if (RigData.HasPlayer)
			{
				RigData.Refs.RigManager.health.SetFullHealth();
			}
		}
		catch
		{
		}
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Health Boost!"),
			Message = NotificationText.op_Implicit("Your health has been restored."),
			ShowPopup = true,
			PopupLength = 3f,
			Type = (NotificationType)0
		});
	}

	private static void BuyKnife()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Expected O, but got Unknown
		if (!TraitorPoints.TrySpend(2))
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
				Message = NotificationText.op_Implicit($"You need {2} TP but only have {TraitorPoints.Points}."),
				ShowPopup = true,
				PopupLength = 2f,
				Type = (NotificationType)1
			});
		}
		else
		{
			try
			{
				_gamemode?.GiveTraitorKnife();
			}
			catch
			{
			}
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("Knife Purchased"),
				Message = NotificationText.op_Implicit("A knife has been holstered. Others can't see it on your body."),
				ShowPopup = true,
				PopupLength = 3f,
				Type = (NotificationType)0
			});
		}
	}
}
public class TroubleInFordTownGamemode : Gamemode
{
	public static class Defaults
	{
		public const int TraitorCount = 1;

		public const int PrepSeconds = 30;

		public const int RoundMinutes = 5;

		public const int WinnerBitReward = 100;

		public const int LoserBitReward = 25;

		public const int CorrectKillBitReward = 50;

		public static readonly MonoDiscReference[] Tracks = FusionMonoDiscPlaylists.AmbientPlaylist;

		public static readonly string[] Sidearms = new string[3] { "c1534c5a-fcfc-4f43-8fb0-d29531393131", "c1534c5a-2a4f-481f-8542-cc9545646572", "c1534c5a-bcb7-4f02-a4f5-da9550333530" };

		public static readonly string[] Primaries = new string[9] { "c1534c5a-a6b5-4177-beb8-04d947756e41", "c1534c5a-9112-49e5-b022-9c955269666c", "c1534c5a-c061-4c5c-a5e2-3d955269666c", "c1534c5a-d00c-4aa8-adfd-3495534d474d", "c1534c5a-8d03-42de-93c7-f595534d4755", "c1534c5a-4c47-428d-b5a5-b05747756e56", "c1534c5a-7f05-402f-9320-609647756e35", "c1534c5a-2774-48db-84fd-778447756e46", "c1534c5a-04d7-41a0-b7b8-5a95534d4750" };

		public const string TraitorKnife = "c1534c5a-1fb8-477c-afbe-2a95436f6d62";
	}

	private enum JesterDeath
	{
		BecamePsychopath,
		KilledByEnemy,
		NoKillerYet
	}

	public const string BrainwashGunBarcode = "JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun";

	private const string HypnotistMetaKey = "tift_hypnotist";

	private ushort _hypnotistSmallID;

	private bool _brainwashGunGiven;

	private float _brainwashGunRetry;

	private const string MusicMetaKey = "tift_music";

	private const string OneStabMetaKey = "tift_onestab";

	public const string OneStabKnifeBarcode = "JonLandon.TFTknife.Spawnable.TFTknife";

	private GameObject _oneStabKnife;

	private string _localPrimaryBarcode;

	private readonly HashSet<ushort> _deadPlayers = new HashSet<ushort>();

	private float _killedJesterTime = -999f;

	private const string TraitorColor = "#ff3333";

	private const string InnocentColor = "#33ff33";

	private const string DetectiveColor = "#3399ff";

	private const string SpectatorColor = "#aaaaaa";

	public const string JesterColor = "#ff69b4";

	public const string PsychopathColor = "#cc0000";

	public const string LoneWolfColor = "#ff8c00";

	public const string GlitchColor = "#00ffff";

	public const string HypnotistColor = "#9b30ff";

	public const string ZombieColor = "#5ecc1a";

	private readonly MusicPlaylist _playlist = new MusicPlaylist();

	private readonly TeamManager _teamManager = new TeamManager();

	private readonly Team _traitorTeam = new Team("Traitors");

	private readonly Team _innocentTeam = new Team("Innocents");

	private readonly Team _detectiveTeam = new Team("Detectives");

	private readonly Team _spectatorTeam = new Team("Spectators");

	private readonly Team _jesterTeam = new Team("Jesters");

	private readonly Team _psychopathTeam = new Team("Psychopaths");

	private readonly Team _loneWolfTeam = new Team("Lone Wolves");

	private readonly Team _glitchTeam = new Team("Glitches");

	private readonly Team _zombieTeam = new Team("Zombies");

	private bool _roundStarted;

	private float _elapsedTime;

	private bool _oneMinuteLeft;

	private bool _gameEnded;

	private bool _localDied;

	private Vector3 _localDeathPos = Vector3.zero;

	private bool _hasLocalDeathPos;

	private Vector3 _localLastAlivePos = Vector3.zero;

	private bool _hasLastAlivePos;

	private Vector3 _prevHeadPos = Vector3.zero;

	private bool _hasPrevHeadPos;

	private int _teleportCooldown;

	private float _roundLengthSeconds;

	private int _lastWristSecond = int.MinValue;

	private int _lastWristTP = int.MinValue;

	private object _lastWristTeam;

	private bool _wristTextInit;

	private float _spectatorTimer;

	private bool _stopScheduled;

	private float _stopDelayRemaining;

	private readonly WristIndicator _wristIndicator = new WristIndicator();

	private readonly TraitorBuyMenu _buyMenu = new TraitorBuyMenu();

	private readonly RolesInfoMenu _rolesInfoMenu = new RolesInfoMenu();

	private readonly RoleLabels _roleLabels = new RoleLabels();

	private readonly HolsterHider _holsterHider = new HolsterHider();

	private readonly HypnotistController _hypnotist = new HypnotistController();

	private readonly List<ushort> _spawnedLoadoutItems = new List<ushort>();

	private readonly Dictionary<ushort, Vector3> _lastKnownPositions = new Dictionary<ushort, Vector3>();

	private readonly Dictionary<ushort, ushort> _recentKillers = new Dictionary<ushort, ushort>();

	private readonly Dictionary<ushort, float> _recentKillTime = new Dictionary<ushort, float>();

	private const float KillFreshnessSeconds = 4f;

	private readonly Dictionary<ushort, string> _recentWeapons = new Dictionary<ushort, string>();

	public override string Title => "Trouble In FordTown";

	public override string Author => "JonLandonMods";

	public override string Barcode => "JonLandonMods.TroubleInFordTown";

	public override string Description => "Trouble In Traitor Town, in BONELAB! Traitors secretly eliminate Innocents. The Detective leads the good side. New roles: Jester (trick an Innocent into killing you to become Psychopath!), Lone Wolf (be the last one standing), and Glitch (appears as Traitor but wins with Innocents).";

	public int TraitorCount { get; set; } = 1;

	public int PrepSeconds { get; set; } = 30;

	public int RoundMinutes { get; set; } = 5;

	public bool DetectiveEnabled { get; set; } = true;

	public bool JesterEnabled { get; set; } = true;

	public bool LoneWolfEnabled { get; set; } = true;

	public bool GlitchEnabled { get; set; } = true;

	public bool HypnotistEnabled { get; set; } = true;

	public bool ZombieEnabled { get; set; } = true;

	public bool WinMusicEnabled { get; set; } = true;

	public bool OneStabKnifeEnabled { get; set; }

	public override bool DisableDevTools => true;

	public override bool DisableSpawnGun => true;

	public override bool DisableManualUnragdoll => true;

	public MusicPlaylist Playlist => _playlist;

	public TeamManager TeamManager => _teamManager;

	public Team TraitorTeam => _traitorTeam;

	public Team InnocentTeam => _innocentTeam;

	public Team DetectiveTeam => _detectiveTeam;

	public Team SpectatorTeam => _spectatorTeam;

	public Team JesterTeam => _jesterTeam;

	public Team PsychopathTeam => _psychopathTeam;

	public Team LoneWolfTeam => _loneWolfTeam;

	public Team GlitchTeam => _glitchTeam;

	public Team ZombieTeam => _zombieTeam;

	public TriggerEvent RoundStartedEvent { get; set; }

	public TriggerEvent OneMinuteLeftEvent { get; set; }

	public TriggerEvent InnocentVictoryEvent { get; set; }

	public TriggerEvent TraitorVictoryEvent { get; set; }

	public TriggerEvent PsychopathVictoryEvent { get; set; }

	public TriggerEvent LoneWolfVictoryEvent { get; set; }

	public TriggerEvent TimeUpEvent { get; set; }

	public TriggerEvent BrainwashEvent { get; set; }

	public TriggerEvent ZombieVictoryEvent { get; set; }

	public TriggerEvent CorpseSpawnEvent { get; set; }

	public override GroupElementData CreateSettingsGroup()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Expected O, but got Unknown
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Expected O, but got Unknown
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Expected O, but got Unknown
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Expected O, but got Unknown
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Expected O, but got Unknown
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Expected O, but got Unknown
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Expected O, but got Unknown
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Expected O, but got Unknown
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Expected O, but got Unknown
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Expected O, but got Unknown
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Expected O, but got Unknown
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Expected O, but got Unknown
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0303: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0326: Expected O, but got Unknown
		GroupElementData obj = ((Gamemode)this).CreateSettingsGroup();
		GroupElementData val = new GroupElementData("General");
		obj.AddElement<GroupElementData>(val);
		val.AddElement<IntElementData>(new IntElementData
		{
			Title = "Traitor Count",
			Value = TraitorCount,
			Increment = 1,
			MinValue = 1,
			MaxValue = 4,
			OnValueChanged = delegate(int v)
			{
				TraitorCount = v;
			}
		});
		val.AddElement<IntElementData>(new IntElementData
		{
			Title = "Prep Time (Seconds)",
			Value = PrepSeconds,
			Increment = 5,
			MinValue = 5,
			MaxValue = 60,
			OnValueChanged = delegate(int v)
			{
				PrepSeconds = v;
			}
		});
		val.AddElement<IntElementData>(new IntElementData
		{
			Title = "Round Length (Minutes)",
			Value = RoundMinutes,
			Increment = 1,
			MinValue = 1,
			MaxValue = 15,
			OnValueChanged = delegate(int v)
			{
				RoundMinutes = v;
			}
		});
		GroupElementData val2 = new GroupElementData("Extra Roles");
		obj.AddElement<GroupElementData>(val2);
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Detective",
			Value = DetectiveEnabled,
			OnValueChanged = delegate(bool v)
			{
				DetectiveEnabled = v;
			}
		});
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Jester",
			Value = JesterEnabled,
			OnValueChanged = delegate(bool v)
			{
				JesterEnabled = v;
			}
		});
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Lone Wolf",
			Value = LoneWolfEnabled,
			OnValueChanged = delegate(bool v)
			{
				LoneWolfEnabled = v;
			}
		});
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Glitch",
			Value = GlitchEnabled,
			OnValueChanged = delegate(bool v)
			{
				GlitchEnabled = v;
			}
		});
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Hypnotist (Traitor)",
			Value = HypnotistEnabled,
			OnValueChanged = delegate(bool v)
			{
				HypnotistEnabled = v;
			}
		});
		val2.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Zombie",
			Value = ZombieEnabled,
			OnValueChanged = delegate(bool v)
			{
				ZombieEnabled = v;
			}
		});
		GroupElementData val3 = new GroupElementData("Win Music");
		obj.AddElement<GroupElementData>(val3);
		val3.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Play Win Song",
			Value = WinMusicEnabled,
			OnValueChanged = delegate(bool v)
			{
				WinMusicEnabled = v;
			}
		});
		GroupElementData val4 = new GroupElementData("Karma");
		obj.AddElement<GroupElementData>(val4);
		val4.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Enable Karma System",
			Value = KarmaManager.Enabled,
			OnValueChanged = delegate(bool v)
			{
				KarmaManager.Enabled = v;
			}
		});
		GroupElementData val5 = new GroupElementData("Traitor Gear");
		obj.AddElement<GroupElementData>(val5);
		val5.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "One-Stab Knife (one-hit kill)",
			Value = OneStabKnifeEnabled,
			OnValueChanged = delegate(bool v)
			{
				OneStabKnifeEnabled = v;
			}
		});
		return obj;
	}

	public override bool CheckReadyConditions()
	{
		return PlayerIDManager.PlayerIDs.Count >= 2;
	}

	public override void OnGamemodeRegistered()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Expected O, but got Unknown
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Expected O, but got Unknown
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Expected O, but got Unknown
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Expected O, but got Unknown
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Expected O, but got Unknown
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Expected O, but got Unknown
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Expected O, but got Unknown
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Expected O, but got Unknown
		//IL_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Expected O, but got Unknown
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Expected O, but got Unknown
		MultiplayerHooking.OnPlayerAction += new PlayerAction(OnPlayerAction);
		FusionOverrides.OnValidateNametag += new UserOverride(OnValidateNametag);
		TeamManager.Register((Gamemode)(object)this);
		TeamManager.AddTeam(TraitorTeam);
		TeamManager.AddTeam(InnocentTeam);
		TeamManager.AddTeam(DetectiveTeam);
		TeamManager.AddTeam(SpectatorTeam);
		TeamManager.AddTeam(JesterTeam);
		TeamManager.AddTeam(PsychopathTeam);
		TeamManager.AddTeam(LoneWolfTeam);
		TeamManager.AddTeam(GlitchTeam);
		TeamManager.AddTeam(ZombieTeam);
		TeamManager.OnAssignedToTeam += OnAssignedToTeam;
		RoundStartedEvent = new TriggerEvent("RoundStarted", ((Gamemode)this).Relay, true);
		RoundStartedEvent.OnTriggeredWithValue += OnRoundStarted;
		OneMinuteLeftEvent = new TriggerEvent("OneMinuteLeft", ((Gamemode)this).Relay, true);
		OneMinuteLeftEvent.OnTriggered += OnOneMinuteLeft;
		InnocentVictoryEvent = new TriggerEvent("InnocentVictory", ((Gamemode)this).Relay, true);
		InnocentVictoryEvent.OnTriggered += OnInnocentVictory;
		TraitorVictoryEvent = new TriggerEvent("TraitorVictory", ((Gamemode)this).Relay, true);
		TraitorVictoryEvent.OnTriggered += OnTraitorVictory;
		PsychopathVictoryEvent = new TriggerEvent("PsychopathVictory", ((Gamemode)this).Relay, true);
		PsychopathVictoryEvent.OnTriggered += OnPsychopathVictory;
		LoneWolfVictoryEvent = new TriggerEvent("LoneWolfVictory", ((Gamemode)this).Relay, true);
		LoneWolfVictoryEvent.OnTriggered += OnLoneWolfVictory;
		TimeUpEvent = new TriggerEvent("TimeUp", ((Gamemode)this).Relay, true);
		TimeUpEvent.OnTriggered += OnTimeUp;
		ZombieVictoryEvent = new TriggerEvent("ZombieVictory", ((Gamemode)this).Relay, true);
		ZombieVictoryEvent.OnTriggered += OnZombieVictory;
		BrainwashEvent = new TriggerEvent("Brainwash", ((Gamemode)this).Relay, false);
		BrainwashEvent.OnTriggeredWithValue += OnBrainwash;
		CorpseSpawnEvent = new TriggerEvent("CorpseSpawn", ((Gamemode)this).Relay, false);
		CorpseSpawnEvent.OnTriggeredWithValue += OnCorpseSpawn;
		try
		{
			_buyMenu.Register(this);
		}
		catch (Exception ex)
		{
			MelonLogger.Warning("[FordTown] Traitor Shop menu unavailable: " + ex.Message);
		}
		try
		{
			_rolesInfoMenu.Register();
		}
		catch (Exception ex2)
		{
			MelonLogger.Warning("[FordTown] Roles Info menu unavailable: " + ex2.Message);
		}
		try
		{
			WinMusic.Initialize();
		}
		catch (Exception ex3)
		{
			MelonLogger.Warning("[FordTown] Win music unavailable: " + ex3.Message);
		}
		HypnotistController hypnotist = _hypnotist;
		hypnotist.OnBrainwashComplete = (Action<ushort>)Delegate.Combine(hypnotist.OnBrainwashComplete, (Action<ushort>)delegate(ushort targetId)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			try
			{
				BrainwashEvent.TryInvoke(targetId.ToString());
			}
			catch
			{
			}
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#9b30ff>BRAINWASH COMPLETE!</color>"),
				Message = NotificationText.op_Implicit("Their corpse has been turned into a Traitor."),
				ShowPopup = true,
				PopupLength = 4f,
				Type = (NotificationType)0
			});
		});
		LocalHealth.OnRespawn += OnLocalRespawn;
	}

	private void OnLocalRespawn()
	{
		if (!((Gamemode)this).IsStarted)
		{
			return;
		}
		try
		{
			LocalPlayer.ReleaseGrips();
		}
		catch
		{
		}
	}

	public override void OnGamemodeUnregistered()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		MultiplayerHooking.OnPlayerAction -= new PlayerAction(OnPlayerAction);
		FusionOverrides.OnValidateNametag -= new UserOverride(OnValidateNametag);
		LocalHealth.OnRespawn -= OnLocalRespawn;
		TeamManager.Unregister();
		TeamManager.OnAssignedToTeam -= OnAssignedToTeam;
		RoundStartedEvent.UnregisterEvent();
		RoundStartedEvent = null;
		OneMinuteLeftEvent.UnregisterEvent();
		OneMinuteLeftEvent = null;
		InnocentVictoryEvent.UnregisterEvent();
		InnocentVictoryEvent = null;
		TraitorVictoryEvent.UnregisterEvent();
		TraitorVictoryEvent = null;
		PsychopathVictoryEvent.UnregisterEvent();
		PsychopathVictoryEvent = null;
		LoneWolfVictoryEvent.UnregisterEvent();
		LoneWolfVictoryEvent = null;
		TimeUpEvent.UnregisterEvent();
		TimeUpEvent = null;
		ZombieVictoryEvent.UnregisterEvent();
		ZombieVictoryEvent = null;
		BrainwashEvent.UnregisterEvent();
		BrainwashEvent = null;
		CorpseSpawnEvent.UnregisterEvent();
		CorpseSpawnEvent = null;
		_hypnotist.Cleanup();
		try
		{
			_buyMenu.Unregister();
		}
		catch
		{
		}
		try
		{
			_rolesInfoMenu.Unregister();
		}
		catch
		{
		}
	}

	public override void OnGamemodeStarted()
	{
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Expected O, but got Unknown
		((Gamemode)this).OnGamemodeStarted();
		_roundStarted = false;
		_elapsedTime = 0f;
		_oneMinuteLeft = false;
		_gameEnded = false;
		_localDied = false;
		_hasLocalDeathPos = false;
		_hasLastAlivePos = false;
		_hasPrevHeadPos = false;
		_teleportCooldown = 0;
		_wristTextInit = false;
		_spectatorTimer = 0f;
		_brainwashGunGiven = false;
		_brainwashGunRetry = 0f;
		_hypnotistSmallID = 0;
		_roundLengthSeconds = 0f;
		_spawnedLoadoutItems.Clear();
		_lastKnownPositions.Clear();
		_recentKillers.Clear();
		_recentKillTime.Clear();
		_recentWeapons.Clear();
		_deadPlayers.Clear();
		_killedJesterTime = -999f;
		_localPrimaryBarcode = null;
		_oneStabKnife = null;
		OneStabState.LocalHolding = false;
		if (KarmaManager.Enabled)
		{
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				KarmaManager.EnsurePlayer(playerID);
			}
		}
		if (NetworkInfo.IsHost)
		{
			try
			{
				((Gamemode)this).Metadata.TrySetMetadata("tift_music", WinMusicEnabled ? "1" : "0");
			}
			catch
			{
			}
			try
			{
				((Gamemode)this).Metadata.TrySetMetadata("tift_onestab", OneStabKnifeEnabled ? "1" : "0");
			}
			catch
			{
			}
			try
			{
				((Gamemode)this).Metadata.TrySetMetadata("tift_hypnotist", "0");
			}
			catch
			{
			}
		}
		LocalHealth.MortalityOverride = true;
		LocalControls.DisableSlowMo = true;
		GamemodeHelper.SetSpawnPoints((IEnumerable<GamemodeMarker>)GamemodeMarker.FilterMarkers((BoneTagReference)null));
		GamemodeHelper.TeleportToSpawnPoint();
		FusionOverrides.ForceUpdateOverrides();
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Trouble In FordTown"),
			Message = NotificationText.op_Implicit($"Roles will be assigned in {PrepSeconds} seconds. Get ready!"),
			ShowPopup = true,
			PopupLength = 5f,
			Type = (NotificationType)0
		});
	}

	public override void OnGamemodeStopped()
	{
		((Gamemode)this).OnGamemodeStopped();
		_roundStarted = false;
		_elapsedTime = 0f;
		_oneMinuteLeft = false;
		_localDied = false;
		_deadPlayers.Clear();
		_oneStabKnife = null;
		OneStabState.LocalHolding = false;
		ClearSpectatorEffects();
		_wristIndicator.Destroy();
		_roleLabels.ClearAll();
		_holsterHider.ClearAll();
		ZombieState.LocalIsZombie = false;
		CorpseManager.ClearAll();
		CorpseManager.DestroyUI();
		TraitorShopRadial.RemoveMenuItems();
		CustomWeapons.Reset();
		TraitorPoints.Clear();
		DespawnLoadoutItems();
		Playlist.StopPlaylist();
		LocalHealth.MortalityOverride = null;
		LocalHealth.VitalityOverride = null;
		LocalControls.DisableSlowMo = false;
		GamemodeHelper.ResetSpawnPoints();
		if (NetworkInfo.IsHost)
		{
			TeamManager.UnassignAllPlayers();
		}
		FusionOverrides.ForceUpdateOverrides();
		_buyMenu.Refresh();
	}

	protected override void OnUpdate()
	{
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		if (!((Gamemode)this).IsStarted)
		{
			return;
		}
		_elapsedTime += TimeReferences.DeltaTime;
		ZombieState.LocalIsZombie = _roundStarted && TeamManager.GetLocalTeam() == ZombieTeam;
		OneStabState.LocalHolding = _roundStarted && (Object)(object)_oneStabKnife != (Object)null && IsHeldByLocal(_oneStabKnife);
		if (_roundStarted && !_localDied && RigData.HasPlayer)
		{
			try
			{
				Transform headset = RigData.Refs.Headset;
				if ((Object)(object)headset != (Object)null)
				{
					Vector3 val = headset.position - Vector3.up * 0.6f;
					if (_hasPrevHeadPos)
					{
						Vector3 val2 = val - _prevHeadPos;
						if (((Vector3)(ref val2)).sqrMagnitude > 6.25f)
						{
							_teleportCooldown = 8;
						}
					}
					if (_teleportCooldown > 0)
					{
						_teleportCooldown--;
					}
					else
					{
						_localLastAlivePos = val;
						_hasLastAlivePos = true;
					}
					_prevHeadPos = val;
					_hasPrevHeadPos = true;
				}
			}
			catch
			{
			}
		}
		UpdateSpectators();
		UpdateWristIndicator();
		CorpseManager.Update();
		_roleLabels.Update(this);
		if (_roundStarted)
		{
			_holsterHider.Update();
		}
		if (_roundStarted && TeamManager.GetLocalTeam() == TraitorTeam && IsLocalHypnotist())
		{
			if (!_brainwashGunGiven)
			{
				_brainwashGunRetry -= TimeReferences.DeltaTime;
				if (_brainwashGunRetry <= 0f)
				{
					_brainwashGunRetry = 1.5f;
					if (LocalHasBrainwashGun())
					{
						_brainwashGunGiven = true;
					}
					else if (RigData.HasPlayer)
					{
						GiveBrainwashGun();
					}
				}
			}
			_hypnotist.Update("JonLandon.BrainwashingGunTFT.Spawnable.BrainwashingGun");
		}
		if (NetworkInfo.IsHost && _stopScheduled)
		{
			_stopDelayRemaining -= TimeReferences.DeltaTime;
			if (_stopDelayRemaining <= 0f)
			{
				_stopScheduled = false;
				GamemodeManager.StopGamemode();
			}
		}
		if (!NetworkInfo.IsHost || _gameEnded)
		{
			return;
		}
		if (!_roundStarted && _elapsedTime >= (float)PrepSeconds)
		{
			AssignRoles();
			_roundStarted = true;
			_elapsedTime = 0f;
			RoundStartedEvent.TryInvoke(RoundMinutes.ToString());
		}
		if (_roundStarted)
		{
			float num = (float)RoundMinutes * 60f;
			if (!_oneMinuteLeft && num - _elapsedTime <= 60f)
			{
				_oneMinuteLeft = true;
				OneMinuteLeftEvent.TryInvoke();
			}
			if (_elapsedTime >= num)
			{
				_gameEnded = true;
				TimeUpEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled));
			}
		}
	}

	private void AssignRoles()
	{
		List<PlayerID> list = new List<PlayerID>(PlayerIDManager.PlayerIDs);
		IEnumerableExtensions.Shuffle<PlayerID>((IList<PlayerID>)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.TryAssi