Decompiled source of Hunted v0.1.1

Hunted.dll

Decompiled 16 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Linq;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Prussian")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1")]
[assembly: AssemblyProduct("Hunted")]
[assembly: AssemblyTitle("Hunted")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Hunted
{
	internal static class CartSpawner
	{
		private const string CartItemName = "Item Cart Medium";

		private static readonly HashSet<ExtractionPoint> Spawned = new HashSet<ExtractionPoint>();

		private static readonly HashSet<GameObject> Own = new HashSet<GameObject>();

		private static bool _running;

		private static float _openFor;

		internal static void Reset()
		{
			Spawned.Clear();
			Own.Clear();
			_running = false;
			_openFor = 0f;
		}

		internal static void Tick(float dt)
		{
			if (_running || !SemiFunc.IsMasterClientOrSingleplayer() || !KillerRole.ModeActive || !ExtractionState.Active)
			{
				return;
			}
			List<ExtractionPoint> list = (from p in ExtractionPoints.Get()
				where (Object)(object)p != (Object)null && !p.inStartRoom && !Spawned.Contains(p) && (int)p.currentState != 1
				select p).ToList();
			if (list.Count == 0)
			{
				_openFor = 0f;
				return;
			}
			_openFor += dt;
			if (!(_openFor < 1.5f))
			{
				_running = true;
				((MonoBehaviour)Hunted.Instance).StartCoroutine(SpawnCarts(list));
			}
		}

		private static IEnumerator SpawnCarts(List<ExtractionPoint> points)
		{
			Item item = FindCartItem();
			if ((Object)(object)item == (Object)null)
			{
				Hunted.Logger.LogError((object)"No cart item found.");
				foreach (ExtractionPoint point in points)
				{
					Spawned.Add(point);
				}
				_running = false;
				yield break;
			}
			yield return LevelGenerator.Instance.PrefabsPrepare((IEnumerable<PrefabRef>)(object)new PrefabRef[1] { item.prefab }, (IEnumerable<string>)null, (IEnumerable<string>)null);
			foreach (ExtractionPoint point2 in points)
			{
				Spawned.Add(point2);
				if (!((Object)(object)point2 == (Object)null))
				{
					Vector3 val = point2.platform.position + Vector3.up * 0.8f;
					Quaternion rotation = ((Component)point2).transform.rotation;
					GameObject val2 = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)item.prefab).ResourcePath, val, rotation, (byte)0, (object[])null) : Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)item.prefab).Prefab, val, rotation));
					if ((Object)(object)val2 == (Object)null)
					{
						Hunted.Logger.LogError((object)$"Could not spawn a cart at {val}.");
					}
					else
					{
						Own.Add(val2);
					}
					yield return null;
				}
			}
			Hunted.Logger.LogInfo((object)$"Spawned {points.Count} carts at extraction points.");
			_running = false;
		}

		private static Item? FindCartItem()
		{
			Dictionary<string, Item> itemDictionary = StatsManager.instance.itemDictionary;
			if (itemDictionary.TryGetValue("Item Cart Medium", out var value) && (Object)(object)value != (Object)null && value.prefab != null)
			{
				return value;
			}
			return ((IEnumerable<Item>)itemDictionary.Values).FirstOrDefault((Func<Item, bool>)((Item i) => (Object)(object)i != (Object)null && i.prefab != null && (Object)(object)((PrefabRef<GameObject>)(object)i.prefab).Prefab != (Object)null && (Object)(object)((PrefabRef<GameObject>)(object)i.prefab).Prefab.GetComponent<PhysGrabCart>() != (Object)null));
		}
	}
	[HarmonyPatch]
	internal static class CartSpawnerPatches
	{
		[HarmonyPatch(typeof(PunManager), "TruckPopulateItemVolumes", new Type[] { typeof(List<ItemSpawn>) })]
		[HarmonyPrefix]
		private static void TruckPopulateItemVolumes_Prefix()
		{
			if (KillerRole.ModeActive && !((Object)(object)ItemManager.instance == (Object)null))
			{
				int num = ItemManager.instance.purchasedItems.RemoveAll((Item i) => (Object)(object)i != (Object)null && (int)i.itemType == 2);
				if (num > 0)
				{
					Hunted.Logger.LogInfo((object)$"Left {num} cart(s) out of the truck rooms.");
				}
			}
		}

		[HarmonyPatch(typeof(PhysGrabCart), "StateSwitchRPC")]
		[HarmonyPrefix]
		private static bool StateSwitchRPC_Prefix(PhysGrabCart __instance, State _state)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance.cartMesh != (Object)null)
			{
				return true;
			}
			__instance.currentState = _state;
			return false;
		}
	}
	internal static class ConfigDefaults
	{
		private static JObject? _root;

		internal static void Load()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Hunted.Defaults.json");
			if (stream == null)
			{
				throw Fail("Defaults.json is not in the DLL.");
			}
			using StreamReader streamReader = new StreamReader(stream);
			try
			{
				_root = JObject.Parse(streamReader.ReadToEnd());
			}
			catch (Exception ex)
			{
				throw Fail("Defaults.json cannot be read: " + ex.Message);
			}
		}

		internal static T Get<T>(string section, string key)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			JObject? root = _root;
			object obj;
			if (root == null)
			{
				obj = null;
			}
			else
			{
				JToken obj2 = root[section];
				obj = ((obj2 != null) ? obj2[(object)key] : null);
			}
			JToken val = (JToken)obj;
			if (val == null || (int)val.Type == 10)
			{
				throw Fail("Defaults.json has no default for the setting [" + section + "] " + key + ".");
			}
			try
			{
				return val.ToObject<T>();
			}
			catch (Exception ex)
			{
				throw Fail("The default for [" + section + "] " + key + " in Defaults.json is not a valid " + typeof(T).Name + ": " + ex.Message);
			}
		}

		private static InvalidOperationException Fail(string message)
		{
			Hunted.Logger.LogError((object)message);
			return new InvalidOperationException(message);
		}
	}
	internal static class ConfigSync
	{
		private const string RoomKey = "Hunted.Config";

		private static ConfigFile _file = null;

		private static readonly Dictionary<string, ConfigEntryBase> Entries = new Dictionary<string, ConfigEntryBase>();

		private static readonly Dictionary<string, string> Own = new Dictionary<string, string>();

		private static bool _overridden;

		private static float _timer;

		private static string? _lastApplied;

		internal static void Init(ConfigFile file)
		{
			_file = file;
			foreach (ConfigDefinition item in file.Keys.ToList())
			{
				ConfigEntryBase val = file[item];
				string key = item.Section + "." + item.Key;
				Entries[key] = val;
				Own[key] = val.GetSerializedValue();
			}
			file.Save();
			file.SaveOnConfigSet = false;
		}

		internal static void Tick()
		{
			_timer -= Time.unscaledDeltaTime;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 0.5f;
			if (!PhotonNetwork.InRoom || SemiFunc.IsMasterClientOrSingleplayer())
			{
				Restore();
				if (PhotonNetwork.InRoom)
				{
					Publish();
				}
				return;
			}
			string text = RoomSync.Get<string>("Hunted.Config");
			if (text == null)
			{
				Restore();
			}
			else if (!(text == _lastApplied) || !_overridden)
			{
				Apply(text);
			}
		}

		private static string Escape(string value)
		{
			return Uri.EscapeDataString(value);
		}

		private static void Publish()
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (KeyValuePair<string, ConfigEntryBase> entry in Entries)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append('|');
				}
				stringBuilder.Append(Escape(entry.Key)).Append('=').Append(Escape(entry.Value.GetSerializedValue()));
			}
			RoomSync.Set("Hunted.Config", stringBuilder.ToString());
		}

		private static void Apply(string text)
		{
			int num = 0;
			string[] array = text.Split('|');
			foreach (string text2 in array)
			{
				int num2 = text2.IndexOf('=');
				if (num2 <= 0)
				{
					continue;
				}
				string text3 = Uri.UnescapeDataString(text2.Substring(0, num2));
				string text4 = Uri.UnescapeDataString(text2.Substring(num2 + 1));
				if (Entries.TryGetValue(text3, out ConfigEntryBase value) && value.GetSerializedValue() != text4)
				{
					try
					{
						value.SetSerializedValue(text4);
						num++;
					}
					catch (Exception ex)
					{
						Hunted.Logger.LogWarning((object)("Could not take the host's value for " + text3 + ": " + ex.Message));
					}
				}
			}
			_overridden = true;
			_lastApplied = text;
			Hunted.Logger.LogInfo((object)$"Using the host's settings ({num} differ from this game's own).");
		}

		private static void Restore()
		{
			if (!_overridden)
			{
				return;
			}
			foreach (KeyValuePair<string, string> item in Own)
			{
				if (Entries.TryGetValue(item.Key, out ConfigEntryBase value) && value.GetSerializedValue() != item.Value)
				{
					value.SetSerializedValue(item.Value);
				}
			}
			_overridden = false;
			_lastApplied = null;
			Hunted.Logger.LogInfo((object)"Back to this game's own settings.");
		}
	}
	[HarmonyPatch(typeof(PlayerDeathHead), "Update")]
	internal static class DeathHeadMap
	{
		[HarmonyPostfix]
		private static void Update_Postfix(PlayerDeathHead __instance)
		{
			if (!KillerRole.ModeActive || !__instance.triggered || (Object)(object)__instance.mapCustom == (Object)null)
			{
				return;
			}
			MapCustomEntity mapCustomEntity = __instance.mapCustom.mapCustomEntity;
			if ((Object)(object)mapCustomEntity == (Object)null)
			{
				return;
			}
			RoomVolumeCheck component = ((Component)__instance).GetComponent<RoomVolumeCheck>();
			if (!((Object)(object)component == (Object)null) && component.CurrentRooms.Count != 0)
			{
				RoomVolume val = component.CurrentRooms[0];
				if ((Object)(object)val != (Object)null && (val.Explored || (Object)(object)val.MapModule == (Object)null))
				{
					mapCustomEntity.mapCustomHideTimer = 0f;
				}
			}
		}
	}
	internal static class DebugToggles
	{
		internal static bool DummySurvivor;

		private const float Scale = 0.55f;

		private static GameObject? _container;

		internal static void Build(Transform page)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0068: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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)
			MenuPageLobby instance = MenuPageLobby.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.playerListTransform == (Object)null))
			{
				_container = new GameObject("Hunted Debug Options", new Type[1] { typeof(RectTransform) });
				RectTransform val = (RectTransform)_container.transform;
				((Transform)val).SetParent(page, false);
				((Transform)val).localScale = new Vector3(0.55f, 0.55f, 1f);
				RectTransform playerListTransform = instance.playerListTransform;
				Vector3 val2 = ((Transform)playerListTransform).TransformPoint(new Vector3(0f, -77f, 0f));
				Vector3 val3 = page.InverseTransformPoint(val2);
				((Transform)val).localPosition = new Vector3(val3.x, val3.y, 0f);
				MenuAPI.CreateREPOToggle("Dummy survivor", (Action<bool>)delegate(bool on)
				{
					DummySurvivor = on;
				}, (Transform)(object)val, new Vector2(0f, 0f), "ON", "OFF", DummySurvivor);
			}
		}

		internal static void Tick()
		{
			if (!((Object)(object)_container == (Object)null))
			{
				bool flag = PhotonNetwork.PlayerList.Length <= 1;
				if (_container.activeSelf != flag)
				{
					_container.SetActive(flag);
				}
			}
		}
	}
	internal class DummySurvivor : MonoBehaviour
	{
		private Rigidbody _body;

		private CapsuleCollider _collider;

		private Transform _visual;

		private Renderer _renderer;

		private bool _carried;

		private float _carryDistance = 2f;

		private float _coverTimer;

		internal static DummySurvivor? Current { get; private set; }

		internal bool Crouching => true;

		internal bool Tumbling { get; private set; }

		internal Vector3 TargetPosition => ((Component)this).transform.position + Vector3.up * (Tumbling ? 0.2f : 0.5f);

		internal static void Reset()
		{
			if ((Object)(object)Current != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Current).gameObject);
			}
			Current = null;
		}

		internal static void Tick()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!DebugToggles.DummySurvivor || KillerRole.PlayerCountForMode != 1 || !KillerRole.ModeActive || !KillerRole.LocalIsKiller || !((Object)(object)LevelGenerator.Instance != (Object)null) || !LevelGenerator.Instance.Generated)
			{
				if ((Object)(object)Current != (Object)null)
				{
					Reset();
				}
			}
			else if ((Object)(object)Current == (Object)null)
			{
				Spawn();
			}
			else if (((Component)Current).transform.position.y < -30f)
			{
				Hunted.Logger.LogDebug((object)"The dummy survivor fell out of the map and is brought back.");
				Reset();
				Spawn();
			}
		}

		private static void Spawn()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00e8: Expected O, but got Unknown
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			PlayerController instance = PlayerController.instance;
			Camera val = (((Object)(object)CameraUtils.Instance != (Object)null) ? CameraUtils.Instance.MainCamera : null);
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)val == (Object)null))
			{
				Vector3 val2 = Vector3.ProjectOnPlane(((Component)val).transform.forward, Vector3.up);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				Vector3 val3 = ((Component)instance).transform.position + normalized * 3f + Vector3.up * 1.5f;
				RaycastHit val5 = default(RaycastHit);
				Vector3 val4 = (Physics.Raycast(val3, Vector3.down, ref val5, 6f, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1) ? (((RaycastHit)(ref val5)).point + Vector3.up * 0.05f) : (((Component)instance).transform.position + normalized * 2f));
				GameObject val6 = new GameObject("Hunted Dummy Survivor");
				val6.transform.position = val4;
				DummySurvivor dummySurvivor = val6.AddComponent<DummySurvivor>();
				dummySurvivor.Build();
				Current = dummySurvivor;
				Hunted.Logger.LogInfo((object)$"Dummy survivor placed at {val4}: stow the weapon, look at it and hold the grab button to carry it.");
			}
		}

		private void Build()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			_body = ((Component)this).gameObject.AddComponent<Rigidbody>();
			_body.mass = 20f;
			_body.constraints = (RigidbodyConstraints)112;
			_body.interpolation = (RigidbodyInterpolation)1;
			_collider = ((Component)this).gameObject.AddComponent<CapsuleCollider>();
			_collider.radius = 0.25f;
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)1);
			((Object)val).name = "Look";
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			val.transform.SetParent(((Component)this).transform, false);
			_visual = val.transform;
			_renderer = val.GetComponent<Renderer>();
			_renderer.material.color = new Color(0.2f, 0.9f, 0.3f);
			_renderer.forceRenderingOff = true;
			_renderer.shadowCastingMode = (ShadowCastingMode)0;
			Apply(tumbled: false);
		}

		private void Apply(bool tumbled)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			Tumbling = tumbled;
			float num = (tumbled ? 0.4f : 0.9f);
			_collider.height = num;
			_collider.center = new Vector3(0f, num / 2f, 0f);
			_collider.radius = (tumbled ? 0.2f : 0.25f);
			_visual.localScale = new Vector3(_collider.radius * 2f, num / 2f, _collider.radius * 2f);
			_visual.localPosition = new Vector3(0f, num / 2f, 0f);
			_renderer.material.color = (tumbled ? new Color(1f, 0.55f, 0.1f) : new Color(0.2f, 0.9f, 0.3f));
			Hunted.Logger.LogDebug((object)("Dummy survivor is now " + (tumbled ? "tumbled (something is above it)" : "crouching") + "."));
		}

		private void Update()
		{
			//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_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_0075: 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)
			Camera val = (((Object)(object)CameraUtils.Instance != (Object)null) ? CameraUtils.Instance.MainCamera : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			CarryLogic(val);
			_coverTimer -= Time.deltaTime;
			if (_coverTimer <= 0f)
			{
				_coverTimer = 0.2f;
				RaycastHit val2 = default(RaycastHit);
				bool flag = Physics.Raycast(((Component)this).transform.position + Vector3.up * 0.1f, Vector3.up, ref val2, 1.1f, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<DummySurvivor>() != (Object)(object)this;
				if (flag != Tumbling)
				{
					Apply(flag);
				}
			}
		}

		private void CarryLogic(Camera camera)
		{
			//IL_00ea: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			bool flag = KillerRole.LocalIsKiller && !KillerWeapon.WeaponInHand();
			if (_carried && (!flag || !SemiFunc.InputHold((InputKey)10)))
			{
				_carried = false;
				_body.isKinematic = false;
				Hunted.Logger.LogDebug((object)"Dummy survivor put down.");
				return;
			}
			RaycastHit val = default(RaycastHit);
			if (!_carried && flag && SemiFunc.InputDown((InputKey)10) && Physics.Raycast(((Component)camera).transform.position, ((Component)camera).transform.forward, ref val, 4f, -1, (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<DummySurvivor>() == (Object)(object)this)
			{
				_carried = true;
				_carryDistance = Mathf.Clamp(((RaycastHit)(ref val)).distance, 1.3f, 3.5f);
				_body.isKinematic = true;
				Hunted.Logger.LogDebug((object)"Dummy survivor picked up.");
			}
			if (_carried)
			{
				Vector3 position = ((Component)camera).transform.position;
				Vector3 forward = ((Component)camera).transform.forward;
				float num = _carryDistance;
				RaycastHit val2 = default(RaycastHit);
				if (Physics.SphereCast(position, 0.25f, forward, ref val2, num, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1) && (Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<DummySurvivor>() != (Object)(object)this && (Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerController>() == (Object)null)
				{
					num = Mathf.Max(0.6f, ((RaycastHit)(ref val2)).distance - 0.1f);
				}
				Vector3 val3 = position + forward * num - Vector3.up * (Tumbling ? 0.3f : 0.6f);
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val3, 15f * Time.deltaTime);
			}
		}
	}
	[HarmonyPatch]
	internal static class NoMonstersPatch
	{
		[HarmonyPatch(typeof(LevelGenerator), "Generate")]
		[HarmonyPrefix]
		private static void Generate_Prefix(LevelGenerator __instance)
		{
			if (Tuning.Monsters.MonstersPerTier <= 0 && SemiFunc.IsMasterClientOrSingleplayer())
			{
				__instance.DebugNoEnemy = true;
				Hunted.Logger.LogInfo((object)"No monsters: Monsters.MonstersPerTier in Tuning.json is 0.");
			}
		}
	}
	internal static class EnemyIgnore
	{
		private static readonly FieldInfo PlayerListField = AccessTools.Field(typeof(GameDirector), "PlayerList");

		private static readonly Dictionary<MethodBase, MethodInfo> Replacements = new Dictionary<MethodBase, MethodInfo>
		{
			{
				AccessTools.Method(typeof(SemiFunc), "PlayerGetList", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(EnemyIgnore), "PlayerGetList", (Type[])null, (Type[])null)
			},
			{
				AccessTools.Method(typeof(SemiFunc), "PlayerGetAllPlayerAvatarWithinRange", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(EnemyIgnore), "AllWithinRange", (Type[])null, (Type[])null)
			},
			{
				AccessTools.Method(typeof(SemiFunc), "PlayerGetAllPlayerAvatarWithinRangeAndVision", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(EnemyIgnore), "AllWithinRangeAndVision", (Type[])null, (Type[])null)
			},
			{
				AccessTools.Method(typeof(SemiFunc), "PlayerGetNearestPlayerAvatarWithinRange", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(EnemyIgnore), "NearestWithinRange", (Type[])null, (Type[])null)
			},
			{
				AccessTools.Method(typeof(SemiFunc), "PlayerNearestDistance", (Type[])null, (Type[])null),
				AccessTools.Method(typeof(EnemyIgnore), "NearestDistance", (Type[])null, (Type[])null)
			}
		};

		private static readonly List<PlayerAvatar> Filtered = new List<PlayerAvatar>();

		internal static void Apply(Harmony harmony)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(EnemyIgnore), "Transpiler", (Type[])null, (Type[])null));
			int num = 0;
			int num2 = 0;
			foreach (MethodBase item in TargetMethods())
			{
				try
				{
					harmony.Patch(item, (HarmonyMethod)null, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
				catch (Exception ex)
				{
					num2++;
					Hunted.Logger.LogWarning((object)("Could not patch " + item.DeclaringType?.Name + "." + item.Name + ": " + ex.Message));
				}
			}
			Hunted.Logger.LogInfo((object)$"Enemy scripts: {num} methods now ignore the killer ({num2} failed).");
		}

		private static IEnumerable<MethodBase> TargetMethods()
		{
			Type[] types = typeof(Enemy).Assembly.GetTypes();
			foreach (Type type in types)
			{
				Type type2 = type;
				while (type2.DeclaringType != null)
				{
					type2 = type2.DeclaringType;
				}
				if (!type2.Name.StartsWith("Enemy", StringComparison.Ordinal))
				{
					continue;
				}
				foreach (MethodBase item in type.GetMethods(AccessTools.allDeclared).Cast<MethodBase>().Concat(type.GetConstructors(AccessTools.allDeclared)))
				{
					if (!item.IsAbstract && UsesPlayers(item))
					{
						yield return item;
					}
				}
			}
		}

		private static bool UsesPlayers(MethodBase method)
		{
			try
			{
				foreach (var (opCode2, obj2) in PatchProcessor.ReadMethodBody(method))
				{
					if (opCode2 == OpCodes.Ldfld && obj2 as FieldInfo == PlayerListField)
					{
						return true;
					}
					if ((opCode2 == OpCodes.Call || opCode2 == OpCodes.Callvirt) && obj2 is MethodBase key && Replacements.ContainsKey(key))
					{
						return true;
					}
				}
			}
			catch (Exception)
			{
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo filter = AccessTools.Method(typeof(EnemyIgnore), "FilterList", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldfld && instruction.operand as FieldInfo == PlayerListField)
				{
					yield return instruction;
					yield return new CodeInstruction(OpCodes.Call, (object)filter);
					continue;
				}
				if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodBase key && Replacements.TryGetValue(key, out MethodInfo value))
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = value;
				}
				yield return instruction;
			}
		}

		public static List<PlayerAvatar> FilterList(List<PlayerAvatar> source)
		{
			string killerSteamId = KillerRole.KillerSteamId;
			if (killerSteamId == null)
			{
				return source;
			}
			bool flag = true;
			int num = 0;
			foreach (PlayerAvatar item in source)
			{
				if (!((Object)(object)item != (Object)null) || !(item.steamID == killerSteamId))
				{
					if (num >= Filtered.Count || (Object)(object)Filtered[num] != (Object)(object)item)
					{
						flag = false;
						break;
					}
					num++;
				}
			}
			if (flag && num == Filtered.Count)
			{
				return Filtered;
			}
			Filtered.Clear();
			foreach (PlayerAvatar item2 in source)
			{
				if ((Object)(object)item2 == (Object)null || item2.steamID != killerSteamId)
				{
					Filtered.Add(item2);
				}
			}
			return Filtered;
		}

		public static List<PlayerAvatar> PlayerGetList()
		{
			List<PlayerAvatar> list = SemiFunc.PlayerGetList();
			List<PlayerAvatar> list2 = FilterList(list);
			if (list2.Count <= 0)
			{
				return list;
			}
			return list2;
		}

		public static List<PlayerAvatar> AllWithinRange(float range, Vector3 position, bool doRaycastCheck = false, LayerMask layerMask = default(LayerMask))
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerAvatar> list = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(range, position, doRaycastCheck, layerMask);
			list.RemoveAll(KillerRole.IsKiller);
			return list;
		}

		public static List<PlayerAvatar> AllWithinRangeAndVision(float range, Vector3 position, PhysGrabObject? thisPhysGrabObject = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			List<PlayerAvatar> list = SemiFunc.PlayerGetAllPlayerAvatarWithinRangeAndVision(range, position, thisPhysGrabObject);
			list.RemoveAll(KillerRole.IsKiller);
			return list;
		}

		public static PlayerAvatar? NearestWithinRange(float range, Vector3 position, bool doRaycastCheck = false, LayerMask layerMask = default(LayerMask))
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			float num = range;
			PlayerAvatar result = null;
			foreach (PlayerAvatar item in AllWithinRange(range, position, doRaycastCheck, layerMask))
			{
				float num2 = Vector3.Distance(position, item.PlayerVisionTarget.VisionTransform.position);
				if (num2 < num)
				{
					num = num2;
					result = item;
				}
			}
			return result;
		}

		public static float NearestDistance(Vector3 position)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			float num = 999f;
			float result = 9f;
			foreach (PlayerAvatar item in FilterList(GameDirector.instance.PlayerList))
			{
				if (!((Object)(object)item == (Object)null) && !item.isDisabled)
				{
					float num2 = Vector3.Distance(position, item.PlayerVisionTarget.VisionTransform.position);
					if (num2 < num)
					{
						num = num2;
						result = num2;
					}
				}
			}
			return result;
		}
	}
	[HarmonyPatch]
	internal static class EnemyPlayerTables
	{
		[HarmonyPatch(typeof(Enemy), "PlayerAdded")]
		[HarmonyPostfix]
		private static void PlayerAdded_Postfix(Enemy __instance)
		{
			if (!KillerRole.ModeActive || (Object)(object)GameDirector.instance == (Object)null)
			{
				return;
			}
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!((Object)(object)player == (Object)null) && !((Object)(object)player.photonView == (Object)null))
				{
					int viewID = player.photonView.ViewID;
					if (__instance.HasVision && (Object)(object)__instance.Vision != (Object)null)
					{
						__instance.Vision.PlayerAdded(viewID);
					}
					if (__instance.HasOnScreen && (Object)(object)__instance.OnScreen != (Object)null)
					{
						__instance.OnScreen.PlayerAdded(viewID);
					}
				}
			}
		}
	}
	internal static class EscapeRule
	{
		internal const string DeadlineKey = "Hunted.Deadline";

		internal const string ResultKey = "Hunted.Result";

		private static float _sinceStart;

		private static float _holdTimer;

		private static bool _ended;

		private static bool _survivorsWon;

		private static float _endedFor;

		private static bool _changed;

		internal static double? SecondsLeft
		{
			get
			{
				if (!PhotonNetwork.InRoom)
				{
					return null;
				}
				double num = RoomSync.Get<double>("Hunted.Deadline");
				if (!(num > 0.0))
				{
					return null;
				}
				return num - PhotonNetwork.Time;
			}
		}

		internal static string? Result
		{
			get
			{
				if (!PhotonNetwork.InRoom)
				{
					return null;
				}
				return RoomSync.Get<string>("Hunted.Result");
			}
		}

		internal static void Reset()
		{
			_sinceStart = 0f;
			_holdTimer = 0f;
			_ended = false;
			_changed = false;
			_endedFor = 0f;
			if (SemiFunc.IsMasterClientOrSingleplayer() && PhotonNetwork.InRoom)
			{
				Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
				if (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"Hunted.Deadline"))
				{
					RoomSync.Set("Hunted.Deadline", null);
				}
				if (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"Hunted.Result"))
				{
					RoomSync.Set("Hunted.Result", null);
				}
			}
		}

		internal static void Tick(float dt)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !KillerRole.ModeActive || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				return;
			}
			if (_ended)
			{
				_endedFor += dt;
				if (_endedFor >= Tuning.Round.ResultSeconds && !_changed)
				{
					_changed = true;
					RunManager instance = RunManager.instance;
					if (instance.levelArena != null && instance.levelArena.Count > 0 && (Object)(object)instance.levelArena[0] != (Object)null)
					{
						instance.levelCurrent = instance.levelArena[0];
					}
					instance.ChangeLevel(false, true, (ChangeLevelType)0);
				}
				return;
			}
			_sinceStart += dt;
			if (_sinceStart < Tuning.Round.StartDelaySeconds)
			{
				return;
			}
			float value = HuntedConfig.TimeLimitMinutes.Value;
			if (value > 0f && PhotonNetwork.InRoom && RoomSync.Get<double>("Hunted.Deadline") <= 0.0)
			{
				RoomSync.Set("Hunted.Deadline", PhotonNetwork.Time + (double)value * 60.0);
				Hunted.Logger.LogInfo((object)$"Time limit: {value} minutes.");
			}
			List<PlayerAvatar> list = (from p in SemiFunc.PlayerGetList()
				where (Object)(object)p != (Object)null && !KillerRole.IsKiller(p)
				select p).ToList();
			if (list.Count == 0)
			{
				return;
			}
			List<PlayerAvatar> list2 = list.Where((PlayerAvatar p) => !p.isDisabled && !p.deadSet).ToList();
			if (list2.Count == 0)
			{
				Hold(dt, Tuning.Round.KillerWinHoldSeconds, survivorsWin: false, "ALL SURVIVORS ARE DEAD - THE KILLER WINS");
				return;
			}
			if (ExtractionState.TrucksOpen && list2.All((PlayerAvatar p) => p.RoomVolumeCheck.inTruck))
			{
				Hold(dt, Tuning.Round.SurvivorEscapeHoldSeconds, survivorsWin: true, "THE SURVIVORS ESCAPED");
				return;
			}
			_holdTimer = 0f;
			double? secondsLeft = SecondsLeft;
			if (!secondsLeft.HasValue || !(secondsLeft <= 0.0))
			{
				return;
			}
			foreach (PlayerAvatar item in list2)
			{
				item.PlayerDeath(-1);
			}
			End(survivorsWin: false, "TIME IS UP - THE KILLER WINS");
		}

		private static void Hold(float dt, float seconds, bool survivorsWin, string text)
		{
			_holdTimer += dt;
			if (_holdTimer >= seconds)
			{
				End(survivorsWin, text);
			}
		}

		private static void End(bool survivorsWin, string text)
		{
			_ended = true;
			_survivorsWon = survivorsWin;
			Hunted.Logger.LogInfo((object)("Round over: " + text));
			RoomSync.Set("Hunted.Result", text);
		}
	}
	internal static class RoundHud
	{
		private static TextMeshProUGUI? _clock;

		internal static void Tick()
		{
			//IL_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			bool flag = KillerRole.ModeActive && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated;
			string text = (flag ? EscapeRule.Result : null);
			if (!string.IsNullOrEmpty(text))
			{
				SetClock(null);
				if ((Object)(object)BigMessageUI.instance != (Object)null)
				{
					bool flag2 = text.Contains("ESCAPED");
					SemiFunc.UIBigMessage(text, flag2 ? "{check}" : "{!}", 25f, Color.white, flag2 ? Color.green : Color.red);
				}
				return;
			}
			double? num = (flag ? EscapeRule.SecondsLeft : ((double?)null));
			if (!num.HasValue)
			{
				SetClock(null);
				return;
			}
			int num2 = Mathf.Max(0, Mathf.CeilToInt((float)num.Value));
			string text2 = $"{num2 / 60}:{num2 % 60:00}";
			SetClock((num2 <= 60) ? ("<color=#FF2A20>" + text2 + "</color>") : text2);
		}

		private static void SetClock(string? text)
		{
			if (text == null)
			{
				if ((Object)(object)_clock != (Object)null && ((Component)_clock).gameObject.activeSelf)
				{
					((Component)_clock).gameObject.SetActive(false);
				}
			}
			else if (!((Object)(object)_clock == (Object)null) || Create())
			{
				if (!((Component)_clock).gameObject.activeSelf)
				{
					((Component)_clock).gameObject.SetActive(true);
				}
				if (((TMP_Text)_clock).text != text)
				{
					((TMP_Text)_clock).text = text;
				}
			}
		}

		private static bool Create()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			GoalUI instance = GoalUI.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			GameObject val = Object.Instantiate<GameObject>(((Component)instance).gameObject, ((Component)instance).transform.parent);
			((Object)val).name = "Hunted Round Clock";
			MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val2 in components)
			{
				if (!(val2 is TMP_Text))
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			_clock = val.GetComponent<TextMeshProUGUI>();
			RectTransform rectTransform = ((TMP_Text)_clock).rectTransform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 1f);
			rectTransform.anchorMax = val3;
			rectTransform.anchorMin = val3;
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition = new Vector2(0f, -20f);
			((TMP_Text)_clock).alignment = (TextAlignmentOptions)258;
			TextMeshProUGUI? clock = _clock;
			((TMP_Text)clock).fontSize = ((TMP_Text)clock).fontSize * 0.8f;
			((TMP_Text)_clock).enableWordWrapping = false;
			((Graphic)_clock).raycastTarget = false;
			((Behaviour)_clock).enabled = true;
			Hunted.Logger.LogDebug((object)"Round clock created from the extraction counter.");
			return true;
		}
	}
	[HarmonyPatch]
	internal static class LevelNumberPatches
	{
		[HarmonyPatch(typeof(LoadingUI), "LevelAnimationStart")]
		[HarmonyPostfix]
		private static void LevelAnimationStart_Postfix(LoadingUI __instance)
		{
			if (KillerRole.ModeActive && (Object)(object)__instance.levelNumberText != (Object)null && SemiFunc.RunIsLevel())
			{
				((TMP_Text)__instance.levelNumberText).text = "";
			}
		}

		internal static void HideLevelUi()
		{
			LevelUI instance = LevelUI.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				bool flag = !KillerRole.ModeActive;
				if (((Component)instance).gameObject.activeSelf != flag)
				{
					((Component)instance).gameObject.SetActive(flag);
				}
			}
		}
	}
	internal static class ExtractionHost
	{
		internal static void Tick()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Invalid comparison between Unknown and I4
			if (!SemiFunc.IsMasterClientOrSingleplayer() || !KillerRole.ModeActive)
			{
				return;
			}
			RoundDirector instance = RoundDirector.instance;
			IReadOnlyList<ExtractionPoint> readOnlyList = ExtractionPoints.Get();
			if ((Object)(object)instance == (Object)null || readOnlyList.Count == 0 || !instance.extractionPointsFetched)
			{
				return;
			}
			if (!ExtractionState.Active)
			{
				int num = Mathf.Min(LevelPatches.ExtractionAmountPatch.Required, readOnlyList.Count);
				ExtractionState.Init(num);
				Hunted.Logger.LogInfo((object)$"{num} of {readOnlyList.Count} extraction points must be completed, goal ${ExtractionState.Goal} each.");
			}
			ExtractionState.ApplyToRound();
			instance.haulGoal = ExtractionState.Goal * ExtractionState.Required;
			foreach (ExtractionPoint item in readOnlyList)
			{
				if ((Object)(object)item != (Object)null && (int)item.currentState == 1)
				{
					item.ButtonPress();
				}
			}
		}
	}
	internal static class ExtractionState
	{
		private const string RoomKey = "Hunted.Gen";

		internal static int Goal { get; private set; }

		internal static int Required { get; private set; }

		internal static bool Active => Required > 0;

		internal static bool TrucksOpen
		{
			get
			{
				if (Active && (Object)(object)RoundDirector.instance != (Object)null)
				{
					return RoundDirector.instance.extractionPointsCompleted >= Required;
				}
				return false;
			}
		}

		internal static void Reset()
		{
			Goal = 0;
			Required = 0;
		}

		internal static void Init(int required)
		{
			Goal = HuntedConfig.ExtractionGoal.Value;
			Required = required;
			RoomSync.Set("Hunted.Gen", $"{Goal}|{Required}");
		}

		internal static void ReadFromRoom()
		{
			string text = RoomSync.Get<string>("Hunted.Gen");
			if (text != null)
			{
				string[] array = text.Split('|');
				if (array.Length == 2 && int.TryParse(array[0], out var result) && int.TryParse(array[1], out var result2))
				{
					Goal = result;
					Required = result2;
				}
			}
		}

		internal static void ApplyToRound()
		{
			if (Active && (Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.extractionPoints != Required)
			{
				RoundDirector.instance.extractionPoints = Required;
			}
		}
	}
	internal static class ExtractionPoints
	{
		private static readonly List<ExtractionPoint> List = new List<ExtractionPoint>();

		private static int _builtFor;

		internal static void Reset()
		{
			List.Clear();
			_builtFor = 0;
		}

		internal static bool IsInsideTruck(Vector3 position)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			RoomVolume[] array = Object.FindObjectsByType<RoomVolume>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (RoomVolume val in array)
			{
				if (!val.Truck)
				{
					continue;
				}
				Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true);
				foreach (Collider val2 in componentsInChildren)
				{
					Bounds bounds = val2.bounds;
					if (((Bounds)(ref bounds)).Contains(position))
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static IReadOnlyList<ExtractionPoint> Get()
		{
			LevelGenerator instance = LevelGenerator.Instance;
			if ((Object)(object)instance == (Object)null || !instance.Generated || (Object)(object)RoundDirector.instance == (Object)null)
			{
				return List;
			}
			if (_builtFor == ((Object)instance).GetInstanceID())
			{
				return List;
			}
			_builtFor = ((Object)instance).GetInstanceID();
			List.Clear();
			List.AddRange(from go in RoundDirector.instance.extractionPointList
				where (Object)(object)go != (Object)null
				select go.GetComponent<ExtractionPoint>() into p
				where (Object)(object)p != (Object)null && !IsInsideTruck(((Component)p).transform.position)
				orderby Math.Round(((Component)p).transform.position.x, 1), Math.Round(((Component)p).transform.position.z, 1)
				select p);
			Hunted.Logger.LogInfo((object)$"Found {List.Count} extraction points outside the truck.");
			return List;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Prussian.Hunted", "Hunted", "0.1.1")]
	public class Hunted : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static BuilderDelegate <0>__Build;

			public static BuilderDelegate <1>__BuildHeader;
		}

		private float _roleSyncTimer;

		private float _extractionTimer;

		internal static Hunted Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//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_004f: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Tuning.Load();
			HuntedConfig.Bind(((BaseUnityPlugin)this).Config);
			object obj = <>O.<0>__Build;
			if (obj == null)
			{
				BuilderDelegate val = DebugToggles.Build;
				<>O.<0>__Build = val;
				obj = (object)val;
			}
			MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj);
			object obj2 = <>O.<1>__BuildHeader;
			if (obj2 == null)
			{
				BuilderDelegate val2 = KillerCheckboxes.BuildHeader;
				<>O.<1>__BuildHeader = val2;
				obj2 = (object)val2;
			}
			MenuAPI.AddElementToLobbyMenu((BuilderDelegate)obj2);
			ConfigSync.Init(((BaseUnityPlugin)this).Config);
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0025: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
			EnemyIgnore.Apply(Harmony);
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			ConfigSync.Tick();
			KillerCheckboxes.Tick();
			DebugToggles.Tick();
			KillerRole.SessionCheck();
			RoundHud.Tick();
			LevelNumberPatches.HideLevelUi();
			TruckPatches.KeepKillerOutOfTruck();
			KillerWeapon.Tick(Time.deltaTime);
			KillerRescue.Tick(Time.deltaTime);
			KillerVision.Tick(Time.deltaTime);
			KillerMap.Tick(Time.deltaTime);
			KillerHud.Tick();
			KillerEnemyContacts.Tick(Time.deltaTime);
			PlayerHealthRules.Tick(Time.deltaTime);
			SurvivorBoost.Tick();
			KillerAura.Tick();
			DummySurvivor.Tick();
			KillerBody.Tick();
			KillerLook.Tick(Time.deltaTime);
			_extractionTimer -= Time.unscaledDeltaTime;
			if (_extractionTimer <= 0f)
			{
				_extractionTimer = 0.25f;
				ExtractionHost.Tick();
				ExtractionState.ApplyToRound();
				TruckSingletons.Tick();
				EscapeRule.Tick(0.25f);
				CartSpawner.Tick(0.25f);
				MapMarkers.Tick();
				KillerRoomMap.Tick();
				KillerRoomRules.Tick(0.25f);
				TruckMapCover.Tick();
				PlayerHealthRules.Sync();
				SurvivorBoost.Sync();
				MapDump.Tick(0.25f);
				ValuableSpawner.Tick(0.25f);
			}
			_roleSyncTimer -= Time.unscaledDeltaTime;
			if (!(_roleSyncTimer > 0f))
			{
				_roleSyncTimer = 0.5f;
				KillerRole.Sync();
				ModPresence.Tick();
			}
		}
	}
	internal static class HuntedConfig
	{
		internal static ConfigEntry<float> KillerWalkSpeedMultiplier;

		internal static ConfigEntry<float> TimeLimitMinutes;

		internal static ConfigEntry<float> KillerFogStart;

		internal static ConfigEntry<float> KillerFogEnd;

		internal static ConfigEntry<float> NightVisionRange;

		internal static ConfigEntry<float> NightVisionIntensity;

		internal static ConfigEntry<float> EnergyPerSurvivorHit;

		internal static ConfigEntry<int> WeaponDamage;

		internal static ConfigEntry<float> EnergyDrainPerSecond;

		internal static ConfigEntry<float> ChargeRate;

		internal static ConfigEntry<int> ExtractionGoal;

		internal static ConfigEntry<int> MaxHealth;

		internal static ConfigEntry<float> HealthRegenPerSecond;

		internal static ConfigEntry<float> BoostSeconds;

		internal static ConfigEntry<int> GridColumns;

		internal static ConfigEntry<int> GridRows;

		internal static void Bind(ConfigFile config)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Expected O, but got Unknown
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Expected O, but got Unknown
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Expected O, but got Unknown
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Expected O, but got Unknown
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Expected O, but got Unknown
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Expected O, but got Unknown
			ConfigDefaults.Load();
			KillerWalkSpeedMultiplier = config.Bind<float>("Killer", "WalkSpeedMultiplier", ConfigDefaults.Get<float>("Killer", "WalkSpeedMultiplier"), new ConfigDescription("Killer walking speed relative to a normal player's walking speed. The killer cannot sprint.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>()));
			ExtractionGoal = config.Bind<int>("Extraction", "GoalPerPoint", ConfigDefaults.Get<int>("Extraction", "GoalPerPoint"), new ConfigDescription("Dollar value of valuables that must be deposited into one extraction point to complete it.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1000, 20000), Array.Empty<object>()));
			MaxHealth = config.Bind<int>("Survivor", "MaxHealth", ConfigDefaults.Get<int>("Survivor", "MaxHealth"), new ConfigDescription("Health every player starts a level with, and the most they can have.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 500), Array.Empty<object>()));
			HealthRegenPerSecond = config.Bind<float>("Survivor", "RegenPerSecond", ConfigDefaults.Get<float>("Survivor", "RegenPerSecond"), new ConfigDescription("Host only. Health a living player regenerates per second. 0 turns regeneration off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			BoostSeconds = config.Bind<float>("Survivor", "BoostSeconds", ConfigDefaults.Get<float>("Survivor", "BoostSeconds"), new ConfigDescription("A survivor who is revived, or hit down to half their maximum health or less, runs without tiring and cannot be tumbled by anything but themselves for this long. 0 turns the boost off.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			GridColumns = config.Bind<int>("Level", "Columns", ConfigDefaults.Get<int>("Level", "Columns"), new ConfigDescription("Columns of rooms in the map's inner grid. The extraction rooms and dead ends sit in an extra column on each side.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 10), Array.Empty<object>()));
			GridRows = config.Bind<int>("Level", "Rows", ConfigDefaults.Get<int>("Level", "Rows"), new ConfigDescription("Rows of rooms in the map's inner grid. The trucks sit outside the first and last row. More rows leave more room for extraction rooms and dead ends.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 10), Array.Empty<object>()));
			EnergyPerSurvivorHit = config.Bind<float>("Sword", "EnergyPerSurvivorHit", ConfigDefaults.Get<float>("Sword", "EnergyPerSurvivorHit"), new ConfigDescription("Host only. Energy (out of 100) the sword loses when it hits a survivor.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			WeaponDamage = config.Bind<int>("Sword", "DamagePerHit", ConfigDefaults.Get<int>("Sword", "DamagePerHit"), new ConfigDescription("Damage the killer's weapon deals to a survivor per hit.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>()));
			EnergyDrainPerSecond = config.Bind<float>("Sword", "EnergyDrainPerSecond", ConfigDefaults.Get<float>("Sword", "EnergyDrainPerSecond"), new ConfigDescription("Energy (out of 100) the weapon loses per second, held or not, on top of the normal loss per hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			ChargeRate = config.Bind<float>("Sword", "ChargePerSecond", ConfigDefaults.Get<float>("Sword", "ChargePerSecond"), new ConfigDescription("Energy the killer's weapon regains per second while the killer is in the killer room.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			KillerFogStart = config.Bind<float>("Vision", "KillerFogStart", ConfigDefaults.Get<float>("Vision", "KillerFogStart"), new ConfigDescription("Killer only. Distance at which the fog starts, the same in every room.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			KillerFogEnd = config.Bind<float>("Vision", "KillerFogEnd", ConfigDefaults.Get<float>("Vision", "KillerFogEnd"), new ConfigDescription("Killer only. Distance at which the fog is solid and the view ends, the same in every room. 0 gives the killer the game's own room fog.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
			NightVisionRange = config.Bind<float>("Vision", "NightVisionRange", ConfigDefaults.Get<float>("Vision", "NightVisionRange"), new ConfigDescription("Reach of the night-vision light around the killer (metres).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>()));
			NightVisionIntensity = config.Bind<float>("Vision", "NightVisionIntensity", ConfigDefaults.Get<float>("Vision", "NightVisionIntensity"), new ConfigDescription("Brightness of the night-vision light.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			TimeLimitMinutes = config.Bind<float>("Extraction", "TimeLimitMinutes", ConfigDefaults.Get<float>("Extraction", "TimeLimitMinutes"), new ConfigDescription("The survivors lose when this many minutes pass before they escape.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 30f), Array.Empty<object>()));
		}
	}
	internal static class KillerAura
	{
		private static GameObject? _object;

		private static PlayerAvatar? _owner;

		internal static void Reset()
		{
			if ((Object)(object)_object != (Object)null)
			{
				Object.Destroy((Object)(object)_object);
			}
			_object = null;
			_owner = null;
		}

		internal static void Tick()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = null;
			if (KillerRole.ModeActive && KillerRole.KillerSteamId != null)
			{
				foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
				{
					if ((Object)(object)item != (Object)null && KillerRole.IsKiller(item))
					{
						val = item;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val.localCamera == (Object)null || val.isDisabled)
			{
				if ((Object)(object)_object != (Object)null)
				{
					Reset();
				}
				return;
			}
			if ((Object)(object)_object != (Object)null && (Object)(object)_owner == (Object)(object)val)
			{
				Apply(_object.GetComponent<Light>());
				return;
			}
			Reset();
			_owner = val;
			_object = new GameObject("Hunted Red Light");
			_object.transform.SetParent(((Component)val.localCamera).transform, false);
			_object.transform.localPosition = Vector3.zero;
			_object.transform.localRotation = Quaternion.identity;
			Light val2 = _object.AddComponent<Light>();
			val2.type = (LightType)2;
			val2.color = new Color(1f, 0f, 0f);
			Apply(val2);
			Hunted.Logger.LogDebug((object)string.Format("Red light built on the camera of {0} (this game is {1}): enabled={2}, range={3}, intensity={4}, shadows={5}.", val.playerName, val.isLocal ? "the killer" : "a survivor", ((Behaviour)val2).enabled, val2.range, val2.intensity, val2.shadows));
		}

		private static void Apply(Light light)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Behaviour)light).enabled)
			{
				((Behaviour)light).enabled = true;
			}
			LightShadows val = (LightShadows)(!_owner.isLocal);
			if (light.shadows != val)
			{
				light.shadows = val;
			}
			light.range = Tuning.Killer.RedLightRange;
			light.intensity = Tuning.Killer.RedLightIntensity;
		}
	}
	internal static class KillerBody
	{
		private static PlayerAvatar? _scaled;

		private static Vector3 _baseScale = Vector3.one;

		private static PlayerAvatar? _soundOwner;

		private static readonly HashSet<Sound> Sounds = new HashSet<Sound>();

		private static readonly FieldInfo[] SoundFields = (from f in typeof(PlayerAvatar).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
			where f.FieldType == typeof(Sound)
			select f).ToArray();

		internal static int Muted;

		internal static int Heavy;

		private static float _shadowTimer;

		private static float? _baseEyeOffset;

		internal static bool IsKillerSound(Sound sound)
		{
			return Sounds.Contains(sound);
		}

		internal static void Reset()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_scaled != (Object)null)
			{
				((Component)_scaled.playerAvatarVisuals).transform.localScale = _baseScale;
			}
			RestoreEyes();
			_scaled = null;
			_soundOwner = null;
			Sounds.Clear();
			Muted = (Heavy = 0);
		}

		private static void RaiseEyes(PlayerAvatar killer)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			CameraPosition instance = CameraPosition.instance;
			if (!((Object)(object)instance == (Object)null) && killer.isLocal)
			{
				float valueOrDefault = _baseEyeOffset.GetValueOrDefault();
				if (!_baseEyeOffset.HasValue)
				{
					valueOrDefault = instance.playerOffset.y;
					_baseEyeOffset = valueOrDefault;
				}
				Vector3 playerOffset = instance.playerOffset;
				playerOffset.y = _baseEyeOffset.Value + (Tuning.Killer.Scale - 1f) * 1.7f;
				instance.playerOffset = playerOffset;
			}
		}

		private static void RestoreEyes()
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			CameraPosition instance = CameraPosition.instance;
			if ((Object)(object)instance != (Object)null && _baseEyeOffset.HasValue)
			{
				Vector3 playerOffset = instance.playerOffset;
				playerOffset.y = _baseEyeOffset.Value;
				instance.playerOffset = playerOffset;
			}
			_baseEyeOffset = null;
		}

		private static void NoShadows(PlayerAvatar killer)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			List<Renderer> list = new List<Renderer>(((Component)killer).GetComponentsInChildren<Renderer>(true));
			if ((Object)(object)killer.tumble != (Object)null)
			{
				list.AddRange(((Component)killer.tumble).GetComponentsInChildren<Renderer>(true));
			}
			if ((Object)(object)KillerWeapon.Weapon != (Object)null)
			{
				list.AddRange(((Component)KillerWeapon.Weapon).GetComponentsInChildren<Renderer>(true));
			}
			foreach (Renderer item in list)
			{
				if ((Object)(object)item != (Object)null && (int)item.shadowCastingMode != 0 && !(item is ParticleSystemRenderer))
				{
					item.shadowCastingMode = (ShadowCastingMode)0;
				}
			}
		}

		internal static void Tick()
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00fc: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar val = null;
			if (KillerRole.ModeActive && KillerRole.KillerSteamId != null)
			{
				val = ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p != (Object)null && KillerRole.IsKiller(p)));
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val.playerAvatarVisuals == (Object)null)
			{
				if ((Object)(object)_scaled != (Object)null || (Object)(object)_soundOwner != (Object)null)
				{
					Reset();
				}
				return;
			}
			if ((Object)(object)_scaled != (Object)(object)val)
			{
				if ((Object)(object)_scaled != (Object)null)
				{
					((Component)_scaled.playerAvatarVisuals).transform.localScale = _baseScale;
				}
				_scaled = val;
				_baseScale = ((Component)val.playerAvatarVisuals).transform.localScale;
				Hunted.Logger.LogInfo((object)string.Format("Killer {0} scaled x{1:0.##} (model {2} -> {3}, this game is {4}).", val.playerName, Tuning.Killer.Scale, _baseScale, _baseScale * Tuning.Killer.Scale, val.isLocal ? "the killer" : "a survivor"));
			}
			((Component)val.playerAvatarVisuals).transform.localScale = _baseScale * Tuning.Killer.Scale;
			RaiseEyes(val);
			_shadowTimer -= Time.unscaledDeltaTime;
			if (_shadowTimer <= 0f)
			{
				_shadowTimer = 1f;
				NoShadows(val);
			}
			if (!((Object)(object)_soundOwner != (Object)(object)val))
			{
				return;
			}
			_soundOwner = val;
			Sounds.Clear();
			FieldInfo[] soundFields = SoundFields;
			foreach (FieldInfo fieldInfo in soundFields)
			{
				object? value = fieldInfo.GetValue(val);
				Sound val2 = (Sound)((value is Sound) ? value : null);
				if (val2 != null && val2 != null)
				{
					Sounds.Add(val2);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class KillerBodyPatches
	{
		[HarmonyPatch(typeof(PlayerAvatar), "Footstep")]
		[HarmonyPrefix]
		private static void Footstep_Prefix(PlayerAvatar __instance)
		{
			Enter(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerAvatar), "Footstep")]
		[HarmonyFinalizer]
		private static void Footstep_Finalizer(PlayerAvatar __instance)
		{
			Leave(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerAvatar), "JumpRPC")]
		[HarmonyPrefix]
		private static void Jump_Prefix(PlayerAvatar __instance)
		{
			Enter(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerAvatar), "JumpRPC")]
		[HarmonyFinalizer]
		private static void Jump_Finalizer(PlayerAvatar __instance)
		{
			Leave(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerAvatar), "LandRPC")]
		[HarmonyPrefix]
		private static void Land_Prefix(PlayerAvatar __instance)
		{
			Enter(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerAvatar), "LandRPC")]
		[HarmonyFinalizer]
		private static void Land_Finalizer(PlayerAvatar __instance)
		{
			Leave(__instance, heavy: true);
		}

		[HarmonyPatch(typeof(PlayerVoiceChat), "Update")]
		[HarmonyPrefix]
		private static void Voice_Prefix(PlayerVoiceChat __instance)
		{
			Enter(__instance.playerAvatar, heavy: false);
		}

		[HarmonyPatch(typeof(PlayerVoiceChat), "Update")]
		[HarmonyFinalizer]
		private static void Voice_Finalizer(PlayerVoiceChat __instance)
		{
			Leave(__instance.playerAvatar, heavy: false);
		}

		[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "EnemyInvestigate", new Type[]
		{
			typeof(float),
			typeof(Vector3)
		})]
		[HarmonyPrefix]
		private static void Impact_Prefix(PhysGrabObjectImpactDetector __instance, out bool __state)
		{
			__state = KillerRole.ModeActive && (Object)(object)__instance.physGrabObject != (Object)null && __instance.physGrabObject.playerGrabbing.Any((PhysGrabber g) => (Object)(object)g != (Object)null && KillerRole.IsKiller(g.playerAvatar));
			if (__state)
			{
				KillerBody.Muted++;
			}
		}

		[HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "EnemyInvestigate", new Type[]
		{
			typeof(float),
			typeof(Vector3)
		})]
		[HarmonyFinalizer]
		private static void Impact_Finalizer(bool __state)
		{
			if (__state)
			{
				KillerBody.Muted--;
			}
		}

		[HarmonyPatch(typeof(EnemyDirector), "SetInvestigate")]
		[HarmonyPrefix]
		private static bool SetInvestigate_Prefix()
		{
			return KillerBody.Muted <= 0;
		}

		private static void Enter(PlayerAvatar? avatar, bool heavy)
		{
			if (KillerRole.ModeActive && KillerRole.IsKiller(avatar))
			{
				KillerBody.Muted++;
				if (heavy)
				{
					KillerBody.Heavy++;
				}
			}
		}

		private static void Leave(PlayerAvatar? avatar, bool heavy)
		{
			if (KillerRole.ModeActive && KillerRole.IsKiller(avatar))
			{
				KillerBody.Muted = Math.Max(0, KillerBody.Muted - 1);
				if (heavy)
				{
					KillerBody.Heavy = Math.Max(0, KillerBody.Heavy - 1);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class KillerSoundPatch
	{
		private static readonly MethodInfo PlayMethod = AccessTools.Method(typeof(Sound), "Play", new Type[5]
		{
			typeof(Vector3),
			typeof(float),
			typeof(float),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static MethodBase TargetMethod()
		{
			return PlayMethod;
		}

		[HarmonyPrefix]
		private static void Play_Prefix(Sound __instance, ref float falloffMultiplier, out (float volume, float pitch, bool changed) __state)
		{
			__state = (volume: __instance.Volume, pitch: __instance.Pitch, changed: false);
			if (KillerRole.ModeActive && (KillerBody.Heavy > 0 || KillerBody.IsKillerSound(__instance)))
			{
				__instance.Volume *= Tuning.Killer.SoundVolumeMultiplier;
				__instance.Pitch *= Tuning.Killer.SoundPitchMultiplier;
				falloffMultiplier *= Tuning.Killer.SoundRangeMultiplier;
				__state.changed = true;
			}
		}

		[HarmonyPostfix]
		private static void Play_Postfix(Sound __instance, (float volume, float pitch, bool changed) __state)
		{
			if (__state.changed)
			{
				(__instance.Volume, __instance.Pitch, _) = __state;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerCollision), "Update")]
	internal static class KillerColliderPatch
	{
		[HarmonyPostfix]
		private static void Update_Postfix(PlayerCollision __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (KillerRole.ModeActive && KillerRole.LocalIsKiller)
			{
				Transform transform = ((Component)__instance).transform;
				transform.localScale *= Tuning.Killer.Scale;
			}
		}
	}
	internal static class KillerChoice
	{
		private const string Key = "Hunted.KillerPick";

		internal static int Actor => RoomSync.Get<int>("Hunted.KillerPick");

		internal static void Toggle(int actor)
		{
			if (SemiFunc.IsMasterClientOrSingleplayer())
			{
				RoomSync.Set("Hunted.KillerPick", (Actor != actor) ? actor : 0);
			}
		}

		internal static PlayerAvatar? Chosen(IEnumerable<PlayerAvatar> players)
		{
			int actor = Actor;
			if (actor == 0)
			{
				return null;
			}
			return players.FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p.photonView != (Object)null && p.photonView.Owner != null && p.photonView.Owner.ActorNumber == actor));
		}
	}
	[HarmonyPatch]
	internal static class KillerCheckboxes
	{
		private sealed class Box
		{
			internal MenuPlayerListed Row;

			internal int Actor;

			internal REPOButton Button;

			internal Image Outer;

			internal Image Fill;
		}

		private static readonly List<Box> Boxes = new List<Box>();

		private static readonly Color Red = new Color(0.95f, 0.2f, 0.15f);

		private static readonly Color Idle = new Color(0.55f, 0.55f, 0.55f);

		private static readonly Vector2 BoxPosition = new Vector2(326f, 17f);

		private const float BoxSize = 20f;

		internal static void BuildHeader(Transform page)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			MenuPageLobby instance = MenuPageLobby.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.playerListTransform == (Object)null) && !((Object)(object)instance.chatPromptText == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)instance.chatPromptText).gameObject, (Transform)(object)instance.playerListTransform);
				((Object)val).name = "Hunted Killer Header";
				LocalizationChangedEvent[] componentsInChildren = val.GetComponentsInChildren<LocalizationChangedEvent>(true);
				foreach (LocalizationChangedEvent val2 in componentsInChildren)
				{
					Object.Destroy((Object)(object)val2);
				}
				TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
				((TMP_Text)component).text = "KILLER\n<size=70%>none = random</size>";
				((TMP_Text)component).alignment = (TextAlignmentOptions)514;
				((TMP_Text)component).enableAutoSizing = false;
				((TMP_Text)component).fontSize = 13f;
				((Graphic)component).color = new Color(0.8f, 0.8f, 0.8f);
				((Graphic)component).raycastTarget = false;
				RectTransform rectTransform = ((TMP_Text)component).rectTransform;
				Vector2 anchorMin = (rectTransform.anchorMax = Vector2.zero);
				rectTransform.anchorMin = anchorMin;
				rectTransform.pivot = new Vector2(0.5f, 0.5f);
				rectTransform.sizeDelta = new Vector2(110f, 32f);
				((Transform)rectTransform).localScale = Vector3.one;
				((Transform)rectTransform).localPosition = new Vector3(BoxPosition.x, BoxPosition.y + 36f, 0f);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MenuPageLobby), "PlayerAdd")]
		private static void PlayerAdd_Postfix(MenuPageLobby __instance, Player player)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00f5: 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)
			MenuPlayerListed val = ((IEnumerable<MenuPlayerListed>)__instance.menuPlayerListedList).LastOrDefault((Func<MenuPlayerListed, bool>)((MenuPlayerListed r) => (Object)(object)r != (Object)null && r.playerPhoton == player));
			if (!((Object)(object)val == (Object)null))
			{
				int actor = player.ActorNumber;
				REPOButton val2 = MenuAPI.CreateREPOButton("", (Action)delegate
				{
					KillerChoice.Toggle(actor);
				}, ((Component)val).transform, default(Vector2));
				val2.overrideButtonSize = new Vector2(20f, 20f);
				((TMP_Text)val2.labelTMP).text = "";
				Box box = new Box
				{
					Row = val,
					Actor = actor,
					Button = val2
				};
				box.Outer = Square("Box", ((Component)val2).transform, 20f, Idle);
				Square("Hollow", ((Component)val2).transform, 16f, new Color(0.08f, 0.08f, 0.08f, 1f));
				box.Fill = Square("Mark", ((Component)val2).transform, 12f, Red);
				Boxes.Add(box);
			}
		}

		private static Image Square(string name, Transform parent, float size, Color color)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(size, size);
			val2.anchoredPosition = Vector2.zero;
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = color;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		internal static void Tick()
		{
			//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_00a9: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			if (Boxes.Count == 0)
			{
				return;
			}
			bool flag = SemiFunc.IsMasterClientOrSingleplayer();
			int actor = KillerChoice.Actor;
			for (int num = Boxes.Count - 1; num >= 0; num--)
			{
				Box box = Boxes[num];
				if ((Object)(object)box.Row == (Object)null || (Object)(object)box.Button == (Object)null)
				{
					Boxes.RemoveAt(num);
				}
				else
				{
					bool flag2 = box.Actor == actor;
					MenuButton menuButton = box.Button.menuButton;
					menuButton.disabled = !flag;
					((Behaviour)box.Fill).enabled = flag2;
					Color val = ((menuButton.hovering && flag) ? Color.white : (flag2 ? Red : Idle));
					if (!flag)
					{
						val *= 0.8f;
					}
					((Graphic)box.Outer).color = val;
					RectTransform rectTransform = ((REPOElement)box.Button).rectTransform;
					rectTransform.pivot = new Vector2(0.5f, 0.5f);
					((Transform)rectTransform).localPosition = new Vector3(BoxPosition.x, BoxPosition.y, 0f);
				}
			}
		}
	}
	internal static class KillerEnemyContacts
	{
		private static readonly HashSet<int> KillerIgnored = new HashSet<int>();

		private static readonly HashSet<int> EnemyIgnored = new HashSet<int>();

		private static float _timer;

		internal static void Reset()
		{
			KillerIgnored.Clear();
			EnemyIgnored.Clear();
			_timer = 0f;
		}

		internal static void Tick(float dt)
		{
			if (!KillerRole.ModeActive || KillerRole.KillerSteamId == null)
			{
				return;
			}
			_timer -= dt;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 1f;
			List<Collider> list = new List<Collider>();
			PlayerAvatar val = ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => KillerRole.IsKiller(p)));
			if ((Object)(object)val != (Object)null)
			{
				list.AddRange(((Component)val).GetComponentsInChildren<Collider>(true));
			}
			if (KillerRole.LocalIsKiller && (Object)(object)PlayerController.instance != (Object)null)
			{
				list.AddRange(((Component)PlayerController.instance).GetComponentsInChildren<Collider>(true));
			}
			if ((Object)(object)KillerWeapon.Weapon != (Object)null)
			{
				list.AddRange(((Component)KillerWeapon.Weapon).GetComponentsInChildren<Collider>(true));
			}
			list = list.Where((Collider c) => (Object)(object)c != (Object)null).Distinct().ToList();
			List<Collider> list2 = (from c in Object.FindObjectsByType<EnemyParent>((FindObjectsInactive)1, (FindObjectsSortMode)0).SelectMany((EnemyParent e) => ((Component)e).GetComponentsInChildren<Collider>(true))
				where (Object)(object)c != (Object)null
				select c).ToList();
			List<Collider> list3 = list.Where((Collider c) => KillerIgnored.Add(((Object)c).GetInstanceID())).ToList();
			List<Collider> list4 = list2.Where((Collider c) => EnemyIgnored.Add(((Object)c).GetInstanceID())).ToList();
			if (list3.Count == 0 && list4.Count == 0)
			{
				return;
			}
			foreach (Collider item in list3)
			{
				foreach (Collider item2 in list2)
				{
					Ignore(item, item2);
				}
			}
			foreach (Collider item3 in list4)
			{
				foreach (Collider item4 in list.Except(list3))
				{
					Ignore(item4, item3);
				}
			}
		}

		private static void Ignore(Collider a, Collider b)
		{
			if ((Object)(object)a != (Object)null && (Object)(object)b != (Object)null && (Object)(object)a != (Object)(object)b)
			{
				Physics.IgnoreCollision(a, b, true);
			}
		}
	}
	internal static class KillerHud
	{
		private static bool _hidden;

		internal static void Tick()
		{
			bool flag = KillerRole.ModeActive && KillerRole.LocalIsKiller;
			if (flag != _hidden || flag)
			{
				Set((Component?)(object)HealthUI.instance, !flag);
				Set((Component?)(object)EnergyUI.instance, !flag);
				_hidden = flag;
			}
		}

		private static void Set(Component? ui, bool visible)
		{
			if ((Object)(object)ui != (Object)null && ui.gameObject.activeSelf != visible)
			{
				ui.gameObject.SetActive(visible);
			}
		}
	}
	internal static class KillerLook
	{
		private static readonly int EmissionColor = Shader.PropertyToID("_EmissionColor");

		private static List<int>? _skeleton;

		private static float _timer;

		private static PlayerAvatar? _logged;

		private static int _cosmeticAttempts;

		private static PlayerAvatar? _cosmeticsFor;

		internal static void Reset()
		{
			_timer = 0f;
			_logged = null;
			_cosmeticAttempts = 0;
			_cosmeticsFor = null;
		}

		private static bool IsSkeleton(CosmeticAsset? asset)
		{
			if ((Object)(object)asset != (Object)null)
			{
				return ((Object)asset).name.IndexOf("skeleton", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		internal static int[] SkeletonIndices()
		{
			List<CosmeticAsset> assets = (((Object)(object)MetaManager.instance != (Object)null) ? MetaManager.instance.cosmeticAssets : null);
			if (assets == null)
			{
				return Array.Empty<int>();
			}
			if (_skeleton == null || _skeleton.Count == 0)
			{
				_skeleton = new List<int>();
				for (int i = 0; i < assets.Count; i++)
				{
					if (IsSkeleton(assets[i]))
					{
						_skeleton.Add(i);
					}
				}
				Hunted.Logger.LogInfo((object)("Skeleton cosmetics for the killer: " + string.Join(", ", _skeleton.Select((int index) => ((Object)assets[index]).name))));
			}
			return _skeleton.ToArray();
		}

		internal static bool BelongsToKiller(PlayerCosmetics cosmetics)
		{
			if (!KillerRole.ModeActive || KillerRole.KillerSteamId == null)
			{
				return false;
			}
			PlayerAvatar val = (((Object)(object)cosmetics.playerAvatarVisuals != (Object)null && !cosmetics.playerAvatarVisuals.isMenuAvatar) ? cosmetics.playerAvatarVisuals.playerAvatar : (((Object)(object)cosmetics.deathHead != (Object)null) ? cosmetics.deathHead.playerAvatar : null));
			if ((Object)(object)val != (Object)null)
			{
				return KillerRole.IsKiller(val);
			}
			return false;
		}

		internal static void Tick(float dt)
		{
			_timer -= dt;
			if (_timer > 0f)
			{
				return;
			}
			_timer = 0.5f;
			PlayerAvatar val = null;
			if (KillerRole.ModeActive && KillerRole.KillerSteamId != null)
			{
				val = ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar p) => (Object)(object)p != (Object)null && KillerRole.IsKiller(p)));
			}
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.playerAvatarVisuals == (Object)null))
			{
				EnsureSkeleton(val);
				if ((Object)(object)val.playerCosmetics != (Object)null)
				{
					WhitenOutfit(val.playerCosmetics);
				}
				GlowEyes(val);
			}
		}

		internal static void WhitenOutfit(PlayerCosmetics cosmetics)
		{
			//IL_00db: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			PlayerEyes val = (((Object)(object)cosmetics.playerAvatarVisuals != (Object)null) ? cosmetics.playerAvatarVisuals.playerEyes : null);
			Transform[] source = (Transform[])(object)(((Object)(object)val == (Object)null) ? new Transform[0] : new Transform[4] { val.eyeLeft, val.eyeRight, val.pupilLeft, val.pupilRight });
			foreach (PlayerMaterial part in cosmetics.playerMaterials)
			{
				Material val2 = (((Object)(object)part != (Object)null) ? part.material : null);
				if (!((Object)(object)val2 == (Object)null) && !source.Any((Transform e) => (Object)(object)e != (Object)null && ((Component)part).transform.IsChildOf(e)))
				{
					Color val3 = (val2.HasProperty("_AlbedoColor") ? val2.GetColor("_AlbedoColor") : Color.white);
					SetColor(val2, "_AlbedoColor", new Color(1f, 1f, 1f, val3.a));
					SetTexture(val2, "_AlbedoTexture", (Texture)(object)Texture2D.whiteTexture);
					if ((int)part.tintType != 0)
					{
						SetColor(val2, "_EmissionColor", Color.black);
					}
					if (part.tintFresnel)
					{
						SetColor(val2, "_FresnelColor", Color.white);
					}
				}
			}
		}

		private static void EnsureSkeleton(PlayerAvatar killer)
		{
			PlayerCosmetics playerCosmetics = killer.playerCosmetics;
			if (!((Object)(object)playerCosmetics == (Object)null) && !playerCosmetics.firstSetup && Object.op_Implicit((Object)(object)LevelGenerator.Instance) && LevelGenerator.Instance.Generated)
			{
				if ((Object)(object)_cosmeticsFor != (Object)(object)killer)
				{
					_cosmeticsFor = killer;
					_cosmeticAttempts = 0;
				}
				if (!playerCosmetics.cosmeticEquipped.Any((Cosmetic c) => (Object)(object)c != (Object)null && IsSkeleton(c.cosmeticAsset)) && _cosmeticAttempts < 6)
				{
					_cosmeticAttempts++;
					playerCosmetics.SetupCosmeticsLogic(playerCosmetics.cosmeticEquippedRaw.ToArray(), false);
				}
			}
		}

		private static void GlowEyes(PlayerAvatar killer)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00f4: 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)
			PlayerEyes playerEyes = killer.playerAvatarVisuals.playerEyes;
			if ((Object)(object)playerEyes == (Object)null)
			{
				return;
			}
			float eyeGlow = Tuning.Killer.EyeGlow;
			Transform[] array = (Transform[])(object)new Transform[2] { playerEyes.eyeLeft, playerEyes.eyeRight };
			foreach (Transform val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer renderer in componentsInChildren)
					{
						Tint(renderer, new Color(1f, 0f, 0f, 1f), eyeGlow);
					}
					if (!killer.isLocal && (Object)(object)val.Find("Hunted Eye Light") == (Object)null)
					{
						GameObject val2 = new GameObject("Hunted Eye Light");
						val2.transform.SetParent(val, false);
						Light val3 = val2.AddComponent<Light>();
						val3.type = (LightType)2;
						val3.color = new Color(1f, 0.05f, 0.05f);
						val3.range = Tuning.Killer.EyeLightRange;
						val3.intensity = Tuning.Killer.EyeLightIntensity;
						val3.shadows = (LightShadows)0;
					}
				}
			}
			Transform[] array2 = (Transform[])(object)new Transform[2] { playerEyes.pupilLeft, playerEyes.pupilRight };
			foreach (Transform val4 in array2)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					Renderer[] componentsInChildren2 = ((Component)val4).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer renderer2 in componentsInChildren2)
					{
						Tint(renderer2, new Color(1f, 0f, 0f, 1f), eyeGlow);
					}
				}
			}
			if (!((Object)(object)_logged != (Object)(object)killer))
			{
				return;
			}
			_logged = killer;
			IEnumerable<string> values = ((IEnumerable<Renderer>)(((Object)(object)playerEyes.eyeLeft != (Object)null) ? ((Array)((Component)playerEyes.eyeLeft).GetComponentsInChildren<Renderer>(true)) : ((Array)new Renderer[0]))).Select((Renderer r) => ((Object)r).name + " [" + string.Join("/", from m in r.sharedMaterials
				where (Object)(object)m != (Object)null
				select ((Object)m.shader).name) + "]");
			Hunted.Logger.LogDebug((object)("Killer eyes: " + string.Join(", ", values)));
		}

		private static void Tint(Renderer renderer, Color color, float emission)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if (renderer is ParticleSystemRenderer)
			{
				return;
			}
			bool flag = emission > 0f;
			Material[] materials = renderer.materials;
			foreach (Material val in materials)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				SetColor(val, "_AlbedoColor", flag ? Color.black : color);
				SetColor(val, "_BaseColor", flag ? Color.black : color);
				SetColor(val, "_Color", flag ? Color.black : color);
				SetTexture(val, "_AlbedoTexture", (Texture)(object)Texture2D.whiteTexture);
				SetTexture(val, "_MainTex", (Texture)(object)Texture2D.whiteTexture);
				SetTexture(val, "_BaseMap", (Texture)(object)Texture2D.whiteTexture);
				SetTexture(val, "_EmissionTexture", (Texture)(object)Texture2D.whiteTexture);
				SetTexture(val, "_EmissionMap", (Texture)(object)Texture2D.whiteTexture);
				string[] array = new string[6] { "_FresnelAmount", "_FresnelEmission", "_Metallic", "_Smoothness", "_NormalStrength", "_ColorOverlayAmount" };
				foreach (string text in array)
				{
					if (val.HasProperty(text))
					{
						val.SetFloat(text, 0f);
					}
				}
				if (val.HasProperty(EmissionColor))
				{
					val.EnableKeyword("_EMISSION");
					val.SetColor(EmissionColor, flag ? (color * emission) : Color.black);
				}
			}
		}

		private static void SetColor(Material material, string name, Color color)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty(name))
			{
				material.SetColor(name, color);
			}
		}

		private static void SetTexture(Material material, string name, Texture texture)
		{
			if (material.HasProperty(name))
			{
				material.SetTexture(name, texture);
			}
		}
	}
	[HarmonyPatch]
	internal static class KillerLookPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerCosmetics), "SetupCosmeticsLogic")]
		private static void SetupCosmetics_Prefix(PlayerCosmetics __instance, ref int[] _cosmeticEquipped)
		{
			if (KillerLook.BelongsToKiller(__instance))
			{
				_cosmeticEquipped = KillerLook.SkeletonIndices();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerCosmetics), "SetupColorsLogic")]
		private static void SetupColors_Postfix(PlayerCosmetics __instance)
		{
			if (KillerLook.BelongsToKiller(__instance))
			{
				KillerLook.WhitenOutfit(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerCosmetics), "SetupColorsAllLogic")]
		private static void SetupColorsAll_Postfix(PlayerCosmetics __instance)
		{
			if (KillerLook.BelongsToKiller(__instance))
			{
				KillerLook.WhitenOutfit(__instance);
			}
		}
	}
	internal static class KillerMap
	{
		private static Camera? _camera;

		private static float _baseSize;

		private static float _baseFov;

		private static float _revealTimer;

		internal static void Reset()
		{
			_camera = null;
			_revealTimer = 0f;
		}

		internal static void Tick(float dt)
		{
			if (!KillerRole.ModeActive || (Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				return;
			}
			bool localIsKiller = KillerRole.LocalIsKiller;
			_revealTimer -= dt;
			if (_revealTimer <= 0f)
			{
				_revealTimer = 1f;
				if (localIsKiller)
				{
					RevealRooms();
				}
				FindCamera();
			}
			ApplyZoom(localIsKiller ? Tuning.Map.KillerZoomOut : Tuning.Map.SurvivorZoomOut);
		}

		private static void RevealRooms()
		{
			RoomVolume[] array = Object.FindObjectsByType<RoomVolume>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			foreach (RoomVolume val in array)
			{
				if ((Object)(object)val.MapModule != (Object)null)
				{
					val.SetExplored();
				}
			}
		}

		private static void FindCamera()
		{
			if (!((Object)(object)_camera != (Object)null))
			{
				int mask = LayerMask.GetMask(new string[1] { "DirtFinderMap" });
				Camera main = (((Object)(object)CameraUtils.Instance != (Object)null) ? CameraUtils.Instance.MainCamera : null);
				_camera = (from c in Object.FindObjectsByType<Camera>((FindObjectsInactive)1, (FindObjectsSortMode)0)
					where (Object)(object)c != (Object)(object)main && (c.cullingMask & mask) != 0
					orderby (c.cullingMask != mask) ? 1 : 0
					select c).FirstOrDefault();
				if (!((Object)(object)_camera == (Object)null))
				{
					_baseSize = _camera.orthographicSize;
					_baseFov = _camera.fieldOfView;
					Hunted.Logger.LogDebug((object)$"Map camera: {((Object)_camera).name}, orthographic={_camera.orthographic}, size={_baseSize}, fov={_baseFov}");
				}
			}
		}

		private static void ApplyZoom(float zoomOut)
		{
			if (!((Object)(object)_camera == (Object)null))
			{
				zoomOut = Mathf.Max(0.1f, zoomOut);
				if (_camera.orthographic)
				{
					_camera.orthographicSize = _baseSize * zoomOut;
				}
				else
				{
					_camera.fieldOfView = Mathf.Min(170f, Mathf.Atan(Mathf.Tan(_baseFov * 0.5f * (MathF.PI / 180f)) * zoomOut) * 2f * 57.29578f);
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class KillerPatches
	{
		private static float _speedFactor = 1f;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SemiFunc), "InputHold")]
		private static bool InputHold_Prefix(InputKey key, ref bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return AllowInput(key, ref __result);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SemiFunc), "InputDown")]
		private static bool InputDown_Prefix(InputKey key, ref bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return AllowInput(key, ref __result);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SemiFunc), "InputUp")]
		private static bool InputUp_Prefix(InputKey key, ref bool __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return AllowInput(key, ref __result);
		}

		private static bool AllowInput(InputKey key, ref bool result)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if (KillerRole.KillerSteamId == null || !KillerRole.LocalIsKiller)
			{
				return true;
			}
			if ((int)key != 15 && (int)key != 14)
			{
				return true;
			}
			result = false;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
		private static void FixedUpdate_Prefix(PlayerController __instance, out float __state)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			__state = -1f;
			if (KillerRole.LocalIsKiller && !(__instance.playerOriginalMoveSpeed <= 0f))
			{
				__state = __instance.MoveSpeed;
				_speedFactor = HuntedConfig.KillerWalkSpeedMultiplier.Value * (KillerRoom.Contains(((Component)__instance).transform.position) ? Tuning.Killer.KillerRoomEmpowerment : 1f);
				__instance.MoveSpeed = __state * _speedFactor;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerController), "FixedUpdate")]
		private static void FixedUpdate_Postfix(PlayerController __instance, float __state)
		{
			if (!(__state < 0f) && Mathf.Approximately(__instance.MoveSpeed, __state * _speedFactor))
			{
				__instance.MoveSpeed = __state;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerHealth), "Hurt")]
		private static bool Hurt_Prefix(PlayerHealth __instance)
		{
			return !KillerRole.IsKiller(__instance.playerAvatar);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerHealth), "Death")]
		private static bool Death_Prefix(PlayerHealth __instance)
		{
			return !KillerRole.IsKiller(__instance.playerAvatar);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
		private static bool PlayerDeath_Prefix(PlayerAvatar __instance)
		{
			return !KillerRole.IsKiller(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerTumble), "TumbleSet")]
		private static bool TumbleSet_Prefix(PlayerTumble __instance, bool _isTumbling)
		{
			if (_isTumbling)
			{
				return !KillerRole.IsKiller(__instance.playerAvatar);
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysGrabber), "StartGrabbingPhysObject")]
		private static bool StartGrabbing_Prefix(PhysGrabber __instance, PhysGrabObject _physGrabObject)
		{
			if (!Kille