Decompiled source of Lamplighter v0.1.0

Lamplighter.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using ModMenu;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Lamplighter")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+5d5e622c2887424482de7152a26a0b3696813702")]
[assembly: AssemblyProduct("Lamplighter")]
[assembly: AssemblyTitle("Lamplighter")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 Lamplighter
{
	internal static class Assets
	{
		internal static readonly Dictionary<string, List<AudioClip>> Sounds = new Dictionary<string, List<AudioClip>>();

		private static readonly Random Rng = new Random();

		internal static GameObject Model { get; private set; }

		public static void Load()
		{
			try
			{
				using (Stream stream = Res("lamplighter"))
				{
					AssetBundle val = ((stream != null) ? AssetBundle.LoadFromStream(stream) : null);
					if ((Object)(object)val == (Object)null)
					{
						Plugin.Log.LogError((object)"Lamplighter: the embedded bundle is missing.");
						return;
					}
					Model = val.LoadAsset<GameObject>("LamplighterModel");
				}
				string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
				foreach (string text in manifestResourceNames)
				{
					if (!text.EndsWith(".wav"))
					{
						continue;
					}
					string text2 = text.Substring("Lamplighter.".Length, text.Length - "Lamplighter.".Length - 4);
					string key = text2.TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9').TrimEnd('_');
					AudioClip val2 = Wav.Load(Res(text2 + ".wav"), "Lamplighter_" + text2);
					if (!((Object)(object)val2 == (Object)null))
					{
						if (!Sounds.TryGetValue(key, out var value))
						{
							value = (Sounds[key] = new List<AudioClip>());
						}
						value.Add(val2);
					}
				}
				Plugin.Log.LogInfo((object)$"Lamplighter: assets loaded (model {(Object)(object)Model != (Object)null}, {Sounds.Count} sounds).");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Lamplighter: assets failed to load: {arg}");
			}
		}

		internal static AudioClip Sound(string word, Random rnd = null)
		{
			if (!Sounds.TryGetValue(word, out var value) || value.Count == 0)
			{
				return null;
			}
			return value[(rnd ?? Rng).Next(value.Count)];
		}

		private static Stream Res(string name)
		{
			return Assembly.GetExecutingAssembly().GetManifestResourceStream("Lamplighter." + name);
		}
	}
	internal static class Wav
	{
		public static AudioClip Load(Stream s, string name)
		{
			if (s == null)
			{
				Plugin.Log.LogError((object)("Lamplighter: sound " + name + " is missing."));
				return null;
			}
			using (s)
			{
				using BinaryReader binaryReader = new BinaryReader(s);
				binaryReader.ReadBytes(12);
				int num = 1;
				int num2 = 44100;
				int num3 = 16;
				byte[] array = null;
				while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length - 8)
				{
					string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4));
					int num4 = binaryReader.ReadInt32();
					if (text == "fmt ")
					{
						binaryReader.ReadInt16();
						num = binaryReader.ReadInt16();
						num2 = binaryReader.ReadInt32();
						binaryReader.ReadInt32();
						binaryReader.ReadInt16();
						num3 = binaryReader.ReadInt16();
						if (num4 > 16)
						{
							binaryReader.ReadBytes(num4 - 16);
						}
					}
					else
					{
						if (text == "data")
						{
							array = binaryReader.ReadBytes(num4);
							break;
						}
						binaryReader.ReadBytes(num4);
					}
				}
				if (array == null || num3 != 16)
				{
					Plugin.Log.LogError((object)("Lamplighter: sound " + name + " isn't 16-bit PCM."));
					return null;
				}
				int num5 = array.Length / 2;
				float[] array2 = new float[num5];
				for (int i = 0; i < num5; i++)
				{
					array2[i] = (float)BitConverter.ToInt16(array, i * 2) / 32768f;
				}
				AudioClip obj = AudioClip.Create(name, num5 / num, num, num2, false);
				obj.SetData(array2, 0);
				return obj;
			}
		}
	}
	public class LamplighterAI : EnemyAI
	{
		internal static readonly List<LamplighterAI> All = new List<LamplighterAI>();

		internal const int Feeding = 0;

		internal const int Drawn = 1;

		internal const int Hunting = 2;

		internal const int Grab = 3;

		internal const int Lost = 4;

		internal const int Dazzled = 5;

		private static readonly string[] StateNames = new string[6] { "Feeding", "Drawn", "Hunting", "Grab", "Lost", "Dazzled" };

		private const float GrabReach = 1.6f;

		private const float GrabTime = 2.5f;

		private GrabbableObject _target;

		private PlayerControllerB _targetHolder;

		private Vector3 _lastSeen;

		private float _sinceSeen;

		private float _seenFor;

		private float _stateTime;

		private Animator _lamp;

		private float _lampTime;

		private float _drinkTime = -1f;

		private float _nextDrink;

		private readonly HashSet<Animator> _unreachable = new HashSet<Animator>();

		private float _nextLook;

		private float _flinch;

		private float _drainAt = -1f;

		private ulong _drainId;

		private bool _roaming;

		private float _noBumpUntil;

		private Pose _pose;

		private Transform _model;

		private AudioSource _hum;

		private Light _emberLight;

		private HDAdditionalLightData _emberHd;

		private Material _emberMat;

		private Material _bodyMat;

		private Color _emberColor;

		private Color _bodyColor;

		private byte _lookMode;

		private Vector3 _lookTarget;

		private Vector3 _lastPos;

		private Vector3 _reach;

		private Vector3 _vel;

		private float _speed;

		private float _yaw;

		private float _actionTime;

		private float _flare;

		private float _drinkVisual = -1f;

		private float _grabVisual = -1f;

		private float _bumpSent;

		private int _shownState = -1;

		private PlayerControllerB _grabVictim;

		private readonly Random _rng = new Random();

		private float _ceilingCheck;

		private float _ceiling = 10f;

		public override void Start()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			if (base.currentSearch == null)
			{
				base.currentSearch = new AISearchRoutine();
			}
			((EnemyAI)this).Start();
			All.Add(this);
			_model = ((Component)this).transform.Find("Model");
			_pose = new Pose(_model)
			{
				Step = OnStep
			};
			_yaw = ((Component)this).transform.eulerAngles.y;
			_lastPos = ((Component)this).transform.position;
			GameNetworkManager instance = GameNetworkManager.Instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				PlayerControllerB localPlayerController = instance.localPlayerController;
				if (localPlayerController == null)
				{
					obj = null;
				}
				else
				{
					AudioSource movementAudio = localPlayerController.movementAudio;
					obj = ((movementAudio != null) ? movementAudio.outputAudioMixerGroup : null);
				}
			}
			AudioMixerGroup outputAudioMixerGroup = (AudioMixerGroup)obj;
			if ((Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.outputAudioMixerGroup = outputAudioMixerGroup;
			}
			if ((Object)(object)base.creatureSFX != (Object)null)
			{
				base.creatureSFX.outputAudioMixerGroup = outputAudioMixerGroup;
			}
			_hum = ((Component)this).gameObject.AddComponent<AudioSource>();
			_hum.clip = Assets.Sound("hum");
			_hum.loop = true;
			_hum.spatialBlend = 1f;
			_hum.rolloffMode = (AudioRolloffMode)1;
			_hum.minDistance = 1.5f;
			_hum.maxDistance = 20f;
			_hum.dopplerLevel = 0f;
			_hum.volume = 0.8f * Mathf.Clamp01(Plugin.HumVolume.Value);
			_hum.outputAudioMixerGroup = outputAudioMixerGroup;
			if ((Object)(object)_hum.clip != (Object)null)
			{
				_hum.time = (float)_rng.NextDouble() * _hum.clip.length * 0.9f;
				_hum.Play();
			}
			Renderer[] componentsInChildren = ((Component)_model).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (((Object)val).name == "Ember")
				{
					_emberMat = val.material;
					_emberColor = _emberMat.GetColor("_EmissiveColor");
				}
				else if (((Object)val).name == "Body")
				{
					_bodyMat = val.material;
					_bodyColor = _bodyMat.GetColor("_EmissiveColor");
				}
			}
			Transform val2 = (((Object)(object)_pose.Ember != (Object)null) ? _pose.Ember : _model);
			GameObject val3 = new GameObject("EmberLight");
			val3.transform.SetParent(val2, false);
			val3.layer = 0;
			_emberHd = GameObjectExtension.AddHDLight(val3, (HDLightTypeAndShape)0);
			_emberLight = val3.GetComponent<Light>();
			_emberHd.color = new Color(1f, 0.45f, 0.12f);
			_emberHd.range = 6f;
			_emberHd.shadowNearPlane = 0.1f;
			_emberLight.shadows = (LightShadows)0;
			ApplyGlow();
			if (((NetworkBehaviour)this).IsServer)
			{
				Net.UseOwnSettings();
			}
			Plugin.Log.LogInfo((object)string.Format("Lamplighter: spawned ({0}) at {1}, rig {2}.", ((NetworkBehaviour)this).IsServer ? "host" : "client", ((Component)this).transform.position, _pose.Valid));
		}

		public override void OnDestroy()
		{
			All.Remove(this);
			((EnemyAI)this).OnDestroy();
		}

		public override void DoAIInterval()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			((EnemyAI)this).DoAIInterval();
			float aIIntervalTime = base.AIIntervalTime;
			_stateTime += aIIntervalTime;
			if (base.stunNormalizedTimer > 0f)
			{
				if (base.currentBehaviourStateIndex != 5)
				{
					Enter(5);
				}
				base.agent.speed = 0f;
				CancelDrink();
				_target = null;
				SendLook(0, Vector3.zero);
				return;
			}
			if (base.currentBehaviourStateIndex == 5)
			{
				Enter(4);
			}
			if (_flinch > 0f)
			{
				_flinch -= aIIntervalTime;
				base.agent.speed = 0f;
				return;
			}
			if (_drainAt >= 0f && Time.time >= _drainAt)
			{
				_drainAt = -1f;
				Net.Drain(_drainId);
			}
			if (base.currentBehaviourStateIndex != 3)
			{
				Look(aIIntervalTime);
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				if ((Object)(object)_target != (Object)null && _sinceSeen <= 0f)
				{
					CancelDrink();
					Enter(1);
				}
				else
				{
					Feed(aIIntervalTime);
				}
				break;
			case 1:
			case 2:
				Chase(aIIntervalTime);
				break;
			case 3:
				base.agent.speed = 0f;
				if (_stateTime >= 2.5f)
				{
					_target = null;
					Enter(0);
				}
				break;
			case 4:
				if ((Object)(object)_target != (Object)null && _sinceSeen <= 0f)
				{
					Enter(1);
					break;
				}
				base.agent.speed = 1.5f;
				StopRoam();
				((EnemyAI)this).SetDestinationToPosition(_lastSeen, false);
				if ((Vector3.Distance(((Component)this).transform.position, _lastSeen) < 1.6f && _stateTime > 4f) || _stateTime > 9f)
				{
					_target = null;
					Enter(0);
				}
				SendLook(1, _lastSeen + Vector3.up * 1.4f);
				break;
			}
		}

		private void Enter(int state)
		{
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)("Lamplighter: " + StateNames[base.currentBehaviourStateIndex] + " -> " + StateNames[state] + "."));
			}
			_stateTime = 0f;
			_seenFor = 0f;
			((EnemyAI)this).SwitchToBehaviourState(state);
		}

		private void Look(float dt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			float currentScore;
			LightSources.Seen seen = LightSources.Best(base.eye.position, _target, out currentScore);
			if ((Object)(object)seen.Item != (Object)null)
			{
				if ((Object)(object)seen.Item != (Object)(object)_target && Plugin.VerboseLog.Value)
				{
					Plugin.Log.LogInfo((object)string.Format("Lamplighter: sees {0} ({1}), score {2:F2}.", seen.Item.itemProperties?.itemName, ((Object)(object)seen.Holder != (Object)null) ? seen.Holder.playerUsername : "dropped", seen.Score));
				}
				_target = seen.Item;
				_targetHolder = seen.Holder;
				_lastSeen = (((Object)(object)seen.Holder != (Object)null) ? ((Component)seen.Holder).transform.position : ((Component)seen.Item).transform.position);
				_sinceSeen = 0f;
			}
			else if ((Object)(object)_target != (Object)null)
			{
				_sinceSeen += dt;
				if ((Object)(object)_target == (Object)null || _sinceSeen > 30f)
				{
					_target = null;
				}
			}
		}

		private void Feed(float dt)
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			base.agent.speed = 2.5f;
			if (_drinkTime >= 0f)
			{
				base.agent.speed = 0f;
				_drinkTime += dt;
				if ((Object)(object)_lamp != (Object)null)
				{
					SendLook(2, Lamps.Pos(_lamp));
				}
				if ((Object)(object)_lamp == (Object)null || !Lamps.IsLit(_lamp))
				{
					CancelDrink();
				}
				else if (_drinkTime >= 2f)
				{
					Net.Lamp(Lamps.Pos(_lamp), drunk: true);
					if (Plugin.VerboseLog.Value)
					{
						Plugin.Log.LogInfo((object)$"Lamplighter: drank a lamp ({Lamps.DrunkCount} dark, {Lamps.DarkFraction:P0} of the facility).");
					}
					_lamp = null;
					_drinkTime = -1f;
					float num = Mathf.Max(1f, Plugin.DrinkInterval.Value);
					_nextDrink = Time.time + num * Random.Range(0.8f, 1.2f);
				}
				return;
			}
			if (Time.time < _nextDrink || Lamps.DarkFraction >= Plugin.MaxDarkFraction.Value)
			{
				Roam();
				SendLook(0, Vector3.zero);
				return;
			}
			if ((Object)(object)_lamp == (Object)null || !Lamps.IsLit(_lamp))
			{
				_lamp = Lamps.NearestLit(((Component)this).transform.position, 80f, _unreachable);
				_lampTime = 0f;
				if ((Object)(object)_lamp == (Object)null)
				{
					Roam();
					return;
				}
				if (!((EnemyAI)this).SetDestinationToPosition(Under(Lamps.Pos(_lamp)), true))
				{
					_unreachable.Add(_lamp);
					_lamp = null;
					Roam();
					return;
				}
				StopRoam();
			}
			_lampTime += dt;
			Vector3 val = Lamps.Pos(_lamp);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(val.x - ((Component)this).transform.position.x, val.z - ((Component)this).transform.position.z);
			if (((Vector2)(ref val2)).magnitude < 1.4f && val.y - ((Component)this).transform.position.y < 5f)
			{
				_drinkTime = 0f;
				base.agent.speed = 0f;
				Net.Lamp(val, drunk: false);
				SendLook(2, val);
			}
			else if (_lampTime > 25f)
			{
				_unreachable.Add(_lamp);
				_lamp = null;
			}
			else
			{
				((EnemyAI)this).SetDestinationToPosition(Under(val), false);
			}
		}

		private static Vector3 Under(Vector3 lamp)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = lamp - Vector3.up * 3f;
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(lamp - Vector3.up * 0.3f, Vector3.down, ref val2, 12f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				val = ((RaycastHit)(ref val2)).point;
			}
			return RoundManager.Instance.GetNavMeshPosition(val, RoundManager.Instance.navHit, 2.5f, -1);
		}

		private void CancelDrink()
		{
			_drinkTime = -1f;
			_lamp = null;
		}

		private void Roam()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!_roaming || base.currentSearch == null || !base.currentSearch.inProgress)
			{
				_roaming = true;
				((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
			}
		}

		private void StopRoam()
		{
			if (_roaming)
			{
				_roaming = false;
				if (base.currentSearch != null && base.currentSearch.inProgress)
				{
					((EnemyAI)this).StopSearch(base.currentSearch, true);
				}
			}
		}

		private void Chase(float dt)
		{
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			StopRoam();
			bool flag = base.currentBehaviourStateIndex == 2;
			base.agent.speed = (flag ? 6.5f : 3.5f);
			bool flag2 = (Object)(object)_target != (Object)null && _sinceSeen <= 0f;
			if ((Object)(object)_target == (Object)null || ((Object)(object)_targetHolder != (Object)null && _targetHolder.isPlayerDead))
			{
				Enter(4);
				return;
			}
			if (!flag2)
			{
				if (_sinceSeen >= Plugin.LostAfter.Value)
				{
					Enter(4);
					return;
				}
				((EnemyAI)this).SetDestinationToPosition(_lastSeen, false);
				SendLook(1, _lastSeen + Vector3.up * 1.4f);
				return;
			}
			Vector3 val = (((Object)(object)_targetHolder != (Object)null) ? ((Component)_targetHolder).transform.position : ((Component)_target).transform.position);
			((EnemyAI)this).SetDestinationToPosition(val, false);
			SendLook(1, LightSources.PosOf(_target, _targetHolder));
			float num = Vector3.Distance(((Component)this).transform.position, val);
			if (num <= 1.6f)
			{
				if ((Object)(object)_targetHolder != (Object)null)
				{
					GrabPlayer(_targetHolder);
				}
				else
				{
					GrabItem(_target);
				}
			}
			else if (!flag)
			{
				if (num <= Plugin.HuntRange.Value)
				{
					_seenFor += dt;
				}
				else
				{
					_seenFor = 0f;
				}
				if (_seenFor >= 1.5f)
				{
					Enter(2);
				}
			}
		}

		private void GrabPlayer(PlayerControllerB p)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)("Lamplighter: grabs " + p.playerUsername + "."));
			}
			GrabbableObject target = _target;
			_noBumpUntil = Time.time + 2.5f + 3f;
			Enter(3);
			base.agent.speed = 0f;
			((EnemyAI)this).SetDestinationToPosition(((Component)this).transform.position, false);
			Net.Grab(((NetworkBehaviour)this).NetworkObjectId, (int)p.playerClientId);
			if ((Object)(object)target != (Object)null && (Object)(object)((NetworkBehaviour)target).NetworkObject != (Object)null)
			{
				_drainId = ((NetworkBehaviour)target).NetworkObjectId;
				_drainAt = Time.time + 1.2f;
			}
			_target = null;
			_targetHolder = null;
		}

		private void GrabItem(GrabbableObject item)
		{
			//IL_0055: 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)
			if (Plugin.VerboseLog.Value)
			{
				Plugin.Log.LogInfo((object)("Lamplighter: drinks the dropped " + item.itemProperties?.itemName + "."));
			}
			Enter(3);
			base.agent.speed = 0f;
			((EnemyAI)this).SetDestinationToPosition(((Component)this).transform.position, false);
			Net.Grab(((NetworkBehaviour)this).NetworkObjectId, -1);
			SendLook(3, ((Component)item).transform.position, force: true);
			if ((Object)(object)((NetworkBehaviour)item).NetworkObject != (Object)null)
			{
				_drainId = ((NetworkBehaviour)item).NetworkObjectId;
				_drainAt = Time.time + 1.2f;
			}
			_target = null;
			_targetHolder = null;
		}

		internal void HostBumped(ulong clientId)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (!base.isEnemyDead && !(base.stunNormalizedTimer > 0f) && base.currentBehaviourStateIndex != 3 && base.ventAnimationFinished && !(Time.time < _noBumpUntil))
			{
				PlayerControllerB val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB x) => (Object)(object)x != (Object)null && x.isPlayerControlled && x.actualClientId == clientId));
				if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && !(Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > 2.6f))
				{
					GrabPlayer(val);
				}
			}
		}

		private void SendLook(byte mode, Vector3 target, bool force = false)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (!force && Time.time < _nextLook && mode == _lookMode)
			{
				SetLook(mode, target);
				return;
			}
			_nextLook = Time.time + 0.2f;
			Net.Look(((NetworkBehaviour)this).NetworkObjectId, mode, target);
			SetLook(mode, target);
		}

		internal void SetLook(byte mode, Vector3 target)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			_lookMode = mode;
			_lookTarget = target;
		}

		internal void OnLampEvent(Vector3 pos, bool drunk)
		{
			//IL_0000: 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_0028: 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)
			if (!(Vector3.Distance(pos, ((Component)this).transform.position) > 7f))
			{
				if (!drunk)
				{
					_drinkVisual = 0f;
					_reach = pos;
					Play(base.creatureVoice, "drink", 1f);
				}
				else
				{
					_drinkVisual = -1f;
					_flare = 1f;
				}
			}
		}

		internal void OnGrab(int playerIndex)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			_grabVisual = 0f;
			_grabVictim = ((playerIndex >= 0 && playerIndex < StartOfRound.Instance.allPlayerScripts.Length) ? StartOfRound.Instance.allPlayerScripts[playerIndex] : null);
			_reach = (((Object)(object)_grabVictim != (Object)null) ? (((Component)_grabVictim).transform.position + Vector3.up * 1.3f) : (((Component)this).transform.position + _model.forward * 1.2f));
			((MonoBehaviour)this).StartCoroutine(GrabSounds());
			PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
			if ((Object)(object)_grabVictim != (Object)null && (Object)(object)_grabVictim == (Object)(object)val && !val.isPlayerDead)
			{
				((MonoBehaviour)this).StartCoroutine(GrabLocal(val));
			}
		}

		private IEnumerator GrabSounds()
		{
			yield return (object)new WaitForSeconds(0.85f);
			if (!base.isEnemyDead)
			{
				Play(base.creatureVoice, "kill", 1f);
				_flare = 1.6f;
				if ((Object)(object)_hum != (Object)null)
				{
					_hum.volume = 0f;
				}
				yield return (object)new WaitForSeconds(1.1f);
				if ((Object)(object)_hum != (Object)null && !base.isEnemyDead)
				{
					_hum.volume = 0.8f * Mathf.Clamp01(Plugin.HumVolume.Value);
				}
			}
		}

		private IEnumerator GrabLocal(PlayerControllerB me)
		{
			me.JumpToFearLevel(1f, true);
			float t = 0f;
			_ = ((Component)me).transform.position;
			while (t < 0.9f)
			{
				if (me.isPlayerDead || base.isEnemyDead || base.stunNormalizedTimer > 0f)
				{
					yield break;
				}
				t += Time.deltaTime;
				yield return null;
			}
			if (Net.GrabKills)
			{
				me.KillPlayer(Vector3.up * 3f + _model.forward * 2f, true, (CauseOfDeath)4, 0, default(Vector3), false);
			}
			else
			{
				me.DamagePlayer(60, true, true, (CauseOfDeath)4, 0, false, default(Vector3));
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (!base.isEnemyDead && !(base.stunNormalizedTimer > 0f) && base.currentBehaviourStateIndex != 3 && !(Time.time - _bumpSent < 1f) && !((Object)(object)((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false) == (Object)null))
			{
				_bumpSent = Time.time;
				Net.Bump(((NetworkBehaviour)this).NetworkObjectId);
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
			if (base.isEnemyDead)
			{
				return;
			}
			Play(base.creatureVoice, "hit", 1f);
			if (!base.enemyType.canDie)
			{
				return;
			}
			base.enemyHP -= force;
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			if (base.enemyHP <= 0)
			{
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
				return;
			}
			_flinch = 0.6f;
			CancelDrink();
			if ((Object)(object)playerWhoHit != (Object)null && base.currentBehaviourStateIndex != 3 && base.currentBehaviourStateIndex != 5)
			{
				_lastSeen = ((Component)playerWhoHit).transform.position;
				_target = null;
				Enter(4);
			}
		}

		public override void SetEnemyStunned(bool setToStunned, float setToStunTime = 1f, PlayerControllerB setStunnedByPlayer = null)
		{
			((EnemyAI)this).SetEnemyStunned(setToStunned, setToStunTime, setStunnedByPlayer);
			if (setToStunned && FlashPatch.InFlash && base.stunNormalizedTimer > 0f)
			{
				base.stunNormalizedTimer = Mathf.Max(base.stunNormalizedTimer, Plugin.DazzleSeconds.Value / Mathf.Max(0.01f, base.enemyType.stunTimeMultiplier));
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			((EnemyAI)this).KillEnemy(destroy);
			if ((Object)(object)_hum != (Object)null)
			{
				_hum.Stop();
			}
			if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && ((NetworkBehaviour)this).IsOwner)
			{
				base.agent.speed = 0f;
			}
			Plugin.Log.LogInfo((object)"Lamplighter: killed.");
		}

		public override void Update()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (_pose == null)
			{
				return;
			}
			float deltaTime = Time.deltaTime;
			Vector3 position = ((Component)this).transform.position;
			Vector3 val = (position - _lastPos) / Mathf.Max(deltaTime, 0.0001f);
			val.y = 0f;
			_lastPos = position;
			_vel = Vector3.Lerp(_vel, val, 1f - Mathf.Exp(-8f * deltaTime));
			_speed = Mathf.Lerp(_speed, Mathf.Min(((Vector3)(ref val)).magnitude, 9f), 1f - Mathf.Exp(-8f * deltaTime));
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if (currentBehaviourStateIndex != _shownState)
			{
				OnStateShown(_shownState, currentBehaviourStateIndex);
			}
			if (_drinkVisual >= 0f)
			{
				_drinkVisual += deltaTime;
				if (_drinkVisual > 2.4f)
				{
					_drinkVisual = -1f;
				}
			}
			if (_grabVisual >= 0f)
			{
				_grabVisual += deltaTime;
				if ((Object)(object)_grabVictim != (Object)null && !_grabVictim.isPlayerDead)
				{
					_reach = ((Component)_grabVictim).transform.position + Vector3.up * 1.3f;
				}
				if (_grabVisual > 2.5f)
				{
					_grabVisual = -1f;
				}
			}
			_flare = Mathf.MoveTowards(_flare, 0f, deltaTime * 0.8f);
			ApplyGlow();
		}

		private void LateUpdate()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00db: 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_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			if (_pose != null && !((Object)(object)_model == (Object)null))
			{
				float deltaTime = Time.deltaTime;
				int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
				Pose.Act act = (base.isEnemyDead ? Pose.Act.Dead : ((!(base.stunNormalizedTimer > 0f) && currentBehaviourStateIndex != 5) ? ((_grabVisual >= 0f || currentBehaviourStateIndex == 3) ? Pose.Act.Grab : ((_drinkVisual >= 0f) ? Pose.Act.Drink : (currentBehaviourStateIndex switch
				{
					2 => Pose.Act.Lunge, 
					1 => Pose.Act.Stalk, 
					4 => Pose.Act.Lost, 
					_ => (_speed > 0.25f) ? Pose.Act.Walk : Pose.Act.Idle, 
				}))) : Pose.Act.Dazzled));
				if (act != _pose.Action)
				{
					_actionTime = 0f;
				}
				_actionTime += deltaTime;
				Vector3 val = Vector3.zero;
				if (act == Pose.Act.Grab || act == Pose.Act.Drink)
				{
					val = _reach - ((Component)this).transform.position;
				}
				else if (_lookMode != 0 && _speed < 1f)
				{
					val = _lookTarget - ((Component)this).transform.position;
				}
				else if (_speed > 0.3f)
				{
					val = _vel;
				}
				val.y = 0f;
				if (!base.isEnemyDead && ((Vector3)(ref val)).sqrMagnitude > 0.01f)
				{
					float yaw = _yaw;
					Quaternion val2 = Quaternion.LookRotation(val);
					_yaw = Mathf.MoveTowardsAngle(yaw, ((Quaternion)(ref val2)).eulerAngles.y, 220f * deltaTime);
				}
				_model.rotation = Quaternion.Euler(0f, _yaw, 0f);
				_pose.Action = act;
				_pose.ActionTime = _actionTime;
				_pose.Speed = _speed;
				_pose.HasLook = _lookMode != 0;
				_pose.Look = _lookTarget;
				_pose.Reach = _reach;
				_pose.Stoop = Mathf.Lerp(_pose.Stoop, StoopFor(), 1f - Mathf.Exp(-3f * deltaTime));
				_pose.Tick(deltaTime);
			}
		}

		private float StoopFor()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time >= _ceilingCheck)
			{
				_ceilingCheck = Time.time + 0.3f;
				Vector3 val = ((Component)this).transform.position + Vector3.up * 1f;
				RaycastHit val2 = default(RaycastHit);
				_ceiling = (Physics.Raycast(val, Vector3.up, ref val2, 4f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) ? (((RaycastHit)(ref val2)).distance + 1f) : 10f);
			}
			return Mathf.Clamp01((3.1f - _ceiling) / 0.7f);
		}

		private void OnStateShown(int from, int to)
		{
			_shownState = to;
			switch (to)
			{
			case 1:
				if (from == 0 || from == 4 || from == -1)
				{
					Play(base.creatureVoice, "notice", 1f);
				}
				break;
			case 2:
				Play(base.creatureVoice, "lunge", 1f);
				break;
			case 4:
				if (from == 1 || from == 2)
				{
					Play(base.creatureVoice, "lost", 0.9f);
				}
				break;
			case 5:
				Play(base.creatureVoice, "dazzled", 1f);
				break;
			}
			if (to != 3)
			{
				_grabVisual = -1f;
			}
		}

		private void OnStep()
		{
			if ((Object)(object)base.creatureSFX == (Object)null)
			{
				return;
			}
			AudioClip val = Assets.Sound("step", _rng);
			if ((Object)(object)val != (Object)null)
			{
				base.creatureSFX.PlayOneShot(val, Random.Range(0.55f, 0.8f));
			}
			if (_rng.NextDouble() < 0.45)
			{
				AudioClip val2 = Assets.Sound("tink", _rng);
				if ((Object)(object)val2 != (Object)null)
				{
					base.creatureSFX.PlayOneShot(val2, Random.Range(0.3f, 0.55f));
				}
			}
		}

		private void Play(AudioSource src, string word, float vol)
		{
			if (!((Object)(object)src == (Object)null))
			{
				AudioClip val = Assets.Sound(word, _rng);
				if (!((Object)(object)val == (Object)null))
				{
					src.PlayOneShot(val, vol);
					WalkieTalkie.TransmitOneShotAudio(src, val, vol);
				}
			}
		}

		private void ApplyGlow()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01((float)Lamps.DrunkCount / 20f);
			float num2 = (base.isEnemyDead ? 0f : ((0.18f + 0.82f * num) * (1f + _flare)));
			if ((Object)(object)_emberMat != (Object)null)
			{
				_emberMat.SetColor("_EmissiveColor", _emberColor * num2);
			}
			if ((Object)(object)_bodyMat != (Object)null)
			{
				_bodyMat.SetColor("_EmissiveColor", _bodyColor * (base.isEnemyDead ? 0f : (0.15f + 0.85f * num + _flare * 0.5f)));
			}
			if ((Object)(object)_emberHd != (Object)null)
			{
				_emberHd.intensity = 60f + 900f * num2;
			}
		}
	}
	[HarmonyPatch(typeof(StunGrenadeItem), "StunExplosion")]
	internal static class FlashPatch
	{
		internal static bool InFlash;

		private static void Prefix()
		{
			InFlash = true;
		}

		private static void Finalizer()
		{
			InFlash = false;
		}
	}
	internal static class Lamps
	{
		private static readonly HashSet<Animator> Drunk = new HashSet<Animator>();

		private static readonly Dictionary<Animator, Vector3> PosCache = new Dictionary<Animator, Vector3>();

		private static float _nextReapply;

		internal static int DrunkCount => Drunk.Count;

		internal static List<Animator> AllLamps
		{
			get
			{
				RoundManager instance = RoundManager.Instance;
				if (!((Object)(object)instance != (Object)null) || instance.allPoweredLightsAnimators == null)
				{
					return new List<Animator>();
				}
				return instance.allPoweredLightsAnimators;
			}
		}

		internal static float DarkFraction
		{
			get
			{
				List<Animator> allLamps = AllLamps;
				if (allLamps.Count == 0)
				{
					return 1f;
				}
				int num = 0;
				foreach (Animator item in allLamps)
				{
					if ((Object)(object)item == (Object)null || !item.GetBool("on") || Drunk.Contains(item))
					{
						num++;
					}
				}
				return (float)num / (float)allLamps.Count;
			}
		}

		internal static Vector3 Pos(Animator a)
		{
			//IL_000f: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if (PosCache.TryGetValue(a, out var value))
			{
				return value;
			}
			Light val = ((IEnumerable<Light>)((Component)a).GetComponentsInChildren<Light>(true)).FirstOrDefault((Func<Light, bool>)((Light l) => !((Component)l).CompareTag("IndirectLightSource"))) ?? ((Component)a).GetComponentInChildren<Light>(true);
			value = (((Object)(object)val != (Object)null) ? ((Component)val).transform.position : ((Component)a).transform.position);
			PosCache[a] = value;
			return value;
		}

		internal static bool IsDrunk(Animator a)
		{
			return Drunk.Contains(a);
		}

		internal static bool IsLit(Animator a)
		{
			if ((Object)(object)a != (Object)null && ((Behaviour)a).isActiveAndEnabled && !Drunk.Contains(a))
			{
				return a.GetBool("on");
			}
			return false;
		}

		internal static Animator NearestLit(Vector3 from, float maxDist, HashSet<Animator> skip)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Animator result = null;
			float num = maxDist * maxDist;
			foreach (Animator allLamp in AllLamps)
			{
				if (IsLit(allLamp) && (skip == null || !skip.Contains(allLamp)))
				{
					Vector3 val = Pos(allLamp) - from;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = allLamp;
					}
				}
			}
			return result;
		}

		internal static bool LitLampNear(Vector3 p, float r)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			float num = r * r;
			foreach (Animator allLamp in AllLamps)
			{
				if (IsLit(allLamp))
				{
					Vector3 val = Pos(allLamp) - p;
					if (((Vector3)(ref val)).sqrMagnitude < num)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static Animator At(Vector3 pos)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Animator result = null;
			float num = 0.5625f;
			foreach (Animator allLamp in AllLamps)
			{
				if (!((Object)(object)allLamp == (Object)null))
				{
					Vector3 val = Pos(allLamp) - pos;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						result = allLamp;
					}
				}
			}
			return result;
		}

		internal static void Drink(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			Animator val = At(pos);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)$"Lamplighter: no lamp at {pos} to put out.");
				return;
			}
			Drunk.Add(val);
			val.SetBool("on", false);
		}

		internal static void Flicker(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			Animator val = At(pos);
			if ((Object)(object)val != (Object)null)
			{
				val.SetTrigger("Flicker");
			}
		}

		internal static List<Vector3> DrunkPositions()
		{
			return Drunk.Where((Animator a) => (Object)(object)a != (Object)null).Select(Pos).ToList();
		}

		internal static void Clear()
		{
			Drunk.Clear();
			PosCache.Clear();
		}

		internal static void Tick()
		{
			if (Drunk.Count == 0 || Time.time < _nextReapply)
			{
				return;
			}
			_nextReapply = Time.time + 0.5f;
			Drunk.RemoveWhere((Animator a) => (Object)(object)a == (Object)null);
			foreach (Animator item in Drunk)
			{
				if (((Behaviour)item).isActiveAndEnabled && item.GetBool("on"))
				{
					item.SetBool("on", false);
				}
			}
		}

		internal static void Relit()
		{
			if (Drunk.Count != 0 && Net.BreakerRelights)
			{
				Plugin.Log.LogInfo((object)$"Lamplighter: the lights came back on; {Drunk.Count} drunk lamps relit.");
				Drunk.Clear();
			}
		}
	}
	[HarmonyPatch]
	internal static class LampPatches
	{
		[HarmonyPatch(typeof(RoundManager), "TurnOnAllLights")]
		[HarmonyPrefix]
		private static void TurnOnAllLights(bool on)
		{
			if (on)
			{
				Lamps.Relit();
			}
		}

		[HarmonyPatch(typeof(RoundManager), "RefreshLightsList")]
		[HarmonyPostfix]
		private static void RefreshLightsList()
		{
			Lamps.Clear();
		}
	}
	internal static class LightSources
	{
		internal struct Seen
		{
			public GrabbableObject Item;

			public PlayerControllerB Holder;

			public Vector3 Pos;

			public float Score;

			public bool Dropped => (Object)(object)Holder == (Object)null;
		}

		internal const float Floor = 0.05f;

		private const float MaxRange = 40f;

		private static readonly List<GrabbableObject> Items = new List<GrabbableObject>();

		private static float _nextRefresh;

		private static Type _headlampType;

		private static FieldInfo _headlampBeam;

		private static bool _lookedForHeadlamp;

		internal static List<GrabbableObject> Current
		{
			get
			{
				if (Time.time >= _nextRefresh)
				{
					_nextRefresh = Time.time + 1.5f;
					Items.Clear();
					Items.AddRange(Object.FindObjectsOfType<GrabbableObject>());
				}
				Items.RemoveAll((GrabbableObject g) => (Object)(object)g == (Object)null);
				return Items;
			}
		}

		internal static Light HeadlampBeam(GrabbableObject g)
		{
			if (!_lookedForHeadlamp)
			{
				_lookedForHeadlamp = true;
				_headlampType = (from a in AppDomain.CurrentDomain.GetAssemblies()
					select a.GetType("Headlamp.HeadlampItem", throwOnError: false)).FirstOrDefault((Type t) => t != null);
				if (_headlampType != null)
				{
					_headlampBeam = _headlampType.GetField("beam", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				Plugin.Log.LogInfo((object)("Lamplighter: Headlamp " + ((_headlampType != null) ? "found" : "not installed") + "."));
			}
			if (_headlampType == null || _headlampBeam == null || !_headlampType.IsInstanceOfType(g))
			{
				return null;
			}
			object? value = _headlampBeam.GetValue(g);
			return (Light)((value is Light) ? value : null);
		}

		private static bool BatteryOk(GrabbableObject g)
		{
			if (g.itemProperties.requiresBattery)
			{
				if (g.insertedBattery != null && !g.insertedBattery.empty)
				{
					return g.insertedBattery.charge > 0f;
				}
				return false;
			}
			return true;
		}

		internal static bool IsOn(GrabbableObject g, out float weight, out Transform beam)
		{
			weight = 0f;
			beam = null;
			if ((Object)(object)g == (Object)null || (Object)(object)g.itemProperties == (Object)null || g.deactivated)
			{
				return false;
			}
			LungProp val = (LungProp)(object)((g is LungProp) ? g : null);
			if (val != null)
			{
				if (!Plugin.TargetApparatus.Value || val.isLungDocked || !g.isHeld || (Object)(object)g.playerHeldBy == (Object)null)
				{
					return false;
				}
				weight = 50f;
				return true;
			}
			FlashlightItem val2 = (FlashlightItem)(object)((g is FlashlightItem) ? g : null);
			if (val2 != null)
			{
				if (!((GrabbableObject)val2).isBeingUsed || !BatteryOk(g))
				{
					return false;
				}
				string text = g.itemProperties.itemName ?? "";
				weight = ((text.IndexOf("laser", StringComparison.OrdinalIgnoreCase) >= 0) ? 0.5f : ((text.IndexOf("pro", StringComparison.OrdinalIgnoreCase) >= 0) ? 1.6f : 1f));
				if (g.isPocketed)
				{
					weight *= 0.5f;
				}
				else if ((Object)(object)val2.flashlightBulb != (Object)null)
				{
					beam = ((Component)val2.flashlightBulb).transform;
				}
				return true;
			}
			Light val3 = HeadlampBeam(g);
			if ((Object)(object)val3 != (Object)null)
			{
				if (!Plugin.TargetHeadlamp.Value || !g.isBeingUsed || !BatteryOk(g))
				{
					return false;
				}
				weight = 1.2f;
				beam = ((Component)val3).transform;
				return true;
			}
			if (!g.isBeingUsed && (g.itemProperties.itemName ?? "").IndexOf("lamp", StringComparison.OrdinalIgnoreCase) < 0 && (g.itemProperties.itemName ?? "").IndexOf("lantern", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return false;
			}
			if (!BatteryOk(g))
			{
				return false;
			}
			Light[] componentsInChildren = ((Component)g).GetComponentsInChildren<Light>();
			foreach (Light val4 in componentsInChildren)
			{
				if (((Behaviour)val4).enabled && val4.intensity > 0f && val4.range > 2f)
				{
					weight = 1f;
					return true;
				}
			}
			return false;
		}

		internal static Vector3 PosOf(GrabbableObject g, PlayerControllerB holder)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)holder != (Object)null && (Object)(object)holder.gameplayCamera != (Object)null)
			{
				return ((Component)holder.gameplayCamera).transform.position - Vector3.up * 0.25f;
			}
			return ((Component)g).transform.position;
		}

		private static bool Inside(GrabbableObject g, PlayerControllerB holder)
		{
			if (!((Object)(object)holder != (Object)null))
			{
				return g.isInFactory;
			}
			return holder.isInsideFactory;
		}

		internal static float Score(GrabbableObject g, Vector3 eye, out PlayerControllerB holder, out Vector3 pos)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			holder = null;
			pos = Vector3.zero;
			if (!IsOn(g, out var weight, out var beam))
			{
				return 0f;
			}
			holder = ((g.isHeld || g.isPocketed) ? g.playerHeldBy : null);
			if ((Object)(object)holder != (Object)null && (holder.isPlayerDead || !holder.isPlayerControlled))
			{
				return 0f;
			}
			if ((Object)(object)holder == (Object)null && (g.isHeld || !Plugin.TargetDroppedLights.Value || g is LungProp))
			{
				return 0f;
			}
			if (!Inside(g, holder))
			{
				return 0f;
			}
			pos = PosOf(g, holder);
			float num = Vector3.Distance(eye, pos);
			if (num > 40f)
			{
				return 0f;
			}
			int collidersAndRoomMaskAndDefault = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			bool flag = false;
			bool flag2 = !Physics.Linecast(eye, pos, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1);
			if ((Object)(object)beam != (Object)null)
			{
				flag = Vector3.Angle(beam.forward, eye - beam.position) < 25f;
				RaycastHit val = default(RaycastHit);
				if (!flag2 && Physics.Raycast(beam.position, beam.forward, ref val, 20f, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
				{
					Vector3 val2 = ((RaycastHit)(ref val)).point - eye;
					flag2 = ((Vector3)(ref val2)).sqrMagnitude < 1600f && !Physics.Linecast(eye, ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.2f, collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1);
				}
			}
			if (!flag2)
			{
				return 0f;
			}
			float num2 = weight * (flag ? 1.5f : 1f) / (1f + num * num / 100f);
			if (weight < 10f && Lamps.LitLampNear(pos, 4f))
			{
				num2 *= 0.5f;
			}
			return num2;
		}

		internal static Seen Best(Vector3 eye, GrabbableObject current, out float currentScore)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			currentScore = 0f;
			Seen result = default(Seen);
			IOrderedEnumerable<GrabbableObject> orderedEnumerable = Current.Where(delegate(GrabbableObject g)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)g != (Object)null)
				{
					Vector3 val = ((Component)g).transform.position - eye;
					return ((Vector3)(ref val)).sqrMagnitude < 1600f;
				}
				return false;
			}).OrderBy(delegate(GrabbableObject g)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = ((Component)g).transform.position - eye;
				return ((Vector3)(ref val)).sqrMagnitude;
			});
			int num = 0;
			Seen result2 = default(Seen);
			foreach (GrabbableObject item in orderedEnumerable)
			{
				if (!IsOn(item, out var _, out var _) || (++num > 8 && (Object)(object)item != (Object)(object)current))
				{
					continue;
				}
				PlayerControllerB holder;
				Vector3 pos;
				float num2 = Score(item, eye, out holder, out pos);
				if (!(num2 <= 0.05f))
				{
					Seen seen = new Seen
					{
						Item = item,
						Holder = holder,
						Pos = pos,
						Score = num2
					};
					if ((Object)(object)item == (Object)(object)current)
					{
						result2 = seen;
						currentScore = num2;
					}
					if (num2 > result.Score)
					{
						result = seen;
					}
				}
			}
			if ((Object)(object)result2.Item != (Object)null && (Object)(object)result.Item != (Object)(object)result2.Item && result.Score < result2.Score * 1.5f)
			{
				return result2;
			}
			return result;
		}

		internal static void Drain(ulong netId)
		{
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.SpawnManager == null || !singleton.SpawnManager.SpawnedObjects.TryGetValue(netId, out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			GrabbableObject component = ((Component)value).GetComponent<GrabbableObject>();
			if ((Object)(object)component == (Object)null || component is LungProp)
			{
				return;
			}
			try
			{
				if (component.insertedBattery != null)
				{
					component.insertedBattery.charge = 0f;
					component.insertedBattery.empty = true;
				}
				if (component.isBeingUsed)
				{
					component.isBeingUsed = false;
					component.UseUpBatteries();
				}
				Plugin.Log.LogInfo((object)("Lamplighter: drank the light of " + component.itemProperties?.itemName + "."));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Lamplighter: draining " + ((Object)component).name + " failed: " + ex.Message));
			}
		}
	}
	[DefaultExecutionOrder(10000)]
	internal sealed class Interference : MonoBehaviour
	{
		private readonly HashSet<FlashlightItem> _touched = new HashSet<FlashlightItem>();

		private readonly Dictionary<Light, float> _helmetBase = new Dictionary<Light, float>();

		private readonly HashSet<Light> _helmetTouched = new HashSet<Light>();

		private static int Level(Vector3 p)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			float num = float.MaxValue;
			foreach (LamplighterAI item in LamplighterAI.All)
			{
				if (!((Object)(object)item == (Object)null) && !((EnemyAI)item).isEnemyDead)
				{
					Vector3 val = ((Component)item).transform.position - p;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
					}
				}
			}
			if (num == float.MaxValue)
			{
				return 0;
			}
			float num2 = Mathf.Sqrt(num);
			if (!(num2 < Net.DeadRadius))
			{
				return (num2 < Net.FlickerRadius) ? 1 : 0;
			}
			return 2;
		}

		private void LateUpdate()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			if (LamplighterAI.All.Count == 0 && _touched.Count == 0 && _helmetTouched.Count == 0)
			{
				return;
			}
			_touched.RemoveWhere((FlashlightItem f) => (Object)(object)f == (Object)null);
			foreach (GrabbableObject item in LightSources.Current)
			{
				FlashlightItem val = (FlashlightItem)(object)((item is FlashlightItem) ? item : null);
				if (val != null)
				{
					int num = ((LamplighterAI.All.Count > 0) ? Level(((Component)val).transform.position) : 0);
					if (num != 0 || _touched.Contains(val))
					{
						if (num > 0 && val.flashlightInterferenceLevel == 0 && ((GrabbableObject)val).isBeingUsed && (Object)(object)val.flashlightAudio != (Object)null && (Object)(object)val.flashlightFlicker != (Object)null)
						{
							val.flashlightAudio.PlayOneShot(val.flashlightFlicker);
						}
						val.flashlightInterferenceLevel = num;
						if (num == 0)
						{
							_touched.Remove(val);
						}
						else
						{
							_touched.Add(val);
						}
					}
				}
				else
				{
					if (LamplighterAI.All.Count <= 0 || !Plugin.TargetHeadlamp.Value)
					{
						continue;
					}
					Light val2 = LightSources.HeadlampBeam(item);
					if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).enabled)
					{
						switch (Level(((Component)val2).transform.position))
						{
						case 1:
							val2.intensity *= Random.Range(0f, 1f);
							break;
						case 2:
							val2.intensity = 0f;
							break;
						}
					}
				}
			}
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null)
			{
				return;
			}
			PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
			foreach (PlayerControllerB val3 in allPlayerScripts)
			{
				Light val4 = (((Object)(object)val3 != (Object)null) ? val3.helmetLight : null);
				if ((Object)(object)val4 == (Object)null)
				{
					continue;
				}
				int num3 = ((((Behaviour)val4).enabled && LamplighterAI.All.Count > 0) ? Level(((Component)val4).transform.position) : 0);
				if (num3 == 0)
				{
					if (_helmetTouched.Remove(val4) && _helmetBase.TryGetValue(val4, out var value))
					{
						val4.intensity = value;
					}
					else
					{
						_helmetBase[val4] = val4.intensity;
					}
					continue;
				}
				if (!_helmetBase.ContainsKey(val4))
				{
					_helmetBase[val4] = val4.intensity;
				}
				_helmetTouched.Add(val4);
				float num4 = _helmetBase[val4];
				val4.intensity = ((num3 == 2) ? 0f : Random.Range(0f, num4));
			}
		}
	}
	internal static class MenuHooks
	{
		internal const string ModMenuGuid = "daniel.lethalcompany.modmenu";

		private const string Tab = "Lamplighter";

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void Register()
		{
			MenuApi.Button("Lamplighter", "Spawn Lamplighter", (Func<string>)(() => (!Runner.Spawn(GameNetworkManager.Instance.localPlayerController, 8f)) ? null : "spawned a Lamplighter"), true, true, (Func<string>)(() => NoPlayer() ?? Runner.SpawnUnavailable()), "8 m ahead");
			MenuApi.Button("Lamplighter", "Stun all", (Func<string>)delegate
			{
				int num = Runner.StunAll();
				return (num <= 0) ? null : string.Format("stunned {0} Lamplighter{1}", num, (num == 1) ? "" : "s");
			}, true, true, (Func<string>)delegate
			{
				object obj = NoPlayer();
				if (obj == null)
				{
					if (!LamplighterAI.All.Exists((LamplighterAI a) => (Object)(object)a != (Object)null && !((EnemyAI)a).isEnemyDead))
					{
						return "none alive";
					}
					obj = null;
				}
				return (string)obj;
			}, (string)null);
			MenuApi.Button("Lamplighter", "Log state", (Func<string>)delegate
			{
				Runner.LogState();
				return "logged Lamplighter state";
			}, true, false, (Func<string>)NoPlayer, "to the BepInEx log");
		}

		private static string NoPlayer()
		{
			if (!((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null))
			{
				return null;
			}
			return "not in a game";
		}
	}
	internal static class Net
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnConfig;

			public static HandleNamedMessageDelegate <1>__OnLamp;

			public static HandleNamedMessageDelegate <2>__OnLook;

			public static HandleNamedMessageDelegate <3>__OnGrab;

			public static HandleNamedMessageDelegate <4>__OnDrain;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HandleNamedMessageDelegate <>9__18_0;

			public static HandleNamedMessageDelegate <>9__18_1;

			public static Func<ulong, bool> <>9__33_0;

			internal void <Register>b__18_0(ulong sender, FastBufferReader r)
			{
				SendConfig(sender);
			}

			internal void <Register>b__18_1(ulong sender, FastBufferReader r)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				ulong netId = default(ulong);
				((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref netId, default(ForPrimitives));
				Find(netId)?.HostBumped(sender);
			}

			internal bool <ToClients>b__33_0(ulong c)
			{
				return c != 0;
			}
		}

		private const string MsgConfigRequest = "DanielLC.Lamplighter.ConfigRequest";

		private const string MsgConfig = "DanielLC.Lamplighter.Config";

		private const string MsgLamp = "DanielLC.Lamplighter.Lamp";

		private const string MsgLook = "DanielLC.Lamplighter.Look";

		private const string MsgGrab = "DanielLC.Lamplighter.Grab";

		private const string MsgDrain = "DanielLC.Lamplighter.Drain";

		private const string MsgBump = "DanielLC.Lamplighter.Bump";

		private static readonly string[] All = new string[7] { "DanielLC.Lamplighter.ConfigRequest", "DanielLC.Lamplighter.Config", "DanielLC.Lamplighter.Lamp", "DanielLC.Lamplighter.Look", "DanielLC.Lamplighter.Grab", "DanielLC.Lamplighter.Drain", "DanielLC.Lamplighter.Bump" };

		private static bool _registered;

		internal static float FlickerRadius = 14f;

		internal static float DeadRadius = 6f;

		internal static bool BreakerRelights = true;

		internal static bool GrabKills = true;

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return false;
			}
		}

		public static bool Online
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton != (Object)null)
				{
					return NetworkManager.Singleton.IsListening;
				}
				return false;
			}
		}

		internal static void UseOwnSettings()
		{
			FlickerRadius = Plugin.FlickerRadius.Value;
			DeadRadius = Plugin.DeadRadius.Value;
			BreakerRelights = Plugin.BreakerRelights.Value;
			GrabKills = Plugin.GrabKills.Value;
		}

		public static void Register()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//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_00db: Expected O, but got Unknown
			//IL_007f: 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_008a: Expected O, but got Unknown
			//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_0101: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if (_registered || (Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null || !singleton.IsListening)
			{
				return;
			}
			CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
			if (singleton.IsServer)
			{
				UseOwnSettings();
				object obj = <>c.<>9__18_0;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = delegate(ulong sender, FastBufferReader r)
					{
						SendConfig(sender);
					};
					<>c.<>9__18_0 = val;
					obj = (object)val;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.ConfigRequest", (HandleNamedMessageDelegate)obj);
				object obj2 = <>c.<>9__18_1;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = delegate(ulong sender, FastBufferReader r)
					{
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						//IL_000c: Unknown result type (might be due to invalid IL or missing references)
						ulong netId = default(ulong);
						((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref netId, default(ForPrimitives));
						Find(netId)?.HostBumped(sender);
					};
					<>c.<>9__18_1 = val2;
					obj2 = (object)val2;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Bump", (HandleNamedMessageDelegate)obj2);
			}
			else
			{
				object obj3 = <>O.<0>__OnConfig;
				if (obj3 == null)
				{
					HandleNamedMessageDelegate val3 = OnConfig;
					<>O.<0>__OnConfig = val3;
					obj3 = (object)val3;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Config", (HandleNamedMessageDelegate)obj3);
				object obj4 = <>O.<1>__OnLamp;
				if (obj4 == null)
				{
					HandleNamedMessageDelegate val4 = OnLamp;
					<>O.<1>__OnLamp = val4;
					obj4 = (object)val4;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Lamp", (HandleNamedMessageDelegate)obj4);
				object obj5 = <>O.<2>__OnLook;
				if (obj5 == null)
				{
					HandleNamedMessageDelegate val5 = OnLook;
					<>O.<2>__OnLook = val5;
					obj5 = (object)val5;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Look", (HandleNamedMessageDelegate)obj5);
				object obj6 = <>O.<3>__OnGrab;
				if (obj6 == null)
				{
					HandleNamedMessageDelegate val6 = OnGrab;
					<>O.<3>__OnGrab = val6;
					obj6 = (object)val6;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Grab", (HandleNamedMessageDelegate)obj6);
				object obj7 = <>O.<4>__OnDrain;
				if (obj7 == null)
				{
					HandleNamedMessageDelegate val7 = OnDrain;
					<>O.<4>__OnDrain = val7;
					obj7 = (object)val7;
				}
				customMessagingManager.RegisterNamedMessageHandler("DanielLC.Lamplighter.Drain", (HandleNamedMessageDelegate)obj7);
				Send("DanielLC.Lamplighter.ConfigRequest", 0uL, null, 16);
			}
			_registered = true;
		}

		public static void Unregister()
		{
			CustomMessagingManager val = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.CustomMessagingManager : null);
			if (val != null)
			{
				string[] all = All;
				foreach (string text in all)
				{
					try
					{
						val.UnregisterNamedMessageHandler(text);
					}
					catch (Exception)
					{
					}
				}
			}
			_registered = false;
		}

		internal static LamplighterAI Find(ulong netId)
		{
			return LamplighterAI.All.FirstOrDefault((LamplighterAI a) => (Object)(object)a != (Object)null && ((NetworkBehaviour)a).NetworkObjectId == netId);
		}

		private static void SendConfig(ulong to)
		{
			List<Vector3> lamps = Lamps.DrunkPositions();
			Send("DanielLC.Lamplighter.Config", to, delegate(FastBufferWriter w)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				float value = Plugin.FlickerRadius.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref value, default(ForPrimitives));
				value = Plugin.DeadRadius.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref value, default(ForPrimitives));
				bool value2 = Plugin.BreakerRelights.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref value2, default(ForPrimitives));
				value2 = Plugin.GrabKills.Value;
				((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref value2, default(ForPrimitives));
				int count = lamps.Count;
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref count, default(ForPrimitives));
				foreach (Vector3 item in lamps)
				{
					Vector3 current = item;
					((FastBufferWriter)(ref w)).WriteValueSafe(ref current);
				}
			}, 64 + lamps.Count * 12);
		}

		private static void OnConfig(ulong sender, FastBufferReader r)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref FlickerRadius, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<float>(ref DeadRadius, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref BreakerRelights, default(ForPrimitives));
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref GrabKills, default(ForPrimitives));
			int num = default(int);
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			Vector3 pos = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				((FastBufferReader)(ref r)).ReadValueSafe(ref pos);
				Lamps.Drink(pos);
			}
			Plugin.Log.LogInfo((object)$"Lamplighter: host settings (flicker {FlickerRadius} m, dead {DeadRadius} m, breaker relights {BreakerRelights}, grab kills {GrabKills}, {num} lamps already dark).");
		}

		internal static void Lamp(Vector3 pos, bool drunk)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			ToClients("DanielLC.Lamplighter.Lamp", delegate(FastBufferWriter w)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				((FastBufferWriter)(ref w)).WriteValueSafe<bool>(ref drunk, default(ForPrimitives));
				((FastBufferWriter)(ref w)).WriteValueSafe(ref pos);
			}, 32, (NetworkDelivery)3);
			ApplyLamp(pos, drunk);
		}

		private static void OnLamp(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			bool drunk = default(bool);
			((FastBufferReader)(ref r)).ReadValueSafe<bool>(ref drunk, default(ForPrimitives));
			Vector3 pos = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref pos);
			ApplyLamp(pos, drunk);
		}

		private static void ApplyLamp(Vector3 pos, bool drunk)
		{
			//IL_000b: 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)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (drunk)
			{
				Lamps.Drink(pos);
			}
			else
			{
				Lamps.Flicker(pos);
			}
			foreach (LamplighterAI item in LamplighterAI.All)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.OnLampEvent(pos, drunk);
				}
			}
		}

		internal static void Look(ulong enemy, byte mode, Vector3 target)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			ToClients("DanielLC.Lamplighter.Look", delegate(FastBufferWriter w)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: 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)
				((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref enemy, default(ForPrimitives));
				((FastBufferWriter)(ref w)).WriteValueSafe<byte>(ref mode, default(ForPrimitives));
				((FastBufferWriter)(ref w)).WriteValueSafe(ref target);
			}, 32, (NetworkDelivery)1);
		}

		private static void OnLook(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			ulong netId = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref netId, default(ForPrimitives));
			byte mode = default(byte);
			((FastBufferReader)(ref r)).ReadValueSafe<byte>(ref mode, default(ForPrimitives));
			Vector3 target = default(Vector3);
			((FastBufferReader)(ref r)).ReadValueSafe(ref target);
			Find(netId)?.SetLook(mode, target);
		}

		internal static void Grab(ulong enemy, int playerIndex)
		{
			ToClients("DanielLC.Lamplighter.Grab", delegate(FastBufferWriter w)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: 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)
				((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref enemy, default(ForPrimitives));
				((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref playerIndex, default(ForPrimitives));
			}, 32, (NetworkDelivery)3);
			Find(enemy)?.OnGrab(playerIndex);
		}

		private static void OnGrab(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			ulong netId = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref netId, default(ForPrimitives));
			int playerIndex = default(int);
			((FastBufferReader)(ref r)).ReadValueSafe<int>(ref playerIndex, default(ForPrimitives));
			Find(netId)?.OnGrab(playerIndex);
		}

		internal static void Bump(ulong enemy)
		{
			if (IsHost)
			{
				Find(enemy)?.HostBumped(0uL);
				return;
			}
			Send("DanielLC.Lamplighter.Bump", 0uL, delegate(FastBufferWriter w)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref enemy, default(ForPrimitives));
			}, 16);
		}

		internal static void Drain(ulong itemNetId)
		{
			ToClients("DanielLC.Lamplighter.Drain", delegate(FastBufferWriter w)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref itemNetId, default(ForPrimitives));
			}, 16, (NetworkDelivery)3);
			LightSources.Drain(itemNetId);
		}

		private static void OnDrain(ulong sender, FastBufferReader r)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ulong netId = default(ulong);
			((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref netId, default(ForPrimitives));
			LightSources.Drain(netId);
		}

		private static void ToClients(string name, Action<FastBufferWriter> write, int size, NetworkDelivery delivery)
		{
			//IL_0068: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || !singleton.IsServer || singleton.CustomMessagingManager == null)
			{
				return;
			}
			List<ulong> list = singleton.ConnectedClientsIds.Where((ulong c) => c != 0).ToList();
			if (list.Count == 0)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(size, (Allocator)2, 65536);
			try
			{
				write(val);
				singleton.CustomMessagingManager.SendNamedMessage(name, (IReadOnlyList<ulong>)list, val, delivery);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}

		private static void Send(string name, ulong to, Action<FastBufferWriter> write, int size)
		{
			//IL_0038: 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)
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(size, (Allocator)2, 65536);
			try
			{
				write?.Invoke(val);
				singleton.CustomMessagingManager.SendNamedMessage(name, to, val, (NetworkDelivery)3);
			}
			finally
			{
				((FastBufferWriter)(ref val)).Dispose();
			}
		}
	}
	[HarmonyPatch]
	internal static class NetPatches
	{
		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void StartOfRoundStart()
		{
			Net.Register();
		}

		[HarmonyPatch(typeof(StartOfRound), "OnDestroy")]
		[HarmonyPrefix]
		private static void StartOfRoundDestroy()
		{
			Net.Unregister();
			Lamps.Clear();
		}
	}
	public static class PluginInfo
	{
		public const string Guid = "daniel.lethalcompany.lamplighter";

		public const string Name = "Lamplighter";

		public const string Version = "0.1.0";
	}
	[BepInPlugin("daniel.lethalcompany.lamplighter", "Lamplighter", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static ConfigEntry<string> SpawnRarity;

		internal static ConfigEntry<int> MaxCount;

		internal static ConfigEntry<float> PowerLevel;

		internal static ConfigEntry<float> EarliestHour;

		internal static ConfigEntry<float> DrinkInterval;

		internal static ConfigEntry<float> MaxDarkFraction;

		internal static ConfigEntry<bool> BreakerRelights;

		internal static ConfigEntry<float> FlickerRadius;

		internal static ConfigEntry<float> DeadRadius;

		internal static ConfigEntry<float> HuntRange;

		internal static ConfigEntry<float> LostAfter;

		internal static ConfigEntry<bool> GrabKills;

		internal static ConfigEntry<bool> Killable;

		internal static ConfigEntry<int> HP;

		internal static ConfigEntry<float> DazzleSeconds;

		internal static ConfigEntry<bool> TargetApparatus;

		internal static ConfigEntry<bool> TargetHeadlamp;

		internal static ConfigEntry<bool> TargetDroppedLights;

		internal static ConfigEntry<float> HumVolume;

		internal static ConfigEntry<bool> VerboseLog;

		private readonly Harmony _harmony = new Harmony("daniel.lethalcompany.lamplighter");

		private void Awake()
		{
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Expected O, but got Unknown
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			SpawnRarity = ((BaseUnityPlugin)this).Config.Bind<string>("Spawning (host)", "Spawn rarity", "Experimentation:10,Assurance:20,Vow:20,Offense:30,March:30,Adamance:30,Rend:45,Dine:45,Titan:45,Artifice:45,Embrion:20,Modded:25", "Moon:rarity pairs. Vanilla moon names, \"Modded\" for every modded moon, or a modded moon's own name.");
			MaxCount = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning (host)", "Max count", 1, "At most this many Lamplighters on a moon at once.");
			PowerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning (host)", "Power level", 2f, "How much of the moon's indoor power budget it uses.");
			EarliestHour = ((BaseUnityPlugin)this).Config.Bind<float>("Spawning (host)", "Earliest hour", 10f, "It doesn't spawn before this hour (24 h clock); more likely later in the day.");
			DrinkInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Drink interval", 10f, "Seconds it waits after drinking a lamp before the next one.");
			MaxDarkFraction = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Max dark fraction", 0.7f, "It stops drinking lamps once this share of the facility's lamps is dark, then only hunts.");
			BreakerRelights = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Breaker relights", true, "Flipping the breaker off and on brings its drunk lamps back.");
			FlickerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Flicker radius", 14f, "Flashlights within this many metres of it flicker.");
			DeadRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Dead radius", 6f, "Flashlights within this many metres of it go dark (they're still on, so it still sees them).");
			HuntRange = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Hunt range", 12f, "Within this range, after 1.5 s in sight, it lunges.");
			LostAfter = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Lost after", 3f, "Seconds without seeing its light before it gives up and searches.");
			GrabKills = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Grab kills", true, "Its grab kills. Off: 60 damage and it drinks your light.");
			Killable = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Killable", true, "It can be killed.");
			HP = ((BaseUnityPlugin)this).Config.Bind<int>("Behaviour (host)", "HP", 6, "Hit points if killable (a shovel hit is 1).");
			DazzleSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Behaviour (host)", "Dazzle seconds", 6f, "How long a stun grenade dazzles it (other stuns are normal length).");
			TargetApparatus = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Hunt the apparatus", true, "Once pulled, the apparatus is the brightest light in the building.");
			TargetHeadlamp = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Hunt the Headlamp", true, "Our Headlamp counts as a light and flickers like a flashlight.");
			TargetDroppedLights = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour (host)", "Drink dropped lights", true, "A lit light on the floor pulls it as a decoy, and it drinks it (battery to 0).");
			HumVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Sound (this player)", "Hum volume", 1f, "Volume of its presence hum (0 to 1).");
			VerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "Verbose log", false, "Log its state changes, targets, drinks and grabs. Spawning, stunning and a state dump are in the F6 Mod Menu.");
			GameObject val = new GameObject("Lamplighter.Runner");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<Runner>();
			Assets.Load();
			Prefab.BuildAndRegister();
			_harmony.PatchAll(typeof(Plugin).Assembly);
			if (Chainloader.PluginInfos.ContainsKey("daniel.lethalcompany.modmenu"))
			{
				MenuHooks.Register();
			}
			Log.LogInfo((object)"Lamplighter 0.1.0 loaded.");
		}
	}
	internal sealed class Pose
	{
		internal enum Act
		{
			Idle,
			Walk,
			Stalk,
			Lunge,
			Drink,
			Lost,
			Dazzled,
			Grab,
			Dead
		}

		internal Act Action;

		internal float Speed;

		internal bool HasLook;

		internal Vector3 Look;

		internal Vector3 Reach;

		internal float Stoop;

		internal float ActionTime;

		internal Action Step;

		private readonly Transform _root;

		private readonly Transform _hips;

		private readonly Transform _spine1;

		private readonly Transform _spine2;

		private readonly Transform _chest;

		private readonly Transform _neck1;

		private readonly Transform _neck2;

		private readonly Transform _head;

		private readonly Transform _ember;

		private readonly Transform _upL;

		private readonly Transform _upR;

		private readonly Transform _foreL;

		private readonly Transform _foreR;

		private readonly Transform _handL;

		private readonly Transform _handR;

		private readonly Transform _thighL;

		private readonly Transform _thighR;

		private readonly Transform _shinL;

		private readonly Transform _shinR;

		private readonly Transform _footL;

		private readonly Transform _footR;

		private readonly List<(Transform t, Quaternion rot)> _rest = new List<(Transform, Quaternion)>();

		private readonly Vector3 _hipsRest;

		private readonly float _legLen;

		private float _phase;

		private float _lastSin;

		private float _weightLunge;

		private float _weightDrink;

		private float _weightDazzle;

		private float _weightGrab;

		private float _weightLook;

		private float _lean;

		private float _dead;

		private Vector3 _lookSmooth;

		internal bool Valid { get; }

		internal Vector3 EmberPos
		{
			get
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_ember != (Object)null))
				{
					return _root.position + Vector3.up * 2.8f;
				}
				return _ember.position;
			}
		}

		internal Transform Ember => _ember;

		internal Pose(Transform root)
		{
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			Transform root2 = root;
			base..ctor();
			_root = root2;
			_hips = F("Hips");
			_spine1 = F("Spine1");
			_spine2 = F("Spine2");
			_chest = F("Chest");
			_neck1 = F("Neck1");
			_neck2 = F("Neck2");
			_head = F("Head");
			_ember = F("Ember");
			_upL = F("UpperArm.L");
			_upR = F("UpperArm.R");
			_foreL = F("Forearm.L");
			_foreR = F("Forearm.R");
			_handL = F("Hand.L");
			_handR = F("Hand.R");
			_thighL = F("Thigh.L");
			_thighR = F("Thigh.R");
			_shinL = F("Shin.L");
			_shinR = F("Shin.R");
			_footL = F("Foot.L");
			_footR = F("Foot.R");
			Transform[] array = (Transform[])(object)new Transform[19]
			{
				_hips, _spine1, _spine2, _chest, _neck1, _neck2, _head, _upL, _upR, _foreL,
				_foreR, _handL, _handR, _thighL, _thighR, _shinL, _shinR, _footL, _footR
			};
			Valid = Array.TrueForAll(array, (Transform t) => (Object)(object)t != (Object)null) && (Object)(object)_ember != (Object)null;
			if (!Valid)
			{
				Plugin.Log.LogError((object)"Lamplighter: the model's rig is incomplete; it won't move its limbs.");
				return;
			}
			Transform[] componentsInChildren = ((Component)root2).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				_rest.Add((val, val.localRotation));
			}
			_hipsRest = _hips.localPosition;
			_legLen = Vector3.Distance(_thighL.position, _footL.position);
			_lookSmooth = _ember.position + root2.forward * 3f;
			Transform F(string n)
			{
				return Prefab.FindDeep(root2, n);
			}
		}

		internal void Tick(float dt)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)