Decompiled source of TroubleInFordTown v1.0.4

Mods/TroubleInFordTown.dll

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

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

public class CorpseProxy
{
	public RigManager Rig;

	public string PlayerName;

	public string RoleName;

	public string RoleColor;

	public string WeaponName;

	public float TimeOfDeath;

	public bool IsValid => (Object)(object)Rig != (Object)null && (Object)(object)((Component)Rig).gameObject != (Object)null;

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

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

	private TextMeshPro _text;

	private CorpseProxy _showing;

	private static TMP_FontAsset _font;

	private static TMP_FontAsset GetFont()
	{
		if ((Object)(object)_font != (Object)null)
		{
			return _font;
		}
		Il2CppArrayBase<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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_root != (Object)null)
		{
			return true;
		}
		if (!RigData.HasPlayer)
		{
			return false;
		}
		_root = new GameObject("TIFT Corpse Inspector");
		Object.DontDestroyOnLoad((Object)(object)_root);
		((Object)_root).hideFlags = (HideFlags)32;
		_root.SetActive(false);
		_text = _root.AddComponent<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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		if (!TryCreate())
		{
			return;
		}
		if (_showing == null || !_showing.IsValid)
		{
			_root.SetActive(false);
			return;
		}
		Transform headset = RigData.Refs.Headset;
		if ((Object)(object)headset == (Object)null)
		{
			_root.SetActive(false);
			return;
		}
		Vector3 val = _showing.Position + Vector3.up * 0.7f;
		Vector3 val2 = headset.position - val;
		if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
		{
			val2 = Vector3.forward;
		}
		_root.transform.position = val;
		_root.transform.rotation = Quaternion.LookRotation(-((Vector3)(ref val2)).normalized);
		float num = Time.realtimeSinceStartup - _showing.TimeOfDeath;
		string text = ((num < 60f) ? $"{Mathf.FloorToInt(num)}s ago" : $"{Mathf.FloorToInt(num / 60f)}m {Mathf.FloorToInt(num % 60f)}s ago");
		string text2 = (string.IsNullOrEmpty(_showing.WeaponName) ? "<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 const float GrabRadius = 1.2f;

	public static void RegisterDeath(string playerName, string roleName, string roleColor, Vector3 deathPosition, string weaponName = null, string avatarBarcode = null)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		SpawnRagdollCorpse(deathPosition, avatarBarcode, delegate(RigManager rig)
		{
			_corpses.Add(new CorpseProxy
			{
				Rig = rig,
				PlayerName = playerName,
				RoleName = roleName,
				RoleColor = roleColor,
				WeaponName = weaponName,
				TimeOfDeath = Time.realtimeSinceStartup
			});
		});
	}

	private static void SpawnRagdollCorpse(Vector3 position, string avatarBarcode, Action<RigManager> onSpawned)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		PlayerRepUtilities.CreateNewRig((Action<RigManager>)delegate(RigManager rig)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			try
			{
				((Component)rig).transform.position = position;
				try
				{
					foreach (InventorySlotReceiver componentsInChild in ((Component)rig).GetComponentsInChildren<InventorySlotReceiver>(true))
					{
						((Behaviour)componentsInChild).enabled = false;
					}
				}
				catch
				{
				}
				if (!string.IsNullOrEmpty(avatarBarcode))
				{
					try
					{
						rig.SwapAvatarCrate(new Barcode(avatarBarcode), false, (Action<bool>)null);
					}
					catch
					{
					}
				}
				try
				{
					rig.physicsRig.ShutdownRig();
					rig.physicsRig.RagdollRig();
				}
				catch
				{
				}
				((Object)((Component)rig).gameObject).name = "[TIFT Corpse]";
				onSpawned?.Invoke(rig);
			}
			catch
			{
			}
		});
	}

	public static void Update()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		if (!RigData.HasPlayer)
		{
			return;
		}
		Hand leftHand = RigData.Refs.LeftHand;
		Transform val = ((leftHand != null) ? ((Component)leftHand).transform : null);
		Hand rightHand = RigData.Refs.RightHand;
		Transform val2 = ((rightHand != null) ? ((Component)rightHand).transform : null);
		Transform headset = RigData.Refs.Headset;
		Vector3 val3 = (((Object)(object)headset != (Object)null) ? headset.position : Vector3.zero);
		Vector3 val4 = (((Object)(object)val != (Object)null) ? val.position : val3);
		Vector3 val5 = (((Object)(object)val2 != (Object)null) ? val2.position : val3);
		CorpseProxy corpseProxy = null;
		float num = 1.2f;
		foreach (CorpseProxy corpse in _corpses)
		{
			if (corpse.IsValid)
			{
				Vector3 position = corpse.Position;
				float num2 = Mathf.Min(Vector3.Distance(val4, position), Vector3.Distance(val5, position));
				if (num2 < num)
				{
					num = num2;
					corpseProxy = corpse;
				}
			}
		}
		if (corpseProxy != null)
		{
			_inspectorUI.ShowFor(corpseProxy);
		}
		else
		{
			_inspectorUI.Hide();
		}
		_inspectorUI.Update();
	}

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

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

	private struct TrackedWeapon
	{
		public ushort EntityId;

		public WeaponType Type;
	}

	private static TrackedWeapon? _active;

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

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

	public const int GoldenPistolCost = 3;

	public const int ShadowKnifeCost = 2;

	public static bool GoldenPistolActive => _active.HasValue && _active.Value.Type == WeaponType.GoldenPistol;

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

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

	private static void SpawnCustomWeapon(string barcode, WeaponType type, Action<GameObject> materializer, TroubleInFordTownGamemode gamemode)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		if (!RigData.HasPlayer)
		{
			return;
		}
		Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode);
		Transform headset = RigData.Refs.Headset;
		Vector3 position = headset.position + headset.forward * 0.5f;
		NetworkAssetSpawner.Spawn(new SpawnRequestInfo
		{
			Spawnable = spawnable,
			Position = position,
			Rotation = Quaternion.identity,
			SpawnEffect = true,
			SpawnCallback = delegate(SpawnCallbackInfo info)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				_active = new TrackedWeapon
				{
					EntityId = info.Entity.ID,
					Type = type
				};
				try
				{
					materializer(info.Spawned);
				}
				catch
				{
				}
				try
				{
					BoostDamage(info.Spawned);
				}
				catch
				{
				}
				gamemode.TryHolster(info.Spawned);
			}
		});
	}

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

	public static void OnLocalKill()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Expected O, but got Unknown
		if (_active.HasValue)
		{
			TrackedWeapon value = _active.Value;
			_active = null;
			try
			{
				LocalPlayer.ReleaseGrips();
			}
			catch
			{
			}
			try
			{
				NetworkAssetSpawner.Despawn(new DespawnRequestInfo
				{
					EntityID = value.EntityId,
					DespawnEffect = true
				});
			}
			catch
			{
			}
			string text = ((value.Type == WeaponType.GoldenPistol) ? "Golden Pistol" : "Shadow Knife");
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit(text),
				Message = NotificationText.op_Implicit("Your one-use weapon has disappeared."),
				ShowPopup = true,
				PopupLength = 3f,
				Type = (NotificationType)0
			});
		}
	}

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

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

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

	private static void TintAllRenderers(GameObject item, Color baseColor, Color emissiveColor)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)item == (Object)null)
		{
			return;
		}
		foreach (MeshRenderer componentsInChild in item.GetComponentsInChildren<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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		Il2CppReferenceArray<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_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
			Message = NotificationText.op_Implicit($"You need {cost} TP but only have {TraitorPoints.Points}."),
			ShowPopup = true,
			PopupLength = 3f,
			Type = (NotificationType)1
		});
	}
}
[HarmonyPatch(typeof(PlayerDamageReceiver), "ReceiveAttack")]
public static class GoldenPistolDamagePatch
{
	[HarmonyPrefix]
	[HarmonyPriority(800)]
	public static void Prefix(PlayerDamageReceiver __instance, ref Attack attack)
	{
		if (!CustomWeapons.GoldenPistolActive)
		{
			return;
		}
		try
		{
			TriggerRefProxy proxy = attack.proxy;
			if (!((Object)(object)proxy == (Object)null) && !((Object)(object)proxy.root == (Object)null))
			{
				RigManager val = RigManager.Cache.Get(proxy.root);
				if (!((Object)(object)val == (Object)null) && FusionPlayer.IsLocalPlayer(val))
				{
					attack.damage = 999999f;
				}
			}
		}
		catch
		{
		}
	}
}
public static class KarmaManager
{
	public static bool Enabled = false;

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

	public const int DefaultKarma = 1000;

	public const int MaxKarma = 1000;

	private const int KickThreshold = 350;

	private const int HighRiskThreshold = 500;

	private const int WarnThreshold = 700;

	public const int GoodKillReward = 200;

	public const int FriendlyFirePenalty = -400;

	public const int WrongKillPenalty = -300;

	public const int RoundParticipationBonus = 30;

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

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

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

	public static void AdjustKarma(PlayerID player, int delta)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Expected O, but got Unknown
		if (Enabled)
		{
			EnsurePlayer(player);
			byte smallID = player.SmallID;
			_karma[smallID] = Math.Clamp(_karma[smallID] + delta, 0, 1000);
			if (player.IsMe)
			{
				int value = _karma[smallID];
				string value2 = ((delta >= 0) ? "+" : "");
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Karma"),
					Message = NotificationText.op_Implicit($"{value2}{delta} karma — you now have {value}"),
					ShowPopup = true,
					PopupLength = 3f,
					Type = (NotificationType)0
				});
			}
			if (NetworkInfo.IsHost)
			{
				CheckAndMaybeKick(player);
			}
		}
	}

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

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

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

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

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

		public TextMeshPro Text;
	}

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

	private static TMP_FontAsset _font;

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

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

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

	private static TMP_FontAsset GetFont()
	{
		if ((Object)(object)_font != (Object)null)
		{
			return _font;
		}
		Il2CppArrayBase<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_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		if (gm == null || !((Gamemode)gm).IsStarted || !RigData.HasPlayer)
		{
			ClearAll();
			return;
		}
		Transform headset = RigData.Refs.Headset;
		if ((Object)(object)headset == (Object)null)
		{
			ClearAll();
			return;
		}
		Team localTeam = gm.TeamManager.GetLocalTeam();
		bool flag = localTeam == gm.TraitorTeam;
		HashSet<ushort> hashSet = new HashSet<ushort>();
		foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
		{
			if (playerID == null || playerID.IsMe)
			{
				continue;
			}
			Team playerTeam = gm.TeamManager.GetPlayerTeam(playerID);
			if (playerTeam == null || playerTeam == gm.SpectatorTeam)
			{
				continue;
			}
			string text;
			Color color;
			if (playerTeam == gm.DetectiveTeam)
			{
				text = "DETECTIVE";
				color = DetectiveBlue;
			}
			else if (flag && playerTeam == gm.JesterTeam)
			{
				text = "JESTER";
				color = JesterPink;
			}
			else
			{
				if (!flag || (playerTeam != gm.TraitorTeam && playerTeam != gm.GlitchTeam))
				{
					continue;
				}
				text = "TRAITOR";
				color = TraitorRed;
			}
			Transform head = GetHead(playerID);
			if (!((Object)(object)head == (Object)null))
			{
				hashSet.Add(playerID.SmallID);
				Label label = EnsureLabel(playerID.SmallID);
				((TMP_Text)label.Text).text = text;
				((Graphic)label.Text).color = color;
				Vector3 val = head.position + Vector3.up * 0.5f;
				Vector3 val2 = val - headset.position;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val2 = Vector3.forward;
				}
				label.Root.transform.position = val;
				label.Root.transform.rotation = Quaternion.LookRotation(val2);
				if (!label.Root.activeSelf)
				{
					label.Root.SetActive(true);
				}
			}
		}
		if (_labels.Count <= 0)
		{
			return;
		}
		List<ushort> list = new List<ushort>();
		foreach (KeyValuePair<ushort, Label> label2 in _labels)
		{
			if (!hashSet.Contains(label2.Key))
			{
				list.Add(label2.Key);
			}
		}
		foreach (ushort item in list)
		{
			if ((Object)(object)_labels[item].Root != (Object)null)
			{
				Object.Destroy((Object)(object)_labels[item].Root);
			}
			_labels.Remove(item);
		}
	}

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

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

	public void Register()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		_settingsPage = Page.Root.CreatePage("TFT Settings", new Color(0.85f, 0.85f, 0.2f), 0, true);
		_settingsPage.CreateBool("Mute Win Music (local)", new Color(0.9f, 0.5f, 0.2f), WinMusic.LocallyMuted, (Action<bool>)delegate(bool v)
		{
			WinMusic.LocallyMuted = v;
		});
		_page = Page.Root.CreatePage("Roles Info", Color.white, 0, true);
		_page.CreateFunction("INNOCENT  —  Find & kill all Traitors to win", new Color(0.2f, 1f, 0.2f), (Action)delegate
		{
		});
		_page.CreateFunction("TRAITOR  —  Eliminate everyone secretly to win", new Color(1f, 0.2f, 0.2f), (Action)delegate
		{
		});
		_page.CreateFunction("DETECTIVE  —  Publicly known; leads the Innocents", new Color(0.2f, 0.6f, 1f), (Action)delegate
		{
		});
		_page.CreateFunction("JESTER  —  Get an Innocent to kill you → become Psychopath", new Color(1f, 0.41f, 0.71f), (Action)delegate
		{
		});
		_page.CreateFunction("PSYCHOPATH  —  Kill everyone after converting from Jester", new Color(0.8f, 0f, 0f), (Action)delegate
		{
		});
		_page.CreateFunction("LONE WOLF  —  Be the last one alive to win", new Color(1f, 0.55f, 0f), (Action)delegate
		{
		});
		_page.CreateFunction("GLITCH  —  Looks like a Traitor; secretly wins with Innocents", new Color(0f, 1f, 1f), (Action)delegate
		{
		});
		_page.CreateFunction("SPECTATOR  —  Eliminated; wait for round end", new Color(0.67f, 0.67f, 0.67f), (Action)delegate
		{
		});
	}

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

	private TroubleInFordTownGamemode _gamemode;

	private FunctionElement _tpHeader;

	private FunctionElement _pistolBtn;

	private FunctionElement _knifeBtn;

	private FunctionElement _healthBtn;

	private FunctionElement _statusLabel;

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

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

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

	public void Refresh()
	{
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		if (_shopPage == null || _gamemode == null)
		{
			return;
		}
		_shopPage.RemoveAll();
		_tpHeader = null;
		_pistolBtn = null;
		_knifeBtn = null;
		_healthBtn = null;
		_statusLabel = null;
		if (!((Gamemode)_gamemode).IsStarted || _gamemode.TeamManager.GetLocalTeam() != _gamemode.TraitorTeam)
		{
			_statusLabel = _shopPage.CreateFunction("Traitors only — in-round", Color.gray, (Action)delegate
			{
			});
			return;
		}
		int points = TraitorPoints.Points;
		_tpHeader = _shopPage.CreateFunction($"Traitor Points: {points}", Color.yellow, (Action)delegate
		{
			Refresh();
		});
		Color val = (Color)((points >= 1) ? new Color(0.2f, 0.9f, 0.3f) : Color.gray);
		_healthBtn = _shopPage.CreateFunction($"Health Boost  [{1} TP]  — restore full health", val, (Action)delegate
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			if (!TraitorPoints.TrySpend(1))
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
					Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."),
					ShowPopup = true,
					PopupLength = 2f,
					Type = (NotificationType)1
				});
			}
			else
			{
				try
				{
				}
				catch
				{
				}
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Health Boost!"),
					Message = NotificationText.op_Implicit("Your health has been restored."),
					ShowPopup = true,
					PopupLength = 3f,
					Type = (NotificationType)0
				});
				Refresh();
			}
		});
	}
}
public static class TraitorPoints
{
	public static int Points { get; private set; }

	public static event Action OnPointsChanged;

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

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

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

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

	private static TroubleInFordTownGamemode _gamemode;

	private static bool _added;

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

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

	private static void BuyHealth()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Expected O, but got Unknown
		if (!TraitorPoints.TrySpend(1))
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("Not Enough Traitor Points"),
				Message = NotificationText.op_Implicit($"You need {1} TP but only have {TraitorPoints.Points}."),
				ShowPopup = true,
				PopupLength = 2f,
				Type = (NotificationType)1
			});
			return;
		}
		try
		{
			if (RigData.HasPlayer)
			{
				RigData.Refs.RigManager.health.SetFullHealth();
			}
		}
		catch
		{
		}
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Health Boost!"),
			Message = NotificationText.op_Implicit("Your health has been restored."),
			ShowPopup = true,
			PopupLength = 3f,
			Type = (NotificationType)0
		});
	}
}
public class TroubleInFordTownGamemode : Gamemode
{
	public static class Defaults
	{
		public const int TraitorCount = 1;

		public const int PrepSeconds = 30;

		public const int RoundMinutes = 5;

		public const int WinnerBitReward = 100;

		public const int LoserBitReward = 25;

		public const int CorrectKillBitReward = 50;

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

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

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

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

	private const string MusicMetaKey = "tift_music";

	private const string TraitorColor = "#ff3333";

	private const string InnocentColor = "#33ff33";

	private const string DetectiveColor = "#3399ff";

	private const string SpectatorColor = "#aaaaaa";

	public const string JesterColor = "#ff69b4";

	public const string PsychopathColor = "#cc0000";

	public const string LoneWolfColor = "#ff8c00";

	public const string GlitchColor = "#00ffff";

	private readonly MusicPlaylist _playlist = new MusicPlaylist();

	private readonly TeamManager _teamManager = new TeamManager();

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

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

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

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

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

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

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

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

	private bool _roundStarted = false;

	private float _elapsedTime = 0f;

	private bool _oneMinuteLeft = false;

	private bool _gameEnded = false;

	private bool _localDied = false;

	private Vector3 _localDeathPos = Vector3.zero;

	private bool _hasLocalDeathPos = false;

	private float _roundLengthSeconds = 0f;

	private bool _stopScheduled = false;

	private float _stopDelayRemaining = 0f;

	private readonly WristIndicator _wristIndicator = new WristIndicator();

	private readonly TraitorBuyMenu _buyMenu = new TraitorBuyMenu();

	private readonly RolesInfoMenu _rolesInfoMenu = new RolesInfoMenu();

	private readonly RoleLabels _roleLabels = new RoleLabels();

	private readonly List<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 = 2.5f;

	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 WinMusicEnabled { get; set; } = true;

	public override bool DisableDevTools => true;

	public override bool DisableSpawnGun => true;

	public override bool DisableManualUnragdoll => true;

	public MusicPlaylist Playlist => _playlist;

	public TeamManager TeamManager => _teamManager;

	public Team TraitorTeam => _traitorTeam;

	public Team InnocentTeam => _innocentTeam;

	public Team DetectiveTeam => _detectiveTeam;

	public Team SpectatorTeam => _spectatorTeam;

	public Team JesterTeam => _jesterTeam;

	public Team PsychopathTeam => _psychopathTeam;

	public Team LoneWolfTeam => _loneWolfTeam;

	public Team GlitchTeam => _glitchTeam;

	public TriggerEvent RoundStartedEvent { get; set; }

	public TriggerEvent OneMinuteLeftEvent { get; set; }

	public TriggerEvent InnocentVictoryEvent { get; set; }

	public TriggerEvent TraitorVictoryEvent { get; set; }

	public TriggerEvent PsychopathVictoryEvent { get; set; }

	public TriggerEvent LoneWolfVictoryEvent { get; set; }

	public TriggerEvent TimeUpEvent { get; set; }

	public override GroupElementData CreateSettingsGroup()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Expected O, but got Unknown
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected O, but got Unknown
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Expected O, but got Unknown
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Expected O, but got Unknown
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Expected O, but got Unknown
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Expected O, but got Unknown
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Expected O, but got Unknown
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Expected O, but got Unknown
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Expected O, but got Unknown
		//IL_025a: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a1: Expected O, but got Unknown
		GroupElementData val = ((Gamemode)this).CreateSettingsGroup();
		GroupElementData val2 = new GroupElementData("General");
		val.AddElement<GroupElementData>(val2);
		val2.AddElement<IntElementData>(new IntElementData
		{
			Title = "Traitor Count",
			Value = TraitorCount,
			Increment = 1,
			MinValue = 1,
			MaxValue = 4,
			OnValueChanged = delegate(int v)
			{
				TraitorCount = v;
			}
		});
		val2.AddElement<IntElementData>(new IntElementData
		{
			Title = "Prep Time (Seconds)",
			Value = PrepSeconds,
			Increment = 5,
			MinValue = 5,
			MaxValue = 60,
			OnValueChanged = delegate(int v)
			{
				PrepSeconds = v;
			}
		});
		val2.AddElement<IntElementData>(new IntElementData
		{
			Title = "Round Length (Minutes)",
			Value = RoundMinutes,
			Increment = 1,
			MinValue = 1,
			MaxValue = 15,
			OnValueChanged = delegate(int v)
			{
				RoundMinutes = v;
			}
		});
		GroupElementData val3 = new GroupElementData("Extra Roles");
		val.AddElement<GroupElementData>(val3);
		val3.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Detective",
			Value = DetectiveEnabled,
			OnValueChanged = delegate(bool v)
			{
				DetectiveEnabled = v;
			}
		});
		val3.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Jester",
			Value = JesterEnabled,
			OnValueChanged = delegate(bool v)
			{
				JesterEnabled = v;
			}
		});
		val3.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Lone Wolf",
			Value = LoneWolfEnabled,
			OnValueChanged = delegate(bool v)
			{
				LoneWolfEnabled = v;
			}
		});
		val3.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Glitch",
			Value = GlitchEnabled,
			OnValueChanged = delegate(bool v)
			{
				GlitchEnabled = v;
			}
		});
		GroupElementData val4 = new GroupElementData("Win Music");
		val.AddElement<GroupElementData>(val4);
		val4.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Play Win Song",
			Value = WinMusicEnabled,
			OnValueChanged = delegate(bool v)
			{
				WinMusicEnabled = v;
			}
		});
		GroupElementData val5 = new GroupElementData("Karma");
		val.AddElement<GroupElementData>(val5);
		val5.AddElement<BoolElementData>(new BoolElementData
		{
			Title = "Enable Karma System",
			Value = KarmaManager.Enabled,
			OnValueChanged = delegate(bool v)
			{
				KarmaManager.Enabled = v;
			}
		});
		return val;
	}

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

	public override void OnGamemodeRegistered()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Expected O, but got Unknown
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Expected O, but got Unknown
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Expected O, but got Unknown
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Expected O, but got Unknown
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Expected O, but got Unknown
		MultiplayerHooking.OnPlayerAction += new PlayerAction(OnPlayerAction);
		FusionOverrides.OnValidateNametag += new UserOverride(OnValidateNametag);
		TeamManager.Register((Gamemode)(object)this);
		TeamManager.AddTeam(TraitorTeam);
		TeamManager.AddTeam(InnocentTeam);
		TeamManager.AddTeam(DetectiveTeam);
		TeamManager.AddTeam(SpectatorTeam);
		TeamManager.AddTeam(JesterTeam);
		TeamManager.AddTeam(PsychopathTeam);
		TeamManager.AddTeam(LoneWolfTeam);
		TeamManager.AddTeam(GlitchTeam);
		TeamManager.OnAssignedToTeam += OnAssignedToTeam;
		RoundStartedEvent = new TriggerEvent("RoundStarted", ((Gamemode)this).Relay, true);
		RoundStartedEvent.OnTriggeredWithValue += OnRoundStarted;
		OneMinuteLeftEvent = new TriggerEvent("OneMinuteLeft", ((Gamemode)this).Relay, true);
		OneMinuteLeftEvent.OnTriggered += OnOneMinuteLeft;
		InnocentVictoryEvent = new TriggerEvent("InnocentVictory", ((Gamemode)this).Relay, true);
		InnocentVictoryEvent.OnTriggered += OnInnocentVictory;
		TraitorVictoryEvent = new TriggerEvent("TraitorVictory", ((Gamemode)this).Relay, true);
		TraitorVictoryEvent.OnTriggered += OnTraitorVictory;
		PsychopathVictoryEvent = new TriggerEvent("PsychopathVictory", ((Gamemode)this).Relay, true);
		PsychopathVictoryEvent.OnTriggered += OnPsychopathVictory;
		LoneWolfVictoryEvent = new TriggerEvent("LoneWolfVictory", ((Gamemode)this).Relay, true);
		LoneWolfVictoryEvent.OnTriggered += OnLoneWolfVictory;
		TimeUpEvent = new TriggerEvent("TimeUp", ((Gamemode)this).Relay, true);
		TimeUpEvent.OnTriggered += OnTimeUp;
		_buyMenu.Register(this);
		_rolesInfoMenu.Register();
		WinMusic.Initialize();
		LocalHealth.OnRespawn += OnLocalRespawn;
	}

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

	public override void OnGamemodeUnregistered()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Expected O, but got Unknown
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		MultiplayerHooking.OnPlayerAction -= new PlayerAction(OnPlayerAction);
		FusionOverrides.OnValidateNametag -= new UserOverride(OnValidateNametag);
		LocalHealth.OnRespawn -= OnLocalRespawn;
		TeamManager.Unregister();
		TeamManager.OnAssignedToTeam -= OnAssignedToTeam;
		RoundStartedEvent.UnregisterEvent();
		RoundStartedEvent = null;
		OneMinuteLeftEvent.UnregisterEvent();
		OneMinuteLeftEvent = null;
		InnocentVictoryEvent.UnregisterEvent();
		InnocentVictoryEvent = null;
		TraitorVictoryEvent.UnregisterEvent();
		TraitorVictoryEvent = null;
		PsychopathVictoryEvent.UnregisterEvent();
		PsychopathVictoryEvent = null;
		LoneWolfVictoryEvent.UnregisterEvent();
		LoneWolfVictoryEvent = null;
		TimeUpEvent.UnregisterEvent();
		TimeUpEvent = null;
		_buyMenu.Unregister();
		_rolesInfoMenu.Unregister();
	}

	public override void OnGamemodeStarted()
	{
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Expected O, but got Unknown
		((Gamemode)this).OnGamemodeStarted();
		_roundStarted = false;
		_elapsedTime = 0f;
		_oneMinuteLeft = false;
		_gameEnded = false;
		_localDied = false;
		_hasLocalDeathPos = false;
		_roundLengthSeconds = 0f;
		_spawnedLoadoutItems.Clear();
		_lastKnownPositions.Clear();
		_recentKillers.Clear();
		_recentKillTime.Clear();
		_recentWeapons.Clear();
		if (KarmaManager.Enabled)
		{
			foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
			{
				KarmaManager.EnsurePlayer(playerID);
			}
		}
		if (NetworkInfo.IsHost)
		{
			try
			{
				((Gamemode)this).Metadata.TrySetMetadata("tift_music", WinMusicEnabled ? "1" : "0");
			}
			catch
			{
			}
		}
		Playlist.SetPlaylist(AudioReference.CreateReferences(Defaults.Tracks));
		Playlist.Shuffle();
		Playlist.StartPlaylist();
		LocalHealth.MortalityOverride = true;
		LocalControls.DisableSlowMo = true;
		GamemodeHelper.SetSpawnPoints((IEnumerable<GamemodeMarker>)GamemodeMarker.FilterMarkers((BoneTagReference)null));
		GamemodeHelper.TeleportToSpawnPoint();
		FusionOverrides.ForceUpdateOverrides();
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("Trouble In FordTown"),
			Message = NotificationText.op_Implicit($"Roles will be assigned in {PrepSeconds} seconds. Get ready!"),
			ShowPopup = true,
			PopupLength = 5f,
			Type = (NotificationType)0
		});
	}

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

	protected override void OnUpdate()
	{
		if (!((Gamemode)this).IsStarted)
		{
			return;
		}
		Playlist.Update();
		_elapsedTime += TimeReferences.DeltaTime;
		UpdateSpectators();
		UpdateWristIndicator();
		CorpseManager.Update();
		_roleLabels.Update(this);
		if (NetworkInfo.IsHost && _stopScheduled)
		{
			_stopDelayRemaining -= TimeReferences.DeltaTime;
			if (_stopDelayRemaining <= 0f)
			{
				_stopScheduled = false;
				GamemodeManager.StopGamemode();
			}
		}
		if (!NetworkInfo.IsHost || _gameEnded)
		{
			return;
		}
		if (!_roundStarted && _elapsedTime >= (float)PrepSeconds)
		{
			AssignRoles();
			_roundStarted = true;
			_elapsedTime = 0f;
			RoundStartedEvent.TryInvoke(RoundMinutes.ToString());
		}
		if (_roundStarted)
		{
			float num = (float)RoundMinutes * 60f;
			if (!_oneMinuteLeft && num - _elapsedTime <= 60f)
			{
				_oneMinuteLeft = true;
				OneMinuteLeftEvent.TryInvoke();
			}
			if (_elapsedTime >= num)
			{
				_gameEnded = true;
				TimeUpEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled));
			}
		}
	}

	private void AssignRoles()
	{
		List<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.TryAssignTeam(list[0], LoneWolfTeam);
			list.RemoveAt(0);
		}
		if (count >= 4 && GlitchEnabled && list.Count > 1)
		{
			TeamManager.TryAssignTeam(list[0], GlitchTeam);
			list.RemoveAt(0);
		}
		foreach (PlayerID item in list)
		{
			TeamManager.TryAssignTeam(item, InnocentTeam);
		}
	}

	private void UpdateSpectators()
	{
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		bool flag = _roundStarted && SpectatorTeam.HasPlayer(PlayerIDManager.LocalID);
		if (flag && RigData.HasPlayer)
		{
			try
			{
				PhysicsRig physicsRig = RigData.Refs.RigManager.physicsRig;
				Hand leftHand = physicsRig.leftHand;
				if ((Object)(object)((leftHand != null) ? leftHand.m_CurrentAttachedGO : null) != (Object)null)
				{
					HandExtensions.TryDetach(physicsRig.leftHand);
				}
				Hand rightHand = physicsRig.rightHand;
				if ((Object)(object)((rightHand != null) ? rightHand.m_CurrentAttachedGO : null) != (Object)null)
				{
					HandExtensions.TryDetach(physicsRig.rightHand);
				}
			}
			catch
			{
			}
		}
		NetworkPlayer val = default(NetworkPlayer);
		foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
		{
			if (playerID.IsMe || !NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val))
			{
				continue;
			}
			bool flag2 = _roundStarted && SpectatorTeam.HasPlayer(playerID);
			if (val.ForceHide != flag2)
			{
				val.ForceHide = flag2;
			}
			bool flag3 = flag2 && !flag;
			RigVoiceSource voiceSource = val.VoiceSource;
			VoiceSource val2 = ((voiceSource != null) ? voiceSource.VoiceSource : null);
			if ((Object)(object)((val2 != null) ? val2.AudioSource : null) != (Object)null && val2.AudioSource.mute != flag3)
			{
				val2.AudioSource.mute = flag3;
			}
			try
			{
				RigRefs rigRefs = val.RigRefs;
				Transform val3 = ((rigRefs != null) ? rigRefs.Headset : null);
				if ((Object)(object)val3 != (Object)null)
				{
					_lastKnownPositions[playerID.SmallID] = val3.position - Vector3.up * 0.6f;
				}
			}
			catch
			{
			}
		}
	}

	private void ClearSpectatorEffects()
	{
		NetworkPlayer val = default(NetworkPlayer);
		foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
		{
			if (!playerID.IsMe && NetworkPlayerManager.TryGetPlayer(playerID.SmallID, ref val))
			{
				val.ForceHide = false;
				RigVoiceSource voiceSource = val.VoiceSource;
				VoiceSource val2 = ((voiceSource != null) ? voiceSource.VoiceSource : null);
				if ((Object)(object)((val2 != null) ? val2.AudioSource : null) != (Object)null)
				{
					val2.AudioSource.mute = false;
				}
			}
		}
	}

	private void UpdateWristIndicator()
	{
		if (_wristIndicator.TryCreate())
		{
			_wristIndicator.SetText(GetWristText());
			_wristIndicator.Update();
		}
	}

	private string GetWristText()
	{
		if (!_roundStarted)
		{
			return "GET READY\nRoles incoming...";
		}
		float num = Mathf.Max(_roundLengthSeconds - _elapsedTime, 0f);
		string text = TimeSpan.FromSeconds(num).ToString("mm\\:ss");
		Team localTeam = TeamManager.GetLocalTeam();
		string text2 = ((localTeam == TraitorTeam) ? $"<color={"#ff3333"}>TRAITOR</color>\nTP: {TraitorPoints.Points}" : ((localTeam == DetectiveTeam) ? "<color=#3399ff>DETECTIVE</color>" : ((localTeam == InnocentTeam) ? "<color=#33ff33>INNOCENT</color>" : ((localTeam == JesterTeam) ? "<color=#ff69b4>JESTER</color>" : ((localTeam == PsychopathTeam) ? "<color=#cc0000>PSYCHOPATH</color>" : ((localTeam == LoneWolfTeam) ? "<color=#ff8c00>LONE WOLF</color>" : ((localTeam == GlitchTeam) ? "<color=#00ffff>GLITCH</color>" : ((localTeam != SpectatorTeam) ? "NO ROLE" : "<color=#aaaaaa>SPECTATING</color>"))))))));
		return text2 + "\n" + text;
	}

	private void SpawnLoadout()
	{
		Team localTeam = TeamManager.GetLocalTeam();
		if (localTeam != SpectatorTeam)
		{
			Random random = new Random();
			SpawnLoadoutItem(Defaults.Sidearms[random.Next(Defaults.Sidearms.Length)]);
			SpawnLoadoutItem(Defaults.Primaries[random.Next(Defaults.Primaries.Length)]);
			if (localTeam == TraitorTeam)
			{
				SpawnLoadoutItem("c1534c5a-1fb8-477c-afbe-2a95436f6d62");
			}
		}
	}

	private void SpawnLoadoutItem(string barcode)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		if (RigData.HasPlayer)
		{
			Transform headset = RigData.Refs.Headset;
			Vector3 position = headset.position + headset.forward * 0.4f;
			Spawnable spawnable = LocalAssetSpawner.CreateSpawnable(barcode);
			NetworkAssetSpawner.Spawn(new SpawnRequestInfo
			{
				Spawnable = spawnable,
				Position = position,
				Rotation = Quaternion.identity,
				SpawnEffect = false,
				SpawnCallback = delegate(SpawnCallbackInfo info)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0019: Unknown result type (might be due to invalid IL or missing references)
					_spawnedLoadoutItems.Add(info.Entity.ID);
					TryHolster(info.Spawned);
				}
			});
		}
	}

	public void TryHolster(GameObject item)
	{
		if ((Object)(object)item == (Object)null || !RigData.HasPlayer)
		{
			return;
		}
		WeaponSlot componentInChildren = item.GetComponentInChildren<WeaponSlot>(true);
		if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.interactableHost == (Object)null)
		{
			return;
		}
		InventorySlotReceiver[] rigSlots = RigData.Refs.RigSlots;
		foreach (InventorySlotReceiver val in rigSlots)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val._slottedWeapon != (Object)null))
			{
				try
				{
					val.InsertInSlot(componentInChildren.interactableHost);
				}
				catch
				{
					continue;
				}
				if ((Object)(object)val._slottedWeapon != (Object)null)
				{
					break;
				}
			}
		}
	}

	private void DespawnLoadoutItems()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			LocalPlayer.ReleaseGrips();
		}
		catch
		{
		}
		foreach (ushort spawnedLoadoutItem in _spawnedLoadoutItems)
		{
			NetworkAssetSpawner.Despawn(new DespawnRequestInfo
			{
				EntityID = spawnedLoadoutItem,
				DespawnEffect = false
			});
		}
		_spawnedLoadoutItems.Clear();
	}

	private void OnAssignedToTeam(PlayerID player, Team team)
	{
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Expected O, but got Unknown
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Expected O, but got Unknown
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Expected O, but got Unknown
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Expected O, but got Unknown
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Expected O, but got Unknown
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0324: Unknown result type (might be due to invalid IL or missing references)
		//IL_032f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0335: Unknown result type (might be due to invalid IL or missing references)
		//IL_0340: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0361: Expected O, but got Unknown
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_037d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Expected O, but got Unknown
		//IL_040f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0414: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0425: Unknown result type (might be due to invalid IL or missing references)
		//IL_0430: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_0444: Unknown result type (might be due to invalid IL or missing references)
		//IL_0451: Expected O, but got Unknown
		//IL_046b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0470: Unknown result type (might be due to invalid IL or missing references)
		//IL_047a: Unknown result type (might be due to invalid IL or missing references)
		//IL_047f: Unknown result type (might be due to invalid IL or missing references)
		FusionOverrides.ForceUpdateOverrides();
		if (player.IsMe && team != null && !_roundStarted)
		{
			_roundStarted = true;
		}
		if (KarmaManager.Enabled)
		{
			KarmaManager.EnsurePlayer(player);
		}
		if (player.IsMe)
		{
			_buyMenu.Refresh();
		}
		if (team == DetectiveTeam && !player.IsMe)
		{
			string text = default(string);
			MetadataHelper.TryGetDisplayName(player, ref text);
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#3399ff>DETECTIVE</color>"),
				Message = NotificationText.op_Implicit(text + " is the Detective!"),
				ShowPopup = true,
				PopupLength = 5f,
				Type = (NotificationType)0
			});
		}
		if (!player.IsMe)
		{
			return;
		}
		if (team == TraitorTeam)
		{
			TraitorShopRadial.AddMenuItems(this);
		}
		else
		{
			TraitorShopRadial.RemoveMenuItems();
		}
		if (team == TraitorTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#ff3333>YOU ARE A TRAITOR!</color>"),
				Message = NotificationText.op_Implicit("Eliminate all Innocents. Open the Traitor Shop in the radial menu!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)0
			});
		}
		else if (team == InnocentTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#33ff33>YOU ARE INNOCENT!</color>"),
				Message = NotificationText.op_Implicit("Find and eliminate the Traitors!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)0
			});
		}
		else if (team == DetectiveTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#3399ff>YOU ARE THE DETECTIVE!</color>"),
				Message = NotificationText.op_Implicit("Lead the Innocents and find the Traitors!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)0
			});
		}
		else if (team == JesterTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#ff69b4>YOU ARE THE JESTER!</color>"),
				Message = NotificationText.op_Implicit("Trick an Innocent into killing you to become the Psychopath! If a Traitor kills you instead, you lose."),
				ShowPopup = true,
				PopupLength = 8f,
				Type = (NotificationType)0
			});
		}
		else if (team == PsychopathTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#cc0000>YOU ARE NOW THE PSYCHOPATH!</color>"),
				Message = NotificationText.op_Implicit("Second chance! Kill everyone to win!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)0
			});
			LocalHealth.MortalityOverride = true;
			LocalHealth.VitalityOverride = 1.5f;
			try
			{
				GamemodeHelper.TeleportToSpawnPoint();
			}
			catch
			{
			}
			MelonCoroutines.Start(RevicePsychopathRoutine());
		}
		else if (team == LoneWolfTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#ff8c00>YOU ARE THE LONE WOLF!</color>"),
				Message = NotificationText.op_Implicit("Kill everyone and be the last one standing to win!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)0
			});
		}
		else if (team == GlitchTeam)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#00ffff>YOU ARE THE GLITCH!</color>"),
				Message = NotificationText.op_Implicit("You appear as a Traitor to Traitors — but you're secretly Innocent. Help Innocents win from the inside!"),
				ShowPopup = true,
				PopupLength = 8f,
				Type = (NotificationType)0
			});
		}
		else
		{
			if (team != SpectatorTeam || !_roundStarted)
			{
				return;
			}
			string text2 = (_localDied ? "YOU ARE NOW SPECTATING" : "<color=#ff69b4>THE JESTER TRICKED YOU!</color>");
			string text3 = (_localDied ? "You can hear other dead players. Wait for the round to end." : "You killed the Jester — now you pay for it. Spectate until the round ends.");
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit(text2),
				Message = NotificationText.op_Implicit(text3),
				ShowPopup = true,
				PopupLength = 5f,
				Type = (NotificationType)1
			});
			LocalHealth.MortalityOverride = false;
			if (!_hasLocalDeathPos)
			{
				try
				{
					GamemodeHelper.TeleportToSpawnPoint();
					return;
				}
				catch
				{
					return;
				}
			}
			MelonCoroutines.Start(MoveSpectatorToBodyRoutine(_localDeathPos + Vector3.up * 0.1f));
		}
	}

	private static IEnumerator MoveSpectatorToBodyRoutine(Vector3 pos)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < 12; i++)
		{
			try
			{
				if (RigData.HasPlayer)
				{
					RigManagerExtensions.TeleportToPosition(RigData.Refs.RigManager, pos, true);
				}
			}
			catch
			{
			}
			yield return (object)new WaitForSeconds(0.1f);
		}
	}

	private void OnRoundStarted(string value)
	{
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Expected O, but got Unknown
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0280: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d9: Expected O, but got Unknown
		_roundStarted = true;
		_elapsedTime = 0f;
		_roundLengthSeconds = (int.TryParse(value, out var result) ? ((float)result * 60f) : 300f);
		SpawnLoadout();
		if (TeamManager.GetLocalTeam() != SpectatorTeam)
		{
			LocalInventory.SetAmmo(100000);
		}
		Team localTeam = TeamManager.GetLocalTeam();
		if (localTeam != TraitorTeam)
		{
			return;
		}
		TraitorPoints.Reset();
		_buyMenu.Refresh();
		List<string> list = new List<string>();
		string item = default(string);
		foreach (byte player in TraitorTeam.Players)
		{
			PlayerID val = FindPlayerBySmallID(player);
			if (val != null && !val.IsMe && MetadataHelper.TryGetDisplayName(val, ref item))
			{
				list.Add(item);
			}
		}
		string text = default(string);
		foreach (byte player2 in GlitchTeam.Players)
		{
			PlayerID val2 = FindPlayerBySmallID(player2);
			if (val2 != null && MetadataHelper.TryGetDisplayName(val2, ref text))
			{
				list.Add(text + " <color=#00ffff>[GLITCH]</color>");
			}
		}
		string text2 = ((list.Count > 0) ? ("Your crew: " + string.Join(", ", list)) : "You are the only Traitor.");
		Notifier.Send(new Notification
		{
			Title = NotificationText.op_Implicit("<color=#ff3333>TRAITORS</color>"),
			Message = NotificationText.op_Implicit(text2),
			ShowPopup = true,
			PopupLength = 7f,
			Type = (NotificationType)0
		});
		if (JesterTeam.PlayerCount <= 0)
		{
			return;
		}
		List<string> list2 = new List<string>();
		string item2 = default(string);
		foreach (byte player3 in JesterTeam.Players)
		{
			PlayerID val3 = FindPlayerBySmallID(player3);
			if (val3 != null && MetadataHelper.TryGetDisplayName(val3, ref item2))
			{
				list2.Add(item2);
			}
		}
		if (list2.Count > 0)
		{
			Notifier.Send(new Notification
			{
				Title = NotificationText.op_Implicit("<color=#ff69b4>JESTER ALERT</color>"),
				Message = NotificationText.op_Implicit("Jester: " + string.Join(", ", list2) + " — if an Innocent kills them, they become Psychopath!"),
				ShowPopup = true,
				PopupLength = 6f,
				Type = (NotificationType)1
			});
		}
	}

	private void OnPlayerAction(PlayerID player, PlayerActionType type, PlayerID otherPlayer = null)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Invalid comparison between Unknown and I4
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Invalid comparison between Unknown and I4
		if (!((Gamemode)this).IsStarted || _gameEnded)
		{
			return;
		}
		if ((int)type == 5 && otherPlayer != null)
		{
			_recentKillers[player.SmallID] = otherPlayer.SmallID;
			_recentKillTime[player.SmallID] = Time.time;
			RigManager rig = null;
			NetworkPlayer val = default(NetworkPlayer);
			if (otherPlayer.IsMe)
			{
				rig = RigData.Refs.RigManager;
			}
			else if (NetworkPlayerManager.TryGetPlayer(otherPlayer.SmallID, ref val))
			{
				RigRefs rigRefs = val.RigRefs;
				rig = ((rigRefs != null) ? rigRefs.RigManager : null);
			}
			string value = TryGetHeldWeaponName(rig);
			if (!string.IsNullOrEmpty(value))
			{
				_recentWeapons[player.SmallID] = value;
			}
		}
		if ((int)type != 2)
		{
			if ((int)type == 5)
			{
				OnPlayerKilled(player, otherPlayer);
			}
		}
		else
		{
			OnPlayerDeath(player);
		}
	}

	private void OnPlayerDeath(PlayerID player)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		if (player.IsMe)
		{
			_localDied = true;
			try
			{
				_localDeathPos = GetDeathPosition(player);
				_hasLocalDeathPos = true;
			}
			catch
			{
			}
			try
			{
				LocalPlayer.ReleaseGrips();
			}
			catch
			{
			}
		}
		if (_roundStarted)
		{
			Vector3 deathPosition = GetDeathPosition(player);
			Team playerTeam = TeamManager.GetPlayerTeam(player);
			string roleName;
			string roleColor;
			if (playerTeam == TraitorTeam)
			{
				roleName = "Traitor";
				roleColor = "#ff3333";
			}
			else if (playerTeam == DetectiveTeam)
			{
				roleName = "Detective";
				roleColor = "#3399ff";
			}
			else if (playerTeam == JesterTeam)
			{
				roleName = "Jester";
				roleColor = "#ff69b4";
			}
			else if (playerTeam == PsychopathTeam)
			{
				roleName = "Psychopath";
				roleColor = "#cc0000";
			}
			else if (playerTeam == LoneWolfTeam)
			{
				roleName = "Lone Wolf";
				roleColor = "#ff8c00";
			}
			else if (playerTeam == GlitchTeam)
			{
				roleName = "Innocent";
				roleColor = "#33ff33";
			}
			else if (playerTeam == SpectatorTeam)
			{
				roleName = "Spectator";
				roleColor = "#aaaaaa";
			}
			else
			{
				roleName = "Innocent";
				roleColor = "#33ff33";
			}
			string weaponName = null;
			if (_recentWeapons.TryGetValue(player.SmallID, out var value))
			{
				weaponName = value;
			}
			string avatarBarcode = null;
			NetworkPlayer val = default(NetworkPlayer);
			if (player.IsMe)
			{
				try
				{
					avatarBarcode = RigData.GetAvatarBarcode();
				}
				catch
				{
				}
			}
			else if (NetworkPlayerManager.TryGetPlayer(player.SmallID, ref val))
			{
				try
				{
					RigRefs rigRefs = val.RigRefs;
					object obj4;
					if (rigRefs == null)
					{
						obj4 = null;
					}
					else
					{
						RigManager rigManager = rigRefs.RigManager;
						if (rigManager == null)
						{
							obj4 = null;
						}
						else
						{
							AvatarCrateReference avatarCrate = rigManager.AvatarCrate;
							obj4 = ((avatarCrate != null) ? ((ScannableReference)avatarCrate).Barcode.ID : null);
						}
					}
					avatarBarcode = (string)obj4;
				}
				catch
				{
				}
			}
			string text = default(string);
			MetadataHelper.TryGetDisplayName(player, ref text);
			CorpseManager.RegisterDeath(text ?? "Unknown", roleName, roleColor, deathPosition, weaponName, avatarBarcode);
		}
		if (KarmaManager.Enabled)
		{
			KarmaManager.AwardRoundBonus(player);
		}
		if (!NetworkInfo.IsHost || !_roundStarted)
		{
			return;
		}
		if (JesterTeam.HasPlayer(player))
		{
			bool flag = false;
			PlayerID val2 = null;
			if (_recentKillTime.TryGetValue(player.SmallID, out var value2) && Time.time - value2 <= 2.5f && _recentKillers.TryGetValue(player.SmallID, out var value3))
			{
				val2 = FindPlayerBySmallID(value3);
				Team val3 = ((val2 != null) ? TeamManager.GetPlayerTeam(val2) : null);
				flag = val3 == InnocentTeam || val3 == DetectiveTeam || val3 == GlitchTeam;
			}
			_recentKillers.Remove(player.SmallID);
			_recentKillTime.Remove(player.SmallID);
			if (flag)
			{
				TeamManager.TryAssignTeam(player, PsychopathTeam);
				if (val2 != null && !SpectatorTeam.HasPlayer(val2))
				{
					TeamManager.TryAssignTeam(val2, SpectatorTeam);
				}
				CheckWinConditions();
				return;
			}
		}
		if (!SpectatorTeam.HasPlayer(player))
		{
			TeamManager.TryAssignTeam(player, SpectatorTeam);
		}
		CheckWinConditions(player);
	}

	private void OnPlayerKilled(PlayerID victim, PlayerID killer)
	{
		if (killer == null || !killer.IsMe || victim.IsMe || !_roundStarted)
		{
			return;
		}
		Team localTeam = TeamManager.GetLocalTeam();
		Team playerTeam = TeamManager.GetPlayerTeam(victim);
		if (playerTeam == SpectatorTeam)
		{
			return;
		}
		bool flag = localTeam == TraitorTeam;
		bool flag2 = localTeam == GlitchTeam;
		bool flag3 = playerTeam == TraitorTeam;
		bool flag4 = playerTeam == GlitchTeam;
		bool flag5 = playerTeam == InnocentTeam || playerTeam == DetectiveTeam;
		if (flag && flag4)
		{
			return;
		}
		bool flag6 = (flag && !flag3) || (!flag && !flag2 && flag3) || (flag2 && flag3);
		if (flag6)
		{
			PointItemManager.RewardBits(50, true);
		}
		if (KarmaManager.Enabled)
		{
			if (flag6)
			{
				KarmaManager.AdjustKarma(PlayerIDManager.LocalID, 200);
			}
			else if (flag && flag3)
			{
				KarmaManager.AdjustKarma(PlayerIDManager.LocalID, -400);
			}
			else if (!flag && flag5)
			{
				KarmaManager.AdjustKarma(PlayerIDManager.LocalID, -300);
			}
		}
		if (flag && !flag3 && !flag4)
		{
			TraitorPoints.AddKillReward();
		}
		if (flag)
		{
			CustomWeapons.OnLocalKill();
		}
	}

	private static IEnumerator RevicePsychopathRoutine()
	{
		for (int i = 0; i < 10; i++)
		{
			try
			{
				if (RigData.HasPlayer)
				{
					LocalHealth.SetFullHealth();
					LocalRagdoll.ToggleRagdoll(false);
				}
			}
			catch
			{
			}
			yield return (object)new WaitForSeconds(0.15f);
		}
	}

	private Vector3 GetDeathPosition(PlayerID player)
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		if (player.IsMe)
		{
			try
			{
				if (RigData.HasPlayer && (Object)(object)RigData.Refs.Headset != (Object)null)
				{
					return RigData.Refs.Headset.position - Vector3.up * 0.6f;
				}
			}
			catch
			{
			}
			return Vector3.zero;
		}
		if (_lastKnownPositions.TryGetValue(player.SmallID, out var value))
		{
			return value;
		}
		try
		{
			NetworkPlayer val = default(NetworkPlayer);
			if (NetworkPlayerManager.TryGetPlayer(player.SmallID, ref val))
			{
				RigRefs rigRefs = val.RigRefs;
				Transform val2 = ((rigRefs != null) ? rigRefs.Headset : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2.position - Vector3.up * 0.6f;
				}
			}
		}
		catch
		{
		}
		return Vector3.zero;
	}

	private void CheckWinConditions(PlayerID dyingPlayer = null)
	{
		if (!_gameEnded)
		{
			int num = CountAlive(TraitorTeam, dyingPlayer);
			int num2 = CountAlive(InnocentTeam, dyingPlayer) + CountAlive(DetectiveTeam, dyingPlayer) + CountAlive(GlitchTeam, dyingPlayer);
			int num3 = CountAlive(JesterTeam, dyingPlayer);
			int num4 = CountAlive(PsychopathTeam, dyingPlayer);
			int num5 = CountAlive(LoneWolfTeam, dyingPlayer);
			if (num4 > 0 && num == 0 && num2 == 0 && num5 == 0 && num3 == 0)
			{
				_gameEnded = true;
				PsychopathVictoryEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Jester, WinMusicEnabled));
			}
			else if (num5 > 0 && num == 0 && num2 == 0 && num4 == 0 && num3 == 0)
			{
				_gameEnded = true;
				LoneWolfVictoryEvent.TryInvoke();
				ScheduleStop(0f);
			}
			else if (num > 0 && num2 == 0 && num4 == 0 && num5 == 0 && num3 == 0)
			{
				_gameEnded = true;
				TraitorVictoryEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Traitors, WinMusicEnabled));
			}
			else if (num == 0 && num5 == 0 && num4 == 0 && num2 > 0)
			{
				_gameEnded = true;
				InnocentVictoryEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled));
			}
			else if (num == 0 && num5 == 0 && num4 == 0 && num2 == 0 && num3 > 0)
			{
				_gameEnded = true;
				InnocentVictoryEvent.TryInvoke();
				ScheduleStop(WinMusic.GetMaxDuration(WinSide.Innocents, WinMusicEnabled));
			}
		}
	}

	private void ScheduleStop(float musicLength)
	{
		if (NetworkInfo.IsHost)
		{
			if (musicLength > 0.1f)
			{
				_stopScheduled = true;
				_stopDelayRemaining = musicLength + 1.5f;
			}
			else
			{
				GamemodeManager.StopGamemode();
			}
		}
	}

	private int CountAlive(Team team, PlayerID dyingPlayer)
	{
		int num = team.PlayerCount;
		if (dyingPlayer != null && team.HasPlayer(dyingPlayer))
		{
			num--;
		}
		return Mathf.Max(0, num);
	}

	private static PlayerID FindPlayerBySmallID(ushort smallId)
	{
		foreach (PlayerID playerID in PlayerIDManager.PlayerIDs)
		{
			if (playerID.SmallID == smallId)
			{
				return playerID;
			}
		}
		return null;
	}

	private bool SongsEnabledByHost()
	{
		try
		{
			string text = default(string);
			if (((Gamemode)this).Metadata.TryGetMetadata("tift_music", ref text))
			{
				return text != "0";
			}
		}
		catch
		{
		}
		return true;
	}

	private static string TryGetHeldWeaponName(RigManager rig)
	{
		if ((Object)(object)rig == (Object)null)
		{
			return null;
		}
		Hand[] array = (Hand[])(object)new Hand[2]
		{
			rig.physicsRig.leftHand,
			rig.physicsRig.rightHand
		};
		Hand[] array2 = array;
		foreach (Hand val in array2)
		{
			try
			{
				GameObject val2 = ((val != null) ? val.m_CurrentAttachedGO : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					GameObject val3 = val2;
					Mar